Commit ce95a3b153

Felix (xq) Queißner <git@random-projects.net>
2023-07-19 10:49:34
Build.zig rename orgy (aka: #16353). Renames FileSource to LazyPath and removes functions that take literal paths instead of LazyPath.
1 parent 235e6ac
Changed files (55)
lib
test
link
interdependent_static_c_libs
macho
bugs
13056
dead_strip
dead_strip_dylibs
dylib
empty
entry
entry_in_archive
entry_in_dylib
headerpad
needed_framework
needed_library
objc
objcpp
pagezero
search_strategy
stack_size
tls
unwind_info
weak_framework
weak_library
static_libs_from_object_files
wasm
extern
infer-features
src
standalone
c_compiler
embed_generated_file
issue_794
issue_8550
main_pkg_path
mix_c_files
mix_o_files
shared_library
stack_iterator
static_c_lib
use_alias
lib/std/Build/Step/CheckFile.zig
@@ -11,7 +11,7 @@ const mem = std.mem;
 step: Step,
 expected_matches: []const []const u8,
 expected_exact: ?[]const u8,
-source: std.Build.FileSource,
+source: std.Build.LazyPath,
 max_bytes: usize = 20 * 1024 * 1024,
 
 pub const base_id = .check_file;
@@ -23,7 +23,7 @@ pub const Options = struct {
 
 pub fn create(
     owner: *std.Build,
-    source: std.Build.FileSource,
+    source: std.Build.LazyPath,
     options: Options,
 ) *CheckFile {
     const self = owner.allocator.create(CheckFile) catch @panic("OOM");
lib/std/Build/Step/CheckObject.zig
@@ -15,14 +15,14 @@ const Step = std.Build.Step;
 pub const base_id = .check_object;
 
 step: Step,
-source: std.Build.FileSource,
+source: std.Build.LazyPath,
 max_bytes: usize = 20 * 1024 * 1024,
 checks: std.ArrayList(Check),
 obj_format: std.Target.ObjectFormat,
 
 pub fn create(
     owner: *std.Build,
-    source: std.Build.FileSource,
+    source: std.Build.LazyPath,
     obj_format: std.Target.ObjectFormat,
 ) *CheckObject {
     const gpa = owner.allocator;
@@ -44,7 +44,7 @@ pub fn create(
 
 const SearchPhrase = struct {
     string: []const u8,
-    file_source: ?std.Build.FileSource = null,
+    file_source: ?std.Build.LazyPath = null,
 
     fn resolve(phrase: SearchPhrase, b: *std.Build, step: *Step) []const u8 {
         const file_source = phrase.file_source orelse return phrase.string;
@@ -302,13 +302,13 @@ pub fn checkExact(self: *CheckObject, phrase: []const u8) void {
     self.checkExactInner(phrase, null);
 }
 
-/// Like `checkExact()` but takes an additional argument `FileSource` which will be
+/// Like `checkExact()` but takes an additional argument `LazyPath` which will be
 /// resolved to a full search query in `make()`.
-pub fn checkExactFileSource(self: *CheckObject, phrase: []const u8, file_source: std.Build.FileSource) void {
+pub fn checkExactPath(self: *CheckObject, phrase: []const u8, file_source: std.Build.LazyPath) void {
     self.checkExactInner(phrase, file_source);
 }
 
-fn checkExactInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void {
+fn checkExactInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.LazyPath) void {
     assert(self.checks.items.len > 0);
     const last = &self.checks.items[self.checks.items.len - 1];
     last.exact(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
@@ -321,7 +321,7 @@ pub fn checkContains(self: *CheckObject, phrase: []const u8) void {
 
 /// Like `checkContains()` but takes an additional argument `FileSource` which will be
 /// resolved to a full search query in `make()`.
-pub fn checkContainsFileSource(self: *CheckObject, phrase: []const u8, file_source: std.Build.FileSource) void {
+pub fn checkContainsPath(self: *CheckObject, phrase: []const u8, file_source: std.Build.LazyPath) void {
     self.checkContainsInner(phrase, file_source);
 }
 
lib/std/Build/Step/Compile.zig
@@ -11,7 +11,7 @@ const Allocator = mem.Allocator;
 const Step = std.Build.Step;
 const CrossTarget = std.zig.CrossTarget;
 const NativeTargetInfo = std.zig.system.NativeTargetInfo;
-const FileSource = std.Build.FileSource;
+const LazyPath = std.Build.LazyPath;
 const PkgConfigPkg = std.Build.PkgConfigPkg;
 const PkgConfigError = std.Build.PkgConfigError;
 const ExecError = std.Build.ExecError;
@@ -28,7 +28,7 @@ name: []const u8,
 target: CrossTarget,
 target_info: NativeTargetInfo,
 optimize: std.builtin.Mode,
-linker_script: ?FileSource = null,
+linker_script: ?LazyPath = null,
 version_script: ?[]const u8 = null,
 out_filename: []const u8,
 linkage: ?Linkage = null,
@@ -40,9 +40,9 @@ strip: ?bool,
 unwind_tables: ?bool,
 // keep in sync with src/link.zig:CompressDebugSections
 compress_debug_sections: enum { none, zlib } = .none,
-lib_paths: ArrayList(FileSource),
-rpaths: ArrayList(FileSource),
-framework_dirs: ArrayList(FileSource),
+lib_paths: ArrayList(LazyPath),
+rpaths: ArrayList(LazyPath),
+framework_dirs: ArrayList(LazyPath),
 frameworks: StringHashMap(FrameworkLinkInfo),
 verbose_link: bool,
 verbose_cc: bool,
@@ -74,8 +74,8 @@ max_memory: ?u64 = null,
 shared_memory: bool = false,
 global_base: ?u64 = null,
 c_std: std.Build.CStd,
-zig_lib_dir: ?[]const u8,
-main_pkg_path: ?[]const u8,
+zig_lib_dir: ?LazyPath,
+main_pkg_path: ?LazyPath,
 exec_cmd_args: ?[]const ?[]const u8,
 filter: ?[]const u8,
 test_evented_io: bool = false,
@@ -85,7 +85,7 @@ wasi_exec_model: ?std.builtin.WasiExecModel = null,
 /// Symbols to be exported when compiling to wasm
 export_symbol_names: []const []const u8 = &.{},
 
-root_src: ?FileSource,
+root_src: ?LazyPath,
 out_h_filename: []const u8,
 out_lib_filename: []const u8,
 out_pdb_filename: []const u8,
@@ -106,7 +106,7 @@ installed_path: ?[]const u8,
 /// Base address for an executable image.
 image_base: ?u64 = null,
 
-libc_file: ?FileSource = null,
+libc_file: ?LazyPath = null,
 
 valgrind_support: ?bool = null,
 each_lib_rpath: ?bool = null,
@@ -223,22 +223,22 @@ pub const CSourceFiles = struct {
 };
 
 pub const CSourceFile = struct {
-    source: FileSource,
-    args: []const []const u8,
+    file: LazyPath,
+    flags: []const []const u8,
 
     pub fn dupe(self: CSourceFile, b: *std.Build) CSourceFile {
         return .{
-            .source = self.source.dupe(b),
-            .args = b.dupeStrings(self.args),
+            .file = self.file.dupe(b),
+            .flags = b.dupeStrings(self.flags),
         };
     }
 };
 
 pub const LinkObject = union(enum) {
-    static_path: FileSource,
+    static_path: LazyPath,
     other_step: *Compile,
     system_lib: SystemLib,
-    assembly_file: FileSource,
+    assembly_file: LazyPath,
     c_source_file: *CSourceFile,
     c_source_files: *CSourceFiles,
 };
@@ -265,15 +265,15 @@ const FrameworkLinkInfo = struct {
 };
 
 pub const IncludeDir = union(enum) {
-    raw_path: []const u8,
-    raw_path_system: []const u8,
+    path: LazyPath,
+    path_system: LazyPath,
     other_step: *Compile,
     config_header_step: *Step.ConfigHeader,
 };
 
 pub const Options = struct {
     name: []const u8,
-    root_source_file: ?FileSource = null,
+    root_source_file: ?LazyPath = null,
     target: CrossTarget,
     optimize: std.builtin.Mode,
     kind: Kind,
@@ -391,7 +391,7 @@ pub const EmitOption = union(enum) {
 
 pub fn create(owner: *std.Build, options: Options) *Compile {
     const name = owner.dupe(options.name);
-    const root_src: ?FileSource = if (options.root_source_file) |rsrc| rsrc.dupe(owner) else null;
+    const root_src: ?LazyPath = if (options.root_source_file) |rsrc| rsrc.dupe(owner) else null;
     if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) {
         panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name});
     }
@@ -462,9 +462,9 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
         .include_dirs = ArrayList(IncludeDir).init(owner.allocator),
         .link_objects = ArrayList(LinkObject).init(owner.allocator),
         .c_macros = ArrayList([]const u8).init(owner.allocator),
-        .lib_paths = ArrayList(FileSource).init(owner.allocator),
-        .rpaths = ArrayList(FileSource).init(owner.allocator),
-        .framework_dirs = ArrayList(FileSource).init(owner.allocator),
+        .lib_paths = ArrayList(LazyPath).init(owner.allocator),
+        .rpaths = ArrayList(LazyPath).init(owner.allocator),
+        .framework_dirs = ArrayList(LazyPath).init(owner.allocator),
         .installed_headers = ArrayList(*Step).init(owner.allocator),
         .c_std = std.Build.CStd.C99,
         .zig_lib_dir = null,
@@ -614,7 +614,7 @@ pub fn addObjCopy(cs: *Compile, options: Step.ObjCopy.Options) *Step.ObjCopy {
             copy.basename = cs.name;
         }
     }
-    return b.addObjCopy(cs.getOutputSource(), copy);
+    return b.addObjCopy(cs.getEmittedBin(), copy);
 }
 
 /// This function would run in the context of the package that created the executable,
@@ -626,10 +626,12 @@ pub const run = @compileError("deprecated; use std.Build.addRunArtifact");
 pub const install = @compileError("deprecated; use std.Build.installArtifact");
 
 pub fn checkObject(self: *Compile) *Step.CheckObject {
-    return Step.CheckObject.create(self.step.owner, self.getOutputSource(), self.target_info.target.ofmt);
+    return Step.CheckObject.create(self.step.owner, self.getEmittedBin(), self.target_info.target.ofmt);
 }
 
-pub fn setLinkerScriptPath(self: *Compile, source: FileSource) void {
+pub const setLinkerScriptPath = setLinkerScript; // DEPRECATED, use setLinkerScript
+
+pub fn setLinkerScript(self: *Compile, source: LazyPath) void {
     const b = self.step.owner;
     self.linker_script = source.dupe(b);
     source.addStepDependencies(&self.step);
@@ -935,19 +937,12 @@ pub fn addCSourceFiles(self: *Compile, files: []const []const u8, flags: []const
     self.link_objects.append(.{ .c_source_files = c_source_files }) catch @panic("OOM");
 }
 
-pub fn addCSourceFile(self: *Compile, file: []const u8, flags: []const []const u8) void {
-    self.addCSourceFileSource(.{
-        .args = flags,
-        .source = .{ .path = file },
-    });
-}
-
-pub fn addCSourceFileSource(self: *Compile, source: CSourceFile) void {
+pub fn addCSourceFile(self: *Compile, source: CSourceFile) void {
     const b = self.step.owner;
     const c_source_file = b.allocator.create(CSourceFile) catch @panic("OOM");
     c_source_file.* = source.dupe(b);
     self.link_objects.append(.{ .c_source_file = c_source_file }) catch @panic("OOM");
-    source.source.addStepDependencies(&self.step);
+    source.file.addStepDependencies(&self.step);
 }
 
 pub fn setVerboseLink(self: *Compile, value: bool) void {
@@ -958,53 +953,63 @@ pub fn setVerboseCC(self: *Compile, value: bool) void {
     self.verbose_cc = value;
 }
 
-pub fn overrideZigLibDir(self: *Compile, dir_path: []const u8) void {
-    const b = self.step.owner;
-    self.zig_lib_dir = b.dupePath(dir_path);
+pub fn overrideZigLibDir(self: *Compile, dir_path: LazyPath) void {
+    self.zig_lib_dir = dir_path.dupe(self.step.owner);
+    dir_path.addStepDependencies(&self.step);
 }
 
-pub fn setMainPkgPath(self: *Compile, dir_path: []const u8) void {
-    const b = self.step.owner;
-    self.main_pkg_path = b.dupePath(dir_path);
+pub fn setMainPkgPath(self: *Compile, dir_path: LazyPath) void {
+    self.main_pkg_path = dir_path.dupe(self.step.owner);
+    dir_path.addStepDependencies(&self.step);
 }
 
-pub fn setLibCFile(self: *Compile, libc_file: ?FileSource) void {
+pub fn setLibCFile(self: *Compile, libc_file: ?LazyPath) void {
     const b = self.step.owner;
     self.libc_file = if (libc_file) |f| f.dupe(b) else null;
 }
 
+pub const getOutputSource = getEmittedBin; // DEPRECATED, use getEmittedBin
+
 /// Returns the generated executable, library or object file.
 /// To run an executable built with zig build, use `run`, or create an install step and invoke it.
-pub fn getOutputSource(self: *Compile) FileSource {
+pub fn getEmittedBin(self: *Compile) LazyPath {
     return .{ .generated = &self.output_path_source };
 }
 
-pub fn getOutputDirectorySource(self: *Compile) FileSource {
+pub const getOutputDirectorySource = getEmitDirectory; // DEPRECATED, use getEmitDirectory
+
+pub fn getEmitDirectory(self: *Compile) LazyPath {
     return .{ .generated = &self.output_dirname_source };
 }
 
+pub const getOutputLibSource = getEmittedImplib; // DEPRECATED, use getEmittedImplib
+
 /// Returns the generated import library. This function can only be called for libraries.
-pub fn getOutputLibSource(self: *Compile) FileSource {
+pub fn getEmittedImplib(self: *Compile) LazyPath {
     assert(self.kind == .lib);
     return .{ .generated = &self.output_lib_path_source };
 }
 
+pub const getOutputHSource = getEmittedH; // DEPRECATED, use getEmittedH
+
 /// Returns the generated header file.
 /// This function can only be called for libraries or object files which have `emit_h` set.
-pub fn getOutputHSource(self: *Compile) FileSource {
+pub fn getEmittedH(self: *Compile) LazyPath {
     assert(self.kind != .exe and self.kind != .@"test");
     assert(self.emit_h);
     return .{ .generated = &self.output_h_path_source };
 }
 
+pub const getOutputPdbSource = getEmittedPdb; // DEPRECATED, use getEmittedPdb
+
 /// Returns the generated PDB file. This function can only be called for Windows and UEFI.
-pub fn getOutputPdbSource(self: *Compile) FileSource {
+pub fn getEmittedPdb(self: *Compile) LazyPath {
     // TODO: Is this right? Isn't PDB for *any* PE/COFF file?
     assert(self.target.isWindows() or self.target.isUefi());
     return .{ .generated = &self.output_pdb_path_source };
 }
 
-pub fn getEmittedDocs(self: *Compile) FileSource {
+pub fn getEmittedDocs(self: *Compile) LazyPath {
     if (self.generated_docs) |g| return .{ .generated = g };
     const arena = self.step.owner.allocator;
     const generated_file = arena.create(GeneratedFile) catch @panic("OOM");
@@ -1013,25 +1018,14 @@ pub fn getEmittedDocs(self: *Compile) FileSource {
     return .{ .generated = generated_file };
 }
 
-pub fn addAssemblyFile(self: *Compile, path: []const u8) void {
-    const b = self.step.owner;
-    self.link_objects.append(.{
-        .assembly_file = .{ .path = b.dupe(path) },
-    }) catch @panic("OOM");
-}
-
-pub fn addAssemblyFileSource(self: *Compile, source: FileSource) void {
+pub fn addAssemblyFile(self: *Compile, source: LazyPath) void {
     const b = self.step.owner;
     const source_duped = source.dupe(b);
     self.link_objects.append(.{ .assembly_file = source_duped }) catch @panic("OOM");
     source_duped.addStepDependencies(&self.step);
 }
 
-pub fn addObjectFile(self: *Compile, source_file: []const u8) void {
-    self.addObjectFileSource(.{ .path = source_file });
-}
-
-pub fn addObjectFileSource(self: *Compile, source: FileSource) void {
+pub fn addObjectFile(self: *Compile, source: LazyPath) void {
     const b = self.step.owner;
     self.link_objects.append(.{ .static_path = source.dupe(b) }) catch @panic("OOM");
     source.addStepDependencies(&self.step);
@@ -1042,14 +1036,16 @@ pub fn addObject(self: *Compile, obj: *Compile) void {
     self.linkLibraryOrObject(obj);
 }
 
-pub fn addSystemIncludePath(self: *Compile, path: []const u8) void {
+pub fn addSystemIncludePath(self: *Compile, path: LazyPath) void {
     const b = self.step.owner;
-    self.include_dirs.append(IncludeDir{ .raw_path_system = b.dupe(path) }) catch @panic("OOM");
+    self.include_dirs.append(IncludeDir{ .path_system = path.dupe(b) }) catch @panic("OOM");
+    path.addStepDependencies(&self.step);
 }
 
-pub fn addIncludePath(self: *Compile, path: []const u8) void {
+pub fn addIncludePath(self: *Compile, path: LazyPath) void {
     const b = self.step.owner;
-    self.include_dirs.append(IncludeDir{ .raw_path = b.dupe(path) }) catch @panic("OOM");
+    self.include_dirs.append(IncludeDir{ .path = path.dupe(b) }) catch @panic("OOM");
+    path.addStepDependencies(&self.step);
 }
 
 pub fn addConfigHeader(self: *Compile, config_header: *Step.ConfigHeader) void {
@@ -1057,32 +1053,17 @@ pub fn addConfigHeader(self: *Compile, config_header: *Step.ConfigHeader) void {
     self.include_dirs.append(.{ .config_header_step = config_header }) catch @panic("OOM");
 }
 
-pub fn addLibraryPath(self: *Compile, path: []const u8) void {
-    const b = self.step.owner;
-    self.lib_paths.append(.{ .path = b.dupe(path) }) catch @panic("OOM");
-}
-
-pub fn addLibraryPathDirectorySource(self: *Compile, directory_source: FileSource) void {
+pub fn addLibraryPath(self: *Compile, directory_source: LazyPath) void {
     self.lib_paths.append(directory_source) catch @panic("OOM");
     directory_source.addStepDependencies(&self.step);
 }
 
-pub fn addRPath(self: *Compile, path: []const u8) void {
-    const b = self.step.owner;
-    self.rpaths.append(.{ .path = b.dupe(path) }) catch @panic("OOM");
-}
-
-pub fn addRPathDirectorySource(self: *Compile, directory_source: FileSource) void {
+pub fn addRPath(self: *Compile, directory_source: LazyPath) void {
     self.rpaths.append(directory_source) catch @panic("OOM");
     directory_source.addStepDependencies(&self.step);
 }
 
-pub fn addFrameworkPath(self: *Compile, dir_path: []const u8) void {
-    const b = self.step.owner;
-    self.framework_dirs.append(.{ .path = b.dupe(dir_path) }) catch @panic("OOM");
-}
-
-pub fn addFrameworkPathDirectorySource(self: *Compile, directory_source: FileSource) void {
+pub fn addFrameworkPath(self: *Compile, directory_source: LazyPath) void {
     self.framework_dirs.append(directory_source) catch @panic("OOM");
     directory_source.addStepDependencies(&self.step);
 }
@@ -1364,7 +1345,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
                 .exe => @panic("Cannot link with an executable build artifact"),
                 .@"test" => @panic("Cannot link with a test"),
                 .obj => {
-                    try zig_args.append(other.getOutputSource().getPath(b));
+                    try zig_args.append(other.getEmittedBin().getPath(b));
                 },
                 .lib => l: {
                     if (self.isStaticLibrary() and other.isStaticLibrary()) {
@@ -1372,7 +1353,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
                         break :l;
                     }
 
-                    const full_path_lib = other.getOutputLibSource().getPath(b);
+                    const full_path_lib = other.getEmittedImplib().getPath(b);
                     try zig_args.append(full_path_lib);
 
                     if (other.linkage == Linkage.dynamic and !self.target.isWindows()) {
@@ -1432,7 +1413,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
             },
 
             .c_source_file => |c_source_file| {
-                if (c_source_file.args.len == 0) {
+                if (c_source_file.flags.len == 0) {
                     if (prev_has_cflags) {
                         try zig_args.append("-cflags");
                         try zig_args.append("--");
@@ -1440,13 +1421,13 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
                     }
                 } else {
                     try zig_args.append("-cflags");
-                    for (c_source_file.args) |arg| {
+                    for (c_source_file.flags) |arg| {
                         try zig_args.append(arg);
                     }
                     try zig_args.append("--");
                     prev_has_cflags = true;
                 }
-                try zig_args.append(c_source_file.source.getPath(b));
+                try zig_args.append(c_source_file.file.getPath(b));
             },
 
             .c_source_files => |c_source_files| {
@@ -1746,18 +1727,18 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
 
     for (self.include_dirs.items) |include_dir| {
         switch (include_dir) {
-            .raw_path => |include_path| {
+            .path => |include_path| {
                 try zig_args.append("-I");
-                try zig_args.append(b.pathFromRoot(include_path));
+                try zig_args.append(include_path.getPath(b));
             },
-            .raw_path_system => |include_path| {
+            .path_system => |include_path| {
                 if (b.sysroot != null) {
                     try zig_args.append("-iwithsysroot");
                 } else {
                     try zig_args.append("-isystem");
                 }
 
-                const resolved_include_path = b.pathFromRoot(include_path);
+                const resolved_include_path = include_path.getPath(b);
 
                 const common_include_path = if (builtin.os.tag == .windows and b.sysroot != null and fs.path.isAbsolute(resolved_include_path)) blk: {
                     // We need to check for disk designator and strip it out from dir path so
@@ -1775,7 +1756,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
             },
             .other_step => |other| {
                 if (other.emit_h) {
-                    const h_path = other.getOutputHSource().getPath(b);
+                    const h_path = other.getEmittedH().getPath(b);
                     try zig_args.append("-isystem");
                     try zig_args.append(fs.path.dirname(h_path).?);
                 }
@@ -1907,7 +1888,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
 
     if (self.zig_lib_dir) |dir| {
         try zig_args.append("--zig-lib-dir");
-        try zig_args.append(b.pathFromRoot(dir));
+        try zig_args.append(dir.getPath(b));
     } else if (b.zig_lib_dir) |dir| {
         try zig_args.append("--zig-lib-dir");
         try zig_args.append(dir);
@@ -1915,7 +1896,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
 
     if (self.main_pkg_path) |dir| {
         try zig_args.append("--main-pkg-path");
-        try zig_args.append(b.pathFromRoot(dir));
+        try zig_args.append(dir.getPath(b));
     }
 
     try addFlag(&zig_args, "PIC", self.force_pic);
@@ -2042,7 +2023,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
     {
         try doAtomicSymLinks(
             step,
-            self.getOutputSource().getPath(b),
+            self.getEmittedBin().getPath(b),
             self.major_only_filename.?,
             self.name_only_filename.?,
         );
lib/std/Build/Step/ConfigHeader.zig
@@ -6,16 +6,18 @@ const Allocator = std.mem.Allocator;
 pub const Style = union(enum) {
     /// The configure format supported by autotools. It uses `#undef foo` to
     /// mark lines that can be substituted with different values.
-    autoconf: std.Build.FileSource,
+    autoconf: std.Build.LazyPath,
     /// The configure format supported by CMake. It uses `@@FOO@@` and
     /// `#cmakedefine` for template substitution.
-    cmake: std.Build.FileSource,
+    cmake: std.Build.LazyPath,
     /// Instead of starting with an input file, start with nothing.
     blank,
     /// Start with nothing, like blank, and output a nasm .asm file.
     nasm,
 
-    pub fn getFileSource(style: Style) ?std.Build.FileSource {
+    pub const getFileSource = getPath; // DEPRECATED, use getPath
+
+    pub fn getPath(style: Style) ?std.Build.LazyPath {
         switch (style) {
             .autoconf, .cmake => |s| return s,
             .blank, .nasm => return null,
@@ -54,7 +56,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
 
     var include_path: []const u8 = "config.h";
 
-    if (options.style.getFileSource()) |s| switch (s) {
+    if (options.style.getPath()) |s| switch (s) {
         .path => |p| {
             const basename = std.fs.path.basename(p);
             if (std.mem.endsWith(u8, basename, ".h.in")) {
@@ -68,7 +70,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
         include_path = p;
     }
 
-    const name = if (options.style.getFileSource()) |s|
+    const name = if (options.style.getPath()) |s|
         owner.fmt("configure {s} header {s} to {s}", .{
             @tagName(options.style), s.getDisplayName(), include_path,
         })
@@ -98,7 +100,9 @@ pub fn addValues(self: *ConfigHeader, values: anytype) void {
     return addValuesInner(self, values) catch @panic("OOM");
 }
 
-pub fn getFileSource(self: *ConfigHeader) std.Build.FileSource {
+pub const getFileSource = getTemplate; // DEPRECATED, use getOutput
+
+pub fn getTemplate(self: *ConfigHeader) std.Build.LazyPath {
     return .{ .generated = &self.output_file };
 }
 
lib/std/Build/Step/InstallArtifact.zig
@@ -76,7 +76,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
     var all_cached = true;
 
     {
-        const full_src_path = self.artifact.getOutputSource().getPath(src_builder);
+        const full_src_path = self.artifact.getEmittedBin().getPath(src_builder);
         const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_dest_path, .{}) catch |err| {
             return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
                 full_src_path, full_dest_path, @errorName(err),
@@ -95,7 +95,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
         self.artifact.target.isWindows() and
         self.artifact.emit_implib != .no_emit)
     {
-        const full_src_path = self.artifact.getOutputLibSource().getPath(src_builder);
+        const full_src_path = self.artifact.getEmittedImplib().getPath(src_builder);
         const full_implib_path = dest_builder.getInstallPath(self.dest_dir, self.artifact.out_lib_filename);
         const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_implib_path, .{}) catch |err| {
             return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
@@ -105,7 +105,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
         all_cached = all_cached and p == .fresh;
     }
     if (self.pdb_dir) |pdb_dir| {
-        const full_src_path = self.artifact.getOutputPdbSource().getPath(src_builder);
+        const full_src_path = self.artifact.getEmittedPdb().getPath(src_builder);
         const full_pdb_path = dest_builder.getInstallPath(pdb_dir, self.artifact.out_pdb_filename);
         const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_pdb_path, .{}) catch |err| {
             return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
@@ -115,7 +115,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
         all_cached = all_cached and p == .fresh;
     }
     if (self.h_dir) |h_dir| {
-        const full_src_path = self.artifact.getOutputHSource().getPath(src_builder);
+        const full_src_path = self.artifact.getEmittedH().getPath(src_builder);
         const full_h_path = dest_builder.getInstallPath(h_dir, self.artifact.out_h_filename);
         const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_h_path, .{}) catch |err| {
             return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
lib/std/Build/Step/InstallDir.zig
@@ -2,7 +2,7 @@ const std = @import("std");
 const mem = std.mem;
 const fs = std.fs;
 const Step = std.Build.Step;
-const FileSource = std.Build.FileSource;
+const LazyPath = std.Build.LazyPath;
 const InstallDir = std.Build.InstallDir;
 const InstallDirStep = @This();
 
@@ -15,7 +15,7 @@ dest_builder: *std.Build,
 pub const base_id = .install_dir;
 
 pub const Options = struct {
-    source_dir: FileSource,
+    source_dir: LazyPath,
     install_dir: InstallDir,
     install_subdir: []const u8,
     /// File paths which end in any of these suffixes will be excluded
lib/std/Build/Step/InstallFile.zig
@@ -1,6 +1,6 @@
 const std = @import("std");
 const Step = std.Build.Step;
-const FileSource = std.Build.FileSource;
+const LazyPath = std.Build.LazyPath;
 const InstallDir = std.Build.InstallDir;
 const InstallFile = @This();
 const assert = std.debug.assert;
@@ -8,7 +8,7 @@ const assert = std.debug.assert;
 pub const base_id = .install_file;
 
 step: Step,
-source: FileSource,
+source: LazyPath,
 dir: InstallDir,
 dest_rel_path: []const u8,
 /// This is used by the build system when a file being installed comes from one
@@ -17,7 +17,7 @@ dest_builder: *std.Build,
 
 pub fn create(
     owner: *std.Build,
-    source: FileSource,
+    source: LazyPath,
     dir: InstallDir,
     dest_rel_path: []const u8,
 ) *InstallFile {
lib/std/Build/Step/ObjCopy.zig
@@ -20,7 +20,7 @@ pub const RawFormat = enum {
 };
 
 step: Step,
-file_source: std.Build.FileSource,
+input_file: std.Build.LazyPath,
 basename: []const u8,
 output_file: std.Build.GeneratedFile,
 
@@ -37,30 +37,32 @@ pub const Options = struct {
 
 pub fn create(
     owner: *std.Build,
-    file_source: std.Build.FileSource,
+    input_file: std.Build.LazyPath,
     options: Options,
 ) *ObjCopy {
     const self = owner.allocator.create(ObjCopy) catch @panic("OOM");
     self.* = ObjCopy{
         .step = Step.init(.{
             .id = base_id,
-            .name = owner.fmt("objcopy {s}", .{file_source.getDisplayName()}),
+            .name = owner.fmt("objcopy {s}", .{input_file.getDisplayName()}),
             .owner = owner,
             .makeFn = make,
         }),
-        .file_source = file_source,
-        .basename = options.basename orelse file_source.getDisplayName(),
+        .input_file = input_file,
+        .basename = options.basename orelse input_file.getDisplayName(),
         .output_file = std.Build.GeneratedFile{ .step = &self.step },
 
         .format = options.format,
         .only_section = options.only_section,
         .pad_to = options.pad_to,
     };
-    file_source.addStepDependencies(&self.step);
+    input_file.addStepDependencies(&self.step);
     return self;
 }
 
-pub fn getOutputSource(self: *const ObjCopy) std.Build.FileSource {
+pub const getOutputSource = getOutput; // DEPRECATED, use getOutput
+
+pub fn getOutput(self: *const ObjCopy) std.Build.LazyPath {
     return .{ .generated = &self.output_file };
 }
 
@@ -75,7 +77,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
     // bytes when ObjCopy implementation is modified incompatibly.
     man.hash.add(@as(u32, 0xe18b7baf));
 
-    const full_src_path = self.file_source.getPath(b);
+    const full_src_path = self.input_file.getPath(b);
     _ = try man.addFile(full_src_path, null);
     man.hash.addOptionalBytes(self.only_section);
     man.hash.addOptional(self.pad_to);
lib/std/Build/Step/Options.zig
@@ -3,7 +3,7 @@ const builtin = @import("builtin");
 const fs = std.fs;
 const Step = std.Build.Step;
 const GeneratedFile = std.Build.GeneratedFile;
-const FileSource = std.Build.FileSource;
+const LazyPath = std.Build.LazyPath;
 
 const Options = @This();
 
@@ -13,8 +13,7 @@ step: Step,
 generated_file: GeneratedFile,
 
 contents: std.ArrayList(u8),
-artifact_args: std.ArrayList(OptionArtifactArg),
-file_source_args: std.ArrayList(OptionFileSourceArg),
+args: std.ArrayList(OptionLazyPathArg),
 
 pub fn create(owner: *std.Build) *Options {
     const self = owner.allocator.create(Options) catch @panic("OOM");
@@ -27,8 +26,7 @@ pub fn create(owner: *std.Build) *Options {
         }),
         .generated_file = undefined,
         .contents = std.ArrayList(u8).init(owner.allocator),
-        .artifact_args = std.ArrayList(OptionArtifactArg).init(owner.allocator),
-        .file_source_args = std.ArrayList(OptionFileSourceArg).init(owner.allocator),
+        .args = std.ArrayList(OptionLazyPathArg).init(owner.allocator),
     };
     self.generated_file = .{ .step = &self.step };
 
@@ -168,35 +166,42 @@ fn printLiteral(out: anytype, val: anytype, indent: u8) !void {
     }
 }
 
+pub const addOptionFileSource = addOptionPath; // DEPRECATED, use addPathOption
+
 /// The value is the path in the cache dir.
 /// Adds a dependency automatically.
-pub fn addOptionFileSource(
+pub fn addOptionPath(
     self: *Options,
     name: []const u8,
-    source: FileSource,
+    path: LazyPath,
 ) void {
-    self.file_source_args.append(.{
-        .name = name,
-        .source = source.dupe(self.step.owner),
+    self.args.append(.{
+        .name = self.step.owner.dupe(name),
+        .path = path.dupe(self.step.owner),
     }) catch @panic("OOM");
-    source.addStepDependencies(&self.step);
+    path.addStepDependencies(&self.step);
 }
 
 /// The value is the path in the cache dir.
 /// Adds a dependency automatically.
 pub fn addOptionArtifact(self: *Options, name: []const u8, artifact: *Step.Compile) void {
-    self.artifact_args.append(.{ .name = self.step.owner.dupe(name), .artifact = artifact }) catch @panic("OOM");
+    self.args.append(.{
+        .name = self.step.owner.dupe(name),
+        .artifact = artifact.getEmittedBin,
+    }) catch @panic("OOM");
     self.step.dependOn(&artifact.step);
 }
 
 pub fn createModule(self: *Options) *std.Build.Module {
     return self.step.owner.createModule(.{
-        .source_file = self.getSource(),
+        .source_file = self.getOutput(),
         .dependencies = &.{},
     });
 }
 
-pub fn getSource(self: *Options) FileSource {
+pub const getSource = getOutput; // DEPRECATED, use getOutput
+
+pub fn getOutput(self: *Options) LazyPath {
     return .{ .generated = &self.generated_file };
 }
 
@@ -207,19 +212,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
     const b = step.owner;
     const self = @fieldParentPtr(Options, "step", step);
 
-    for (self.artifact_args.items) |item| {
-        self.addOption(
-            []const u8,
-            item.name,
-            b.pathFromRoot(item.artifact.getOutputSource().getPath(b)),
-        );
-    }
-
-    for (self.file_source_args.items) |item| {
+    for (self.args.items) |item| {
         self.addOption(
             []const u8,
             item.name,
-            item.source.getPath(b),
+            item.path.getPath(b),
         );
     }
 
@@ -294,14 +291,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
     }
 }
 
-const OptionArtifactArg = struct {
-    name: []const u8,
-    artifact: *Step.Compile,
-};
-
-const OptionFileSourceArg = struct {
+const OptionLazyPathArg = struct {
     name: []const u8,
-    source: FileSource,
+    path: LazyPath,
 };
 
 test Options {
lib/std/Build/Step/Run.zig
@@ -82,7 +82,7 @@ has_side_effects: bool = false,
 pub const StdIn = union(enum) {
     none,
     bytes: []const u8,
-    file_source: std.Build.FileSource,
+    file_source: std.Build.LazyPath,
 };
 
 pub const StdIo = union(enum) {
@@ -120,15 +120,15 @@ pub const StdIo = union(enum) {
 
 pub const Arg = union(enum) {
     artifact: *Step.Compile,
-    file_source: PrefixedFileSource,
-    directory_source: PrefixedFileSource,
+    file_source: PrefixedLazyPath,
+    directory_source: PrefixedLazyPath,
     bytes: []u8,
     output: *Output,
 };
 
-pub const PrefixedFileSource = struct {
+pub const PrefixedLazyPath = struct {
     prefix: []const u8,
-    file_source: std.Build.FileSource,
+    file_source: std.Build.LazyPath,
 };
 
 pub const Output = struct {
@@ -169,9 +169,9 @@ pub fn addArtifactArg(self: *Run, artifact: *Step.Compile) void {
 }
 
 /// This provides file path as a command line argument to the command being
-/// run, and returns a FileSource which can be used as inputs to other APIs
+/// run, and returns a LazyPath which can be used as inputs to other APIs
 /// throughout the build system.
-pub fn addOutputFileArg(self: *Run, basename: []const u8) std.Build.FileSource {
+pub fn addOutputFileArg(self: *Run, basename: []const u8) std.Build.LazyPath {
     return self.addPrefixedOutputFileArg("", basename);
 }
 
@@ -179,7 +179,7 @@ pub fn addPrefixedOutputFileArg(
     self: *Run,
     prefix: []const u8,
     basename: []const u8,
-) std.Build.FileSource {
+) std.Build.LazyPath {
     const b = self.step.owner;
 
     const output = b.allocator.create(Output) catch @panic("OOM");
@@ -197,14 +197,18 @@ pub fn addPrefixedOutputFileArg(
     return .{ .generated = &output.generated_file };
 }
 
-pub fn addFileSourceArg(self: *Run, file_source: std.Build.FileSource) void {
-    self.addPrefixedFileSourceArg("", file_source);
+pub const addFileSourceArg = addFileArg; // DEPRECATED, use addFileArg
+
+pub fn addFileArg(self: *Run, file_source: std.Build.LazyPath) void {
+    self.addPrefixedFileArg("", file_source);
 }
 
-pub fn addPrefixedFileSourceArg(self: *Run, prefix: []const u8, file_source: std.Build.FileSource) void {
+pub const addPrefixedFileSourceArg = addPrefixedFileArg; // DEPRECATED, use addPrefixedFileArg
+
+pub fn addPrefixedFileArg(self: *Run, prefix: []const u8, file_source: std.Build.LazyPath) void {
     const b = self.step.owner;
 
-    const prefixed_file_source: PrefixedFileSource = .{
+    const prefixed_file_source: PrefixedLazyPath = .{
         .prefix = b.dupe(prefix),
         .file_source = file_source.dupe(b),
     };
@@ -212,14 +216,18 @@ pub fn addPrefixedFileSourceArg(self: *Run, prefix: []const u8, file_source: std
     file_source.addStepDependencies(&self.step);
 }
 
-pub fn addDirectorySourceArg(self: *Run, directory_source: std.Build.FileSource) void {
-    self.addPrefixedDirectorySourceArg("", directory_source);
+pub const addDirectorySourceArg = addDirectoryArg; // DEPRECATED, use addDirectoryArg
+
+pub fn addDirectoryArg(self: *Run, directory_source: std.Build.LazyPath) void {
+    self.addPrefixedDirectoryArg("", directory_source);
 }
 
-pub fn addPrefixedDirectorySourceArg(self: *Run, prefix: []const u8, directory_source: std.Build.FileSource) void {
+pub const addPrefixedDirectorySourceArg = addPrefixedDirectoryArg; // DEPRECATED, use addPrefixedDirectoryArg
+
+pub fn addPrefixedDirectoryArg(self: *Run, prefix: []const u8, directory_source: std.Build.LazyPath) void {
     const b = self.step.owner;
 
-    const prefixed_directory_source: PrefixedFileSource = .{
+    const prefixed_directory_source: PrefixedLazyPath = .{
         .prefix = b.dupe(prefix),
         .file_source = directory_source.dupe(b),
     };
@@ -331,7 +339,7 @@ pub fn addCheck(self: *Run, new_check: StdIo.Check) void {
     }
 }
 
-pub fn captureStdErr(self: *Run) std.Build.FileSource {
+pub fn captureStdErr(self: *Run) std.Build.LazyPath {
     assert(self.stdio != .inherit);
 
     if (self.captured_stderr) |output| return .{ .generated = &output.generated_file };
@@ -346,7 +354,7 @@ pub fn captureStdErr(self: *Run) std.Build.FileSource {
     return .{ .generated = &output.generated_file };
 }
 
-pub fn captureStdOut(self: *Run) std.Build.FileSource {
+pub fn captureStdOut(self: *Run) std.Build.LazyPath {
     assert(self.stdio != .inherit);
 
     if (self.captured_stdout) |output| return .{ .generated = &output.generated_file };
@@ -449,7 +457,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
                     self.addPathForDynLibs(artifact);
                 }
                 const file_path = artifact.installed_path orelse
-                    artifact.getOutputSource().getPath(b);
+                    artifact.getEmittedBin().getPath(b);
 
                 try argv_list.append(file_path);
 
@@ -1241,7 +1249,7 @@ fn addPathForDynLibs(self: *Run, artifact: *Step.Compile) void {
         switch (link_object) {
             .other_step => |other| {
                 if (other.target.isWindows() and other.isDynamicLibrary()) {
-                    addPathDir(self, fs.path.dirname(other.getOutputSource().getPath(b)).?);
+                    addPathDir(self, fs.path.dirname(other.getEmittedBin().getPath(b)).?);
                     addPathForDynLibs(self, other);
                 }
             },
lib/std/Build/Step/TranslateC.zig
@@ -9,7 +9,7 @@ const TranslateC = @This();
 pub const base_id = .translate_c;
 
 step: Step,
-source: std.Build.FileSource,
+source: std.Build.LazyPath,
 include_dirs: std.ArrayList([]const u8),
 c_macros: std.ArrayList([]const u8),
 out_basename: []const u8,
@@ -18,7 +18,7 @@ optimize: std.builtin.OptimizeMode,
 output_file: std.Build.GeneratedFile,
 
 pub const Options = struct {
-    source_file: std.Build.FileSource,
+    source_file: std.Build.LazyPath,
     target: CrossTarget,
     optimize: std.builtin.OptimizeMode,
 };
@@ -53,10 +53,14 @@ pub const AddExecutableOptions = struct {
     linkage: ?Step.Compile.Linkage = null,
 };
 
+pub fn getOutput(self: *TranslateC) std.Build.LazyPath {
+    return .{ .generated = &self.output_file };
+}
+
 /// Creates a step to build an executable from the translated source.
 pub fn addExecutable(self: *TranslateC, options: AddExecutableOptions) *Step.Compile {
     return self.step.owner.addExecutable(.{
-        .root_source_file = .{ .generated = &self.output_file },
+        .root_source_file = self.getOutput(),
         .name = options.name orelse "translated_c",
         .version = options.version,
         .target = options.target orelse self.target,
@@ -70,7 +74,7 @@ pub fn addExecutable(self: *TranslateC, options: AddExecutableOptions) *Step.Com
 /// `createModule` can be used instead to create a private module.
 pub fn addModule(self: *TranslateC, name: []const u8) *std.Build.Module {
     return self.step.owner.addModule(name, .{
-        .source_file = .{ .generated = &self.output_file },
+        .source_file = self.getOutput(),
     });
 }
 
@@ -83,7 +87,7 @@ pub fn createModule(self: *TranslateC) *std.Build.Module {
 
     module.* = .{
         .builder = b,
-        .source_file = .{ .generated = &self.output_file },
+        .source_file = self.getOutput(),
         .dependencies = std.StringArrayHashMap(*std.Build.Module).init(b.allocator),
     };
     return module;
@@ -96,7 +100,7 @@ pub fn addIncludeDir(self: *TranslateC, include_dir: []const u8) void {
 pub fn addCheckFile(self: *TranslateC, expected_matches: []const []const u8) *Step.CheckFile {
     return Step.CheckFile.create(
         self.step.owner,
-        .{ .generated = &self.output_file },
+        self.getOutput(),
         .{ .expected_matches = expected_matches },
     );
 }
lib/std/Build/Step/WriteFile.zig
@@ -28,7 +28,9 @@ pub const File = struct {
     sub_path: []const u8,
     contents: Contents,
 
-    pub fn getFileSource(self: *File) std.Build.FileSource {
+    pub const getFileSource = getPath; // DEPRECATED, use getPath
+
+    pub fn getPath(self: *File) std.Build.LazyPath {
         return .{ .generated = &self.generated_file };
     }
 };
@@ -40,7 +42,7 @@ pub const OutputSourceFile = struct {
 
 pub const Contents = union(enum) {
     bytes: []const u8,
-    copy: std.Build.FileSource,
+    copy: std.Build.LazyPath,
 };
 
 pub fn create(owner: *std.Build) *WriteFile {
@@ -59,7 +61,7 @@ pub fn create(owner: *std.Build) *WriteFile {
     return wf;
 }
 
-pub fn add(wf: *WriteFile, sub_path: []const u8, bytes: []const u8) std.Build.FileSource {
+pub fn add(wf: *WriteFile, sub_path: []const u8, bytes: []const u8) std.Build.LazyPath {
     const b = wf.step.owner;
     const gpa = b.allocator;
     const file = gpa.create(File) catch @panic("OOM");
@@ -70,7 +72,7 @@ pub fn add(wf: *WriteFile, sub_path: []const u8, bytes: []const u8) std.Build.Fi
     };
     wf.files.append(gpa, file) catch @panic("OOM");
     wf.maybeUpdateName();
-    return file.getFileSource();
+    return file.getPath();
 }
 
 /// Place the file into the generated directory within the local cache,
@@ -80,7 +82,7 @@ pub fn add(wf: *WriteFile, sub_path: []const u8, bytes: []const u8) std.Build.Fi
 /// include sub-directories, in which case this step will ensure the
 /// required sub-path exists.
 /// This is the option expected to be used most commonly with `addCopyFile`.
-pub fn addCopyFile(wf: *WriteFile, source: std.Build.FileSource, sub_path: []const u8) std.Build.FileSource {
+pub fn addCopyFile(wf: *WriteFile, source: std.Build.LazyPath, sub_path: []const u8) std.Build.LazyPath {
     const b = wf.step.owner;
     const gpa = b.allocator;
     const file = gpa.create(File) catch @panic("OOM");
@@ -93,7 +95,7 @@ pub fn addCopyFile(wf: *WriteFile, source: std.Build.FileSource, sub_path: []con
 
     wf.maybeUpdateName();
     source.addStepDependencies(&wf.step);
-    return file.getFileSource();
+    return file.getLazyPath();
 }
 
 /// A path relative to the package root.
@@ -101,7 +103,7 @@ pub fn addCopyFile(wf: *WriteFile, source: std.Build.FileSource, sub_path: []con
 /// used as part of the normal build process, but as a utility occasionally
 /// run by a developer with intent to modify source files and then commit
 /// those changes to version control.
-pub fn addCopyFileToSource(wf: *WriteFile, source: std.Build.FileSource, sub_path: []const u8) void {
+pub fn addCopyFileToSource(wf: *WriteFile, source: std.Build.LazyPath, sub_path: []const u8) void {
     const b = wf.step.owner;
     wf.output_source_files.append(b.allocator, .{
         .contents = .{ .copy = source },
@@ -123,11 +125,13 @@ pub fn addBytesToSource(wf: *WriteFile, bytes: []const u8, sub_path: []const u8)
     }) catch @panic("OOM");
 }
 
-pub const getFileSource = @compileError("Deprecated; use the return value from add()/addCopyFile(), or use files[i].getFileSource()");
+pub const getFileSource = @compileError("Deprecated; use the return value from add()/addCopyFile(), or use files[i].getPath()");
+
+pub const getDirectorySource = getDirectory;
 
-/// Returns a `FileSource` representing the base directory that contains all the
+/// Returns a `LazyPath` representing the base directory that contains all the
 /// files from this `WriteFile`.
-pub fn getDirectorySource(wf: *WriteFile) std.Build.FileSource {
+pub fn getDirectory(wf: *WriteFile) std.Build.LazyPath {
     return .{ .generated = &wf.generated_directory };
 }
 
lib/std/Build.zig
@@ -471,7 +471,7 @@ pub fn addOptions(self: *Build) *Step.Options {
 
 pub const ExecutableOptions = struct {
     name: []const u8,
-    root_source_file: ?FileSource = null,
+    root_source_file: ?LazyPath = null,
     version: ?std.SemanticVersion = null,
     target: CrossTarget = .{},
     optimize: std.builtin.Mode = .Debug,
@@ -502,7 +502,7 @@ pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile {
 
 pub const ObjectOptions = struct {
     name: []const u8,
-    root_source_file: ?FileSource = null,
+    root_source_file: ?LazyPath = null,
     target: CrossTarget,
     optimize: std.builtin.Mode,
     max_rss: usize = 0,
@@ -529,7 +529,7 @@ pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile {
 
 pub const SharedLibraryOptions = struct {
     name: []const u8,
-    root_source_file: ?FileSource = null,
+    root_source_file: ?LazyPath = null,
     version: ?std.SemanticVersion = null,
     target: CrossTarget,
     optimize: std.builtin.Mode,
@@ -559,7 +559,7 @@ pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile
 
 pub const StaticLibraryOptions = struct {
     name: []const u8,
-    root_source_file: ?FileSource = null,
+    root_source_file: ?LazyPath = null,
     target: CrossTarget,
     optimize: std.builtin.Mode,
     version: ?std.SemanticVersion = null,
@@ -589,7 +589,7 @@ pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile
 
 pub const TestOptions = struct {
     name: []const u8 = "test",
-    root_source_file: FileSource,
+    root_source_file: LazyPath,
     target: CrossTarget = .{},
     optimize: std.builtin.Mode = .Debug,
     version: ?std.SemanticVersion = null,
@@ -621,7 +621,7 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile {
 
 pub const AssemblyOptions = struct {
     name: []const u8,
-    source_file: FileSource,
+    source_file: LazyPath,
     target: CrossTarget,
     optimize: std.builtin.Mode,
     max_rss: usize = 0,
@@ -636,7 +636,7 @@ pub fn addAssembly(b: *Build, options: AssemblyOptions) *Step.Compile {
         .optimize = options.optimize,
         .max_rss = options.max_rss,
     });
-    obj_step.addAssemblyFileSource(options.source_file.dupe(b));
+    obj_step.addAssemblyLazyPath(options.source_file.dupe(b));
     return obj_step;
 }
 
@@ -655,7 +655,7 @@ pub const ModuleDependency = struct {
 };
 
 pub const CreateModuleOptions = struct {
-    source_file: FileSource,
+    source_file: LazyPath,
     dependencies: []const ModuleDependency = &.{},
 };
 
@@ -1284,22 +1284,22 @@ pub fn installLibFile(self: *Build, src_path: []const u8, dest_rel_path: []const
     self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .lib, dest_rel_path).step);
 }
 
-pub fn addObjCopy(b: *Build, source: FileSource, options: Step.ObjCopy.Options) *Step.ObjCopy {
+pub fn addObjCopy(b: *Build, source: LazyPath, options: Step.ObjCopy.Options) *Step.ObjCopy {
     return Step.ObjCopy.create(b, source, options);
 }
 
 ///`dest_rel_path` is relative to install prefix path
-pub fn addInstallFile(self: *Build, source: FileSource, dest_rel_path: []const u8) *Step.InstallFile {
+pub fn addInstallFile(self: *Build, source: LazyPath, dest_rel_path: []const u8) *Step.InstallFile {
     return self.addInstallFileWithDir(source.dupe(self), .prefix, dest_rel_path);
 }
 
 ///`dest_rel_path` is relative to bin path
-pub fn addInstallBinFile(self: *Build, source: FileSource, dest_rel_path: []const u8) *Step.InstallFile {
+pub fn addInstallBinFile(self: *Build, source: LazyPath, dest_rel_path: []const u8) *Step.InstallFile {
     return self.addInstallFileWithDir(source.dupe(self), .bin, dest_rel_path);
 }
 
 ///`dest_rel_path` is relative to lib path
-pub fn addInstallLibFile(self: *Build, source: FileSource, dest_rel_path: []const u8) *Step.InstallFile {
+pub fn addInstallLibFile(self: *Build, source: LazyPath, dest_rel_path: []const u8) *Step.InstallFile {
     return self.addInstallFileWithDir(source.dupe(self), .lib, dest_rel_path);
 }
 
@@ -1309,7 +1309,7 @@ pub fn addInstallHeaderFile(b: *Build, src_path: []const u8, dest_rel_path: []co
 
 pub fn addInstallFileWithDir(
     self: *Build,
-    source: FileSource,
+    source: LazyPath,
     install_dir: InstallDir,
     dest_rel_path: []const u8,
 ) *Step.InstallFile {
@@ -1322,7 +1322,7 @@ pub fn addInstallDirectory(self: *Build, options: InstallDirectoryOptions) *Step
 
 pub fn addCheckFile(
     b: *Build,
-    file_source: FileSource,
+    file_source: LazyPath,
     options: Step.CheckFile.Options,
 ) *Step.CheckFile {
     return Step.CheckFile.create(b, file_source, options);
@@ -1608,7 +1608,7 @@ pub const Module = struct {
     /// This could either be a generated file, in which case the module
     /// contains exactly one file, or it could be a path to the root source
     /// file of directory of files which constitute the module.
-    source_file: FileSource,
+    source_file: LazyPath,
     dependencies: std.StringArrayHashMap(*Module),
 };
 
@@ -1630,8 +1630,10 @@ pub const GeneratedFile = struct {
     }
 };
 
-/// A file source is a reference to an existing or future file.
-pub const FileSource = union(enum) {
+pub const FileSource = LazyPath; // DEPRECATED, use LazyPath now
+
+/// A reference to an existing or future path.
+pub const LazyPath = union(enum) {
     /// A plain file path, relative to build root or absolute.
     path: []const u8,
 
@@ -1641,14 +1643,14 @@ pub const FileSource = union(enum) {
 
     /// Returns a new file source that will have a relative path to the build root guaranteed.
     /// This should be preferred over setting `.path` directly as it documents that the files are in the project directory.
-    pub fn relative(path: []const u8) FileSource {
+    pub fn relative(path: []const u8) LazyPath {
         std.debug.assert(!std.fs.path.isAbsolute(path));
-        return FileSource{ .path = path };
+        return LazyPath{ .path = path };
     }
 
     /// Returns a string that can be shown to represent the file source.
     /// Either returns the path or `"generated"`.
-    pub fn getDisplayName(self: FileSource) []const u8 {
+    pub fn getDisplayName(self: LazyPath) []const u8 {
         return switch (self) {
             .path => self.path,
             .generated => "generated",
@@ -1656,7 +1658,7 @@ pub const FileSource = union(enum) {
     }
 
     /// Adds dependencies this file source implies to the given step.
-    pub fn addStepDependencies(self: FileSource, other_step: *Step) void {
+    pub fn addStepDependencies(self: LazyPath, other_step: *Step) void {
         switch (self) {
             .path => {},
             .generated => |gen| other_step.dependOn(gen.step),
@@ -1664,14 +1666,14 @@ pub const FileSource = union(enum) {
     }
 
     /// Should only be called during make(), returns a path relative to the build root or absolute.
-    pub fn getPath(self: FileSource, src_builder: *Build) []const u8 {
+    pub fn getPath(self: LazyPath, src_builder: *Build) []const u8 {
         return getPath2(self, src_builder, null);
     }
 
     /// Should only be called during make(), returns a path relative to the build root or absolute.
     /// asking_step is only used for debugging purposes; it's the step being run that is asking for
     /// the path.
-    pub fn getPath2(self: FileSource, src_builder: *Build, asking_step: ?*Step) []const u8 {
+    pub fn getPath2(self: LazyPath, src_builder: *Build, asking_step: ?*Step) []const u8 {
         switch (self) {
             .path => |p| return src_builder.pathFromRoot(p),
             .generated => |gen| return gen.path orelse {
@@ -1684,7 +1686,7 @@ pub const FileSource = union(enum) {
     }
 
     /// Duplicates the file source for a given builder.
-    pub fn dupe(self: FileSource, b: *Build) FileSource {
+    pub fn dupe(self: LazyPath, b: *Build) LazyPath {
         return switch (self) {
             .path => |p| .{ .path = b.dupePath(p) },
             .generated => |gen| .{ .generated = gen },
test/link/interdependent_static_c_libs/build.zig
@@ -16,16 +16,16 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = .{},
     });
-    lib_a.addCSourceFile("a.c", &[_][]const u8{});
-    lib_a.addIncludePath(".");
+    lib_a.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &[_][]const u8{} });
+    lib_a.addIncludePath(.{ .path = "." });
 
     const lib_b = b.addStaticLibrary(.{
         .name = "b",
         .optimize = optimize,
         .target = .{},
     });
-    lib_b.addCSourceFile("b.c", &[_][]const u8{});
-    lib_b.addIncludePath(".");
+    lib_b.addCSourceFile(.{ .file = .{ .path = "b.c" }, .flags = &[_][]const u8{} });
+    lib_b.addIncludePath(.{ .path = "." });
 
     const test_exe = b.addTest(.{
         .root_source_file = .{ .path = "main.zig" },
@@ -33,7 +33,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
     });
     test_exe.linkLibrary(lib_a);
     test_exe.linkLibrary(lib_b);
-    test_exe.addIncludePath(".");
+    test_exe.addIncludePath(.{ .path = "." });
 
     test_step.dependOn(&b.addRunArtifact(test_exe).step);
 }
test/link/macho/bugs/13056/build.zig
@@ -23,13 +23,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .name = "test",
         .optimize = optimize,
     });
-    exe.addSystemIncludePath(std.fs.path.join(b.allocator, &.{ sdk.path, "/usr/include" }) catch unreachable);
-    exe.addIncludePath(std.fs.path.join(b.allocator, &.{ sdk.path, "/usr/include/c++/v1" }) catch unreachable);
-    exe.addCSourceFile("test.cpp", &.{
+    exe.addSystemIncludePath(.{ .path = b.pathJoin(&.{ sdk.path, "/usr/include" }) });
+    exe.addIncludePath(.{ .path = b.pathJoin(&.{ sdk.path, "/usr/include/c++/v1" }) });
+    exe.addCSourceFile(.{ .file = .{ .path = "test.cpp" }, .flags = &.{
         "-nostdlib++",
         "-nostdinc++",
-    });
-    exe.addObjectFile(std.fs.path.join(b.allocator, &.{ sdk.path, "/usr/lib/libc++.tbd" }) catch unreachable);
+    } });
+    exe.addObjectFile(.{ .path = b.pathJoin(&.{ sdk.path, "/usr/lib/libc++.tbd" }) });
 
     const run_cmd = b.addRunArtifact(exe);
     run_cmd.expectStdErrEqual("x: 5\n");
test/link/macho/dead_strip/build.zig
@@ -52,7 +52,7 @@ fn createScenario(
         .optimize = optimize,
         .target = target,
     });
-    exe.addCSourceFile("main.c", &[0][]const u8{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
     exe.linkLibC();
     return exe;
 }
test/link/macho/dead_strip_dylibs/build.zig
@@ -53,7 +53,7 @@ fn createScenario(
         .name = name,
         .optimize = optimize,
     });
-    exe.addCSourceFile("main.c", &[0][]const u8{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
     exe.linkLibC();
     exe.linkFramework("Cocoa");
     return exe;
test/link/macho/dylib/build.zig
@@ -21,7 +21,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = target,
     });
-    dylib.addCSourceFile("a.c", &.{});
+    dylib.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &.{} });
     dylib.linkLibC();
 
     const check_dylib = dylib.checkObject();
@@ -39,10 +39,10 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = target,
     });
-    exe.addCSourceFile("main.c", &.{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
     exe.linkSystemLibrary("a");
-    exe.addLibraryPathDirectorySource(dylib.getOutputDirectorySource());
-    exe.addRPathDirectorySource(dylib.getOutputDirectorySource());
+    exe.addLibraryPath(dylib.getEmitDirectory());
+    exe.addRPath(dylib.getEmitDirectory());
     exe.linkLibC();
 
     const check_exe = exe.checkObject();
@@ -55,7 +55,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
 
     check_exe.checkStart();
     check_exe.checkExact("cmd RPATH");
-    check_exe.checkExactFileSource("path", dylib.getOutputDirectorySource());
+    check_exe.checkExactPath("path", dylib.getOutputDirectorySource());
     test_step.dependOn(&check_exe.step);
 
     const run = b.addRunArtifact(exe);
test/link/macho/empty/build.zig
@@ -20,8 +20,8 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = target,
     });
-    exe.addCSourceFile("main.c", &[0][]const u8{});
-    exe.addCSourceFile("empty.c", &[0][]const u8{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
+    exe.addCSourceFile(.{ .file = .{ .path = "empty.c" }, .flags = &[0][]const u8{} });
     exe.linkLibC();
 
     const run_cmd = b.addRunArtifact(exe);
test/link/macho/entry/build.zig
@@ -18,7 +18,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = .{ .os_tag = .macos },
     });
-    exe.addCSourceFile("main.c", &.{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
     exe.linkLibC();
     exe.entry_symbol_name = "_non_main";
 
test/link/macho/entry_in_archive/build.zig
@@ -18,7 +18,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = .{ .os_tag = .macos },
     });
-    lib.addCSourceFile("main.c", &.{});
+    lib.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
     lib.linkLibC();
 
     const exe = b.addExecutable(.{
test/link/macho/entry_in_dylib/build.zig
@@ -18,7 +18,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = .{ .os_tag = .macos },
     });
-    lib.addCSourceFile("bootstrap.c", &.{});
+    lib.addCSourceFile(.{ .file = .{ .path = "bootstrap.c" }, .flags = &.{} });
     lib.linkLibC();
     lib.linker_allow_shlib_undefined = true;
 
@@ -27,7 +27,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = .{ .os_tag = .macos },
     });
-    exe.addCSourceFile("main.c", &.{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
     exe.linkLibrary(lib);
     exe.linkLibC();
     exe.entry_symbol_name = "_bootstrap";
test/link/macho/headerpad/build.zig
@@ -113,7 +113,7 @@ fn simpleExe(
         .name = name,
         .optimize = optimize,
     });
-    exe.addCSourceFile("main.c", &.{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
     exe.linkLibC();
     exe.linkFramework("CoreFoundation");
     exe.linkFramework("Foundation");
test/link/macho/needed_framework/build.zig
@@ -20,7 +20,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .name = "test",
         .optimize = optimize,
     });
-    exe.addCSourceFile("main.c", &[0][]const u8{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
     exe.linkLibC();
     exe.linkFrameworkNeeded("Cocoa");
     exe.dead_strip_dylibs = true;
test/link/macho/needed_library/build.zig
@@ -21,7 +21,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = target,
     });
-    dylib.addCSourceFile("a.c", &.{});
+    dylib.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &.{} });
     dylib.linkLibC();
 
     // -dead_strip_dylibs
@@ -31,11 +31,11 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = target,
     });
-    exe.addCSourceFile("main.c", &[0][]const u8{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
     exe.linkLibC();
     exe.linkSystemLibraryNeeded("a");
-    exe.addLibraryPathDirectorySource(dylib.getOutputDirectorySource());
-    exe.addRPathDirectorySource(dylib.getOutputDirectorySource());
+    exe.addLibraryPath(dylib.getEmitDirectory());
+    exe.addRPath(dylib.getEmitDirectory());
     exe.dead_strip_dylibs = true;
 
     const check = exe.checkObject();
test/link/macho/objc/build.zig
@@ -18,9 +18,9 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .name = "test",
         .optimize = optimize,
     });
-    exe.addIncludePath(".");
-    exe.addCSourceFile("Foo.m", &[0][]const u8{});
-    exe.addCSourceFile("test.m", &[0][]const u8{});
+    exe.addIncludePath(.{ .path = "." });
+    exe.addCSourceFile(.{ .file = .{ .path = "Foo.m" }, .flags = &[0][]const u8{} });
+    exe.addCSourceFile(.{ .file = .{ .path = "test.m" }, .flags = &[0][]const u8{} });
     exe.linkLibC();
     // TODO when we figure out how to ship framework stubs for cross-compilation,
     // populate paths to the sysroot here.
test/link/macho/objcpp/build.zig
@@ -19,9 +19,9 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
     });
     b.default_step.dependOn(&exe.step);
-    exe.addIncludePath(".");
-    exe.addCSourceFile("Foo.mm", &[0][]const u8{});
-    exe.addCSourceFile("test.mm", &[0][]const u8{});
+    exe.addIncludePath(.{ .path = "." });
+    exe.addCSourceFile(.{ .file = .{ .path = "Foo.mm" }, .flags = &[0][]const u8{} });
+    exe.addCSourceFile(.{ .file = .{ .path = "test.mm" }, .flags = &[0][]const u8{} });
     exe.linkLibCpp();
     // TODO when we figure out how to ship framework stubs for cross-compilation,
     // populate paths to the sysroot here.
test/link/macho/pagezero/build.zig
@@ -15,7 +15,7 @@ pub fn build(b: *std.Build) void {
             .optimize = optimize,
             .target = target,
         });
-        exe.addCSourceFile("main.c", &.{});
+        exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
         exe.linkLibC();
         exe.pagezero_size = 0x4000;
 
@@ -39,7 +39,7 @@ pub fn build(b: *std.Build) void {
             .optimize = optimize,
             .target = target,
         });
-        exe.addCSourceFile("main.c", &.{});
+        exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
         exe.linkLibC();
         exe.pagezero_size = 0;
 
test/link/macho/search_strategy/build.zig
@@ -55,7 +55,7 @@ fn createScenario(
         .optimize = optimize,
         .target = target,
     });
-    static.addCSourceFile("a.c", &.{});
+    static.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &.{} });
     static.linkLibC();
     static.override_dest_dir = std.Build.InstallDir{
         .custom = "static",
@@ -67,7 +67,7 @@ fn createScenario(
         .optimize = optimize,
         .target = target,
     });
-    dylib.addCSourceFile("a.c", &.{});
+    dylib.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &.{} });
     dylib.linkLibC();
     dylib.override_dest_dir = std.Build.InstallDir{
         .custom = "dynamic",
@@ -78,11 +78,11 @@ fn createScenario(
         .optimize = optimize,
         .target = target,
     });
-    exe.addCSourceFile("main.c", &.{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
     exe.linkSystemLibraryName(name);
     exe.linkLibC();
-    exe.addLibraryPathDirectorySource(static.getOutputDirectorySource());
-    exe.addLibraryPathDirectorySource(dylib.getOutputDirectorySource());
-    exe.addRPathDirectorySource(dylib.getOutputDirectorySource());
+    exe.addLibraryPath(static.getEmitDirectory());
+    exe.addLibraryPath(dylib.getEmitDirectory());
+    exe.addRPath(dylib.getEmitDirectory());
     return exe;
 }
test/link/macho/stack_size/build.zig
@@ -20,7 +20,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = target,
     });
-    exe.addCSourceFile("main.c", &.{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
     exe.linkLibC();
     exe.stack_size = 0x100000000;
 
test/link/macho/tls/build.zig
@@ -21,7 +21,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = target,
     });
-    lib.addCSourceFile("a.c", &.{});
+    lib.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &.{} });
     lib.linkLibC();
 
     const test_exe = b.addTest(.{
test/link/macho/unwind_info/build.zig
@@ -75,7 +75,7 @@ fn createScenario(
         .target = target,
     });
     b.default_step.dependOn(&exe.step);
-    exe.addIncludePath(".");
+    exe.addIncludePath(.{ .path = "." });
     exe.addCSourceFiles(&[_][]const u8{
         "main.cpp",
         "simple_string.cpp",
test/link/macho/weak_framework/build.zig
@@ -18,7 +18,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .name = "test",
         .optimize = optimize,
     });
-    exe.addCSourceFile("main.c", &[0][]const u8{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
     exe.linkLibC();
     exe.linkFrameworkWeak("Cocoa");
 
test/link/macho/weak_library/build.zig
@@ -21,7 +21,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .target = target,
         .optimize = optimize,
     });
-    dylib.addCSourceFile("a.c", &.{});
+    dylib.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &.{} });
     dylib.linkLibC();
     b.installArtifact(dylib);
 
@@ -30,11 +30,11 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .target = target,
         .optimize = optimize,
     });
-    exe.addCSourceFile("main.c", &[0][]const u8{});
+    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
     exe.linkLibC();
     exe.linkSystemLibraryWeak("a");
-    exe.addLibraryPathDirectorySource(dylib.getOutputDirectorySource());
-    exe.addRPathDirectorySource(dylib.getOutputDirectorySource());
+    exe.addLibraryPath(dylib.getEmitDirectory());
+    exe.addRPath(dylib.getEmitDirectory());
 
     const check = exe.checkObject();
     check.checkStart();
test/link/static_libs_from_object_files/build.zig
@@ -2,7 +2,7 @@ const std = @import("std");
 const builtin = @import("builtin");
 
 const Build = std.Build;
-const FileSource = Build.FileSource;
+const LazyPath = Build.LazyPath;
 const Step = Build.Step;
 const Run = Step.Run;
 const WriteFile = Step.WriteFile;
@@ -14,7 +14,7 @@ pub fn build(b: *Build) void {
     b.default_step = test_step;
 
     // generate c files
-    const files = b.allocator.alloc(std.Build.FileSource, nb_files) catch unreachable;
+    const files = b.allocator.alloc(LazyPath, nb_files) catch unreachable;
     defer b.allocator.free(files);
     {
         for (files[0 .. nb_files - 1], 1..nb_files) |*file, i| {
@@ -47,7 +47,7 @@ pub fn build(b: *Build) void {
     add(b, test_step, files, .ReleaseFast);
 }
 
-fn add(b: *Build, test_step: *Step, files: []const std.Build.FileSource, optimize: std.builtin.OptimizeMode) void {
+fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.builtin.OptimizeMode) void {
     const flags = [_][]const u8{
         "-Wall",
         "-std=c11",
@@ -63,7 +63,7 @@ fn add(b: *Build, test_step: *Step, files: []const std.Build.FileSource, optimiz
         });
 
         for (files) |file| {
-            exe.addCSourceFileSource(.{ .source = file, .args = &flags });
+            exe.addCSourceFile(.{ .file = file, .flags = &flags });
         }
 
         const run_cmd = b.addRunArtifact(exe);
@@ -88,7 +88,7 @@ fn add(b: *Build, test_step: *Step, files: []const std.Build.FileSource, optimiz
 
         for (files, 1..) |file, i| {
             const lib = if (i & 1 == 0) lib_a else lib_b;
-            lib.addCSourceFileSource(.{ .source = file, .args = &flags });
+            lib.addCSourceFile(.{ .file = file, .flags = &flags });
         }
 
         const exe = b.addExecutable(.{
@@ -125,7 +125,7 @@ fn add(b: *Build, test_step: *Step, files: []const std.Build.FileSource, optimiz
                 .target = .{},
                 .optimize = optimize,
             });
-            obj.addCSourceFileSource(.{ .source = file, .args = &flags });
+            obj.addCSourceFile(.{ .file = file, .flags = &flags });
 
             const lib = if (i & 1 == 0) lib_a else lib_b;
             lib.addObject(obj);
test/link/wasm/extern/build.zig
@@ -19,7 +19,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = .{ .cpu_arch = .wasm32, .os_tag = .wasi },
     });
-    exe.addCSourceFile("foo.c", &.{});
+    exe.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &.{} });
     exe.use_llvm = false;
     exe.use_lld = false;
 
test/link/wasm/infer-features/build.zig
@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
             .os_tag = .freestanding,
         },
     });
-    c_obj.addCSourceFile("foo.c", &.{});
+    c_obj.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &.{} });
 
     // Wasm library that doesn't have any features specified. This will
     // infer its featureset from other linked object files.
test/src/Cases.zig
@@ -518,12 +518,12 @@ pub fn lowerToBuildSteps(
         }
 
         const writefiles = b.addWriteFiles();
-        var file_sources = std.StringHashMap(std.Build.FileSource).init(b.allocator);
+        var file_sources = std.StringHashMap(std.Build.LazyPath).init(b.allocator);
         defer file_sources.deinit();
         for (update.files.items) |file| {
             file_sources.put(file.path, writefiles.add(file.path, file.src)) catch @panic("OOM");
         }
-        const root_source_file = writefiles.files.items[0].getFileSource();
+        const root_source_file = writefiles.files.items[0].getPath();
 
         const artifact = if (case.is_test) b.addTest(.{
             .root_source_file = root_source_file,
@@ -577,7 +577,7 @@ pub fn lowerToBuildSteps(
                 parent_step.dependOn(&artifact.step);
             },
             .CompareObjectFile => |expected_output| {
-                const check = b.addCheckFile(artifact.getOutputSource(), .{
+                const check = b.addCheckFile(artifact.getEmittedBin(), .{
                     .expected_exact = expected_output,
                 });
 
test/src/CompareOutput.zig
@@ -99,7 +99,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
                 .target = .{},
                 .optimize = .Debug,
             });
-            exe.addAssemblyFileSource(write_src.files.items[0].getFileSource());
+            exe.addAssemblyFile(write_src.files.items[0].getPath());
 
             const run = b.addRunArtifact(exe);
             run.setName(annotated_case_name);
@@ -119,7 +119,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
 
                 const exe = b.addExecutable(.{
                     .name = "test",
-                    .root_source_file = write_src.files.items[0].getFileSource(),
+                    .root_source_file = write_src.files.items[0].getPath(),
                     .optimize = optimize,
                     .target = .{},
                 });
@@ -145,7 +145,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
 
             const exe = b.addExecutable(.{
                 .name = "test",
-                .root_source_file = write_src.files.items[0].getFileSource(),
+                .root_source_file = write_src.files.items[0].getPath(),
                 .target = .{},
                 .optimize = .Debug,
             });
test/src/run_translated_c.zig
@@ -85,7 +85,7 @@ pub const RunTranslatedCContext = struct {
             _ = write_src.add(src_file.filename, src_file.source);
         }
         const translate_c = b.addTranslateC(.{
-            .source_file = write_src.files.items[0].getFileSource(),
+            .source_file = write_src.files.items[0].getPath(),
             .target = .{},
             .optimize = .Debug,
         });
test/src/StackTrace.zig
@@ -75,7 +75,7 @@ fn addExpect(
     const write_src = b.addWriteFile("source.zig", source);
     const exe = b.addExecutable(.{
         .name = "test",
-        .root_source_file = write_src.files.items[0].getFileSource(),
+        .root_source_file = write_src.files.items[0].getPath(),
         .optimize = optimize_mode,
         .target = .{},
     });
@@ -88,7 +88,7 @@ fn addExpect(
 
     const check_run = b.addRunArtifact(self.check_exe);
     check_run.setName(annotated_case_name);
-    check_run.addFileSourceArg(run.captureStdErr());
+    check_run.addFileArg(run.captureStdErr());
     check_run.addArgs(&.{
         @tagName(optimize_mode),
     });
test/src/translate_c.zig
@@ -108,7 +108,7 @@ pub const TranslateCContext = struct {
         }
 
         const translate_c = b.addTranslateC(.{
-            .source_file = write_src.files.items[0].getFileSource(),
+            .source_file = write_src.files.items[0].getPath(),
             .target = case.target,
             .optimize = .Debug,
         });
test/standalone/c_compiler/build.zig
@@ -19,7 +19,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .optimize = optimize,
         .target = target,
     });
-    exe_c.addCSourceFile("test.c", &[0][]const u8{});
+    exe_c.addCSourceFile(.{ .file = .{ .path = "test.c" }, .flags = &[0][]const u8{} });
     exe_c.linkLibC();
 
     const exe_cpp = b.addExecutable(.{
@@ -28,7 +28,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .target = target,
     });
     b.default_step.dependOn(&exe_cpp.step);
-    exe_cpp.addCSourceFile("test.cpp", &[0][]const u8{});
+    exe_cpp.addCSourceFile(.{ .file = .{ .path = "test.cpp" }, .flags = &[0][]const u8{} });
     exe_cpp.linkLibCpp();
 
     switch (target.getOsTag()) {
test/standalone/embed_generated_file/build.zig
@@ -19,7 +19,7 @@ pub fn build(b: *std.Build) void {
         .optimize = .Debug,
     });
     exe.addAnonymousModule("bootloader.elf", .{
-        .source_file = bootloader.getOutputSource(),
+        .source_file = bootloader.getEmittedBin(),
     });
 
     test_step.dependOn(&exe.step);
test/standalone/issue_794/build.zig
@@ -7,7 +7,7 @@ pub fn build(b: *std.Build) void {
     const test_artifact = b.addTest(.{
         .root_source_file = .{ .path = "main.zig" },
     });
-    test_artifact.addIncludePath("a_directory");
+    test_artifact.addIncludePath(.{ .path = "a_directory" });
 
     test_step.dependOn(&test_artifact.step);
 }
test/standalone/issue_8550/build.zig
@@ -19,8 +19,8 @@ pub fn build(b: *std.Build) !void {
         .optimize = optimize,
         .target = target,
     });
-    kernel.addObjectFile("./boot.S");
-    kernel.setLinkerScriptPath(.{ .path = "./linker.ld" });
+    kernel.addObjectFile(.{ .path = "./boot.S" });
+    kernel.setLinkerScript(.{ .path = "./linker.ld" });
     b.installArtifact(kernel);
 
     test_step.dependOn(&kernel.step);
test/standalone/main_pkg_path/build.zig
@@ -7,7 +7,7 @@ pub fn build(b: *std.Build) void {
     const test_exe = b.addTest(.{
         .root_source_file = .{ .path = "a/test.zig" },
     });
-    test_exe.setMainPkgPath(".");
+    test_exe.setMainPkgPath(.{.path="."});
 
     test_step.dependOn(&b.addRunArtifact(test_exe).step);
 }
test/standalone/mix_c_files/build.zig
@@ -21,7 +21,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
         .root_source_file = .{ .path = "main.zig" },
         .optimize = optimize,
     });
-    exe.addCSourceFile("test.c", &[_][]const u8{"-std=c11"});
+    exe.addCSourceFile(.{ .file = .{ .path = "test.c" }, .flags = &[_][]const u8{"-std=c11"} });
     exe.linkLibC();
 
     const run_cmd = b.addRunArtifact(exe);
test/standalone/mix_o_files/build.zig
@@ -19,7 +19,10 @@ pub fn build(b: *std.Build) void {
         .optimize = optimize,
         .target = target,
     });
-    exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"});
+    exe.addCSourceFile(.{
+        .file = .{ .path = "test.c" },
+        .flags = &[_][]const u8{"-std=c99"},
+    });
     exe.addObject(obj);
     exe.linkSystemLibrary("c");
 
test/standalone/shared_library/build.zig
@@ -19,7 +19,10 @@ pub fn build(b: *std.Build) void {
         .target = target,
         .optimize = optimize,
     });
-    exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"});
+    exe.addCSourceFile(.{
+        .file = .{ .path = "test.c" },
+        .flags = &[_][]const u8{"-std=c99"},
+    });
     exe.linkLibrary(lib);
     exe.linkSystemLibrary("c");
 
test/standalone/stack_iterator/build.zig
@@ -74,7 +74,10 @@ pub fn build(b: *std.Build) void {
         if (target.isWindows()) c_shared_lib.defineCMacro("LIB_API", "__declspec(dllexport)");
 
         c_shared_lib.strip = false;
-        c_shared_lib.addCSourceFile("shared_lib.c", &.{"-fomit-frame-pointer"});
+        c_shared_lib.addCSourceFile(.{
+            .file = .{ .path = "shared_lib.c" },
+            .flags = &.{"-fomit-frame-pointer"},
+        });
         c_shared_lib.linkLibC();
 
         const exe = b.addExecutable(.{
test/standalone/static_c_lib/build.zig
@@ -11,15 +11,15 @@ pub fn build(b: *std.Build) void {
         .optimize = optimize,
         .target = .{},
     });
-    foo.addCSourceFile("foo.c", &[_][]const u8{});
-    foo.addIncludePath(".");
+    foo.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &[_][]const u8{} });
+    foo.addIncludePath(.{ .path = "." });
 
     const test_exe = b.addTest(.{
         .root_source_file = .{ .path = "foo.zig" },
         .optimize = optimize,
     });
     test_exe.linkLibrary(foo);
-    test_exe.addIncludePath(".");
+    test_exe.addIncludePath(.{ .path = "." });
 
     test_step.dependOn(&b.addRunArtifact(test_exe).step);
 }
test/standalone/use_alias/build.zig
@@ -10,7 +10,7 @@ pub fn build(b: *std.Build) void {
         .root_source_file = .{ .path = "main.zig" },
         .optimize = optimize,
     });
-    main.addIncludePath(".");
+    main.addIncludePath(.{.path="."});
 
     test_step.dependOn(&b.addRunArtifact(main).step);
 }
test/tests.zig
@@ -759,7 +759,7 @@ pub fn addCliTests(b: *std.Build) *Step {
             "-fno-emit-bin", "-fno-emit-h",
             "-fstrip",       "-OReleaseFast",
         });
-        run.addFileSourceArg(writefile.files.items[0].getFileSource());
+        run.addFileArg(writefile.files.items[0].getPath());
         const example_s = run.addPrefixedOutputFileArg("-femit-asm=", "example.s");
 
         const checkfile = b.addCheckFile(example_s, .{
@@ -1017,8 +1017,8 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
         else
             "";
 
-        these_tests.overrideZigLibDir("lib");
-        these_tests.addIncludePath("test");
+        these_tests.overrideZigLibDir(.{ .path = "lib" });
+        these_tests.addIncludePath(.{ .path = "test" });
 
         const qualified_name = b.fmt("{s}-{s}-{s}{s}{s}{s}", .{
             options.name,
@@ -1038,10 +1038,10 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
                 .link_libc = test_target.link_libc,
                 .target = altered_target,
             });
-            compile_c.overrideZigLibDir("lib");
-            compile_c.addCSourceFileSource(.{
-                .source = these_tests.getOutputSource(),
-                .args = &.{
+            compile_c.overrideZigLibDir(.{ .path = "lib" });
+            compile_c.addCSourceFile(.{
+                .file = these_tests.getEmittedBin(),
+                .flags = &.{
                     // TODO output -std=c89 compatible C code
                     "-std=c99",
                     "-pedantic",
@@ -1058,7 +1058,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
                     "-Wno-absolute-value",
                 },
             });
-            compile_c.addIncludePath("lib"); // for zig.h
+            compile_c.addIncludePath(.{ .path = "lib" }); // for zig.h
             if (test_target.target.getOsTag() == .windows) {
                 if (true) {
                     // Unfortunately this requires about 8G of RAM for clang to compile
@@ -1131,7 +1131,10 @@ pub fn addCAbiTests(b: *std.Build, skip_non_native: bool, skip_release: bool) *S
                 test_step.target_info.dynamic_linker.max_byte = null;
             }
             test_step.linkLibC();
-            test_step.addCSourceFile("test/c_abi/cfuncs.c", &.{"-std=c99"});
+            test_step.addCSourceFile(.{
+                .file = .{ .path = "test/c_abi/cfuncs.c" },
+                .flags = &.{"-std=c99"},
+            });
 
             // This test is intentionally trying to check if the external ABI is
             // done properly. LTO would be a hindrance to this.
build.zig
@@ -45,9 +45,9 @@ pub fn build(b: *std.Build) !void {
     const docgen_cmd = b.addRunArtifact(docgen_exe);
     docgen_cmd.addArgs(&.{ "--zig", b.zig_exe });
     if (b.zig_lib_dir) |p| {
-        docgen_cmd.addArgs(&.{ "--zig-lib-dir", p });
+        docgen_cmd.addArgs(&.{ "--zig-lib-dir", b.pathFromRoot(p) });
     }
-    docgen_cmd.addFileSourceArg(.{ .path = "doc/langref.html.in" });
+    docgen_cmd.addFileArg(.{ .path = "doc/langref.html.in" });
     const langref_file = docgen_cmd.addOutputFileArg("langref.html");
     const install_langref = b.addInstallFileWithDir(langref_file, .prefix, "doc/langref.html");
     if (!skip_install_langref) {
@@ -58,7 +58,7 @@ pub fn build(b: *std.Build) !void {
         .root_source_file = .{ .path = "lib/std/std.zig" },
         .target = target,
     });
-    autodoc_test.overrideZigLibDir("lib");
+    autodoc_test.overrideZigLibDir(.{ .path = "lib" });
     autodoc_test.emit_bin = .no_emit; // https://github.com/ziglang/zig/issues/16351
     const install_std_docs = b.addInstallDirectory(.{
         .source_dir = autodoc_test.getEmittedDocs(),
@@ -89,7 +89,7 @@ pub fn build(b: *std.Build) !void {
         .root_source_file = .{ .path = "test/src/Cases.zig" },
         .optimize = optimize,
     });
-    check_case_exe.main_pkg_path = ".";
+    check_case_exe.setMainPkgPath(.{ .path = "." });
     check_case_exe.stack_size = stack_size;
     check_case_exe.single_threaded = single_threaded;
 
@@ -352,10 +352,9 @@ pub fn build(b: *std.Build) !void {
     exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);
     exe_options.addOption(bool, "value_tracing", value_tracing);
     if (tracy) |tracy_path| {
-        const client_cpp = fs.path.join(
-            b.allocator,
+        const client_cpp = b.pathJoin(
             &[_][]const u8{ tracy_path, "public", "TracyClient.cpp" },
-        ) catch unreachable;
+        );
 
         // On mingw, we need to opt into windows 7+ to get some features required by tracy.
         const tracy_c_flags: []const []const u8 = if (target.isWindows() and target.getAbi() == .gnu)
@@ -363,8 +362,8 @@ pub fn build(b: *std.Build) !void {
         else
             &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" };
 
-        exe.addIncludePath(tracy_path);
-        exe.addCSourceFile(client_cpp, tracy_c_flags);
+        exe.addIncludePath(.{ .path = tracy_path });
+        exe.addCSourceFile(.{ .file = .{ .path = client_cpp }, .flags = tracy_c_flags });
         if (!enable_llvm) {
             exe.linkSystemLibraryName("c++");
         }
@@ -554,7 +553,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
     });
     run_opt.addArtifactArg(exe);
     run_opt.addArg("-o");
-    run_opt.addFileSourceArg(.{ .path = "stage1/zig1.wasm" });
+    run_opt.addFileArg(.{ .path = "stage1/zig1.wasm" });
 
     const copy_zig_h = b.addWriteFiles();
     copy_zig_h.addCopyFileToSource(.{ .path = "lib/zig.h" }, "stage1/zig.h");
@@ -603,7 +602,7 @@ fn addCmakeCfgOptionsToExe(
         // useful for package maintainers
         exe.headerpad_max_install_names = true;
     }
-    exe.addObjectFile(fs.path.join(b.allocator, &[_][]const u8{
+    exe.addObjectFile(.{ .path = b.pathJoin(&[_][]const u8{
         cfg.cmake_binary_dir,
         "zigcpp",
         b.fmt("{s}{s}{s}", .{
@@ -611,11 +610,11 @@ fn addCmakeCfgOptionsToExe(
             "zigcpp",
             cfg.cmake_static_library_suffix,
         }),
-    }) catch unreachable);
+    }) });
     assert(cfg.lld_include_dir.len != 0);
-    exe.addIncludePath(cfg.lld_include_dir);
-    exe.addIncludePath(cfg.llvm_include_dir);
-    exe.addLibraryPath(cfg.llvm_lib_dir);
+    exe.addIncludePath(.{ .path = cfg.lld_include_dir });
+    exe.addIncludePath(.{ .path = cfg.llvm_include_dir });
+    exe.addLibraryPath(.{ .path = cfg.llvm_lib_dir });
     addCMakeLibraryList(exe, cfg.clang_libraries);
     addCMakeLibraryList(exe, cfg.lld_libraries);
     addCMakeLibraryList(exe, cfg.llvm_libraries);
@@ -671,7 +670,7 @@ fn addCmakeCfgOptionsToExe(
     }
 
     if (cfg.dia_guids_lib.len != 0) {
-        exe.addObjectFile(cfg.dia_guids_lib);
+        exe.addObjectFile(.{ .path = cfg.dia_guids_lib });
     }
 }
 
@@ -732,7 +731,7 @@ fn addCxxKnownPath(
         }
         return error.RequiredLibraryNotFound;
     }
-    exe.addObjectFile(path_unpadded);
+    exe.addObjectFile(.{ .path = path_unpadded });
 
     // TODO a way to integrate with system c++ include files here
     // c++ -E -Wp,-v -xc++ /dev/null
@@ -752,7 +751,7 @@ fn addCMakeLibraryList(exe: *std.Build.Step.Compile, list: []const u8) void {
         } else if (exe.target.isWindows() and mem.endsWith(u8, lib, ".lib") and !fs.path.isAbsolute(lib)) {
             exe.linkSystemLibrary(lib[0 .. lib.len - ".lib".len]);
         } else {
-            exe.addObjectFile(lib);
+            exe.addObjectFile(.{ .path = lib });
         }
     }
 }