| ... | @@ -1228,11 +1228,12 @@ pub const GeneratedFile = struct { | ... | @@ -1228,11 +1228,12 @@ pub const GeneratedFile = struct { |
| 1228 | /// The step that generates the file | 1228 | /// The step that generates the file |
| 1229 | step: *Step, | 1229 | step: *Step, |
| 1230 | | 1230 | |
| 1231 | /// A function that returns the absolute path to the generated file. | 1231 | /// The path to the generated file. Must be either absolute or relative to the build root. |
| 1232 | getPathFn: fn (self: *const GeneratedFile) []const u8, | 1232 | /// This value must be set in the `fn make()` of the `step` and must not be `null` afterwards. |
| | 1233 | path: ?[]const u8 = null, |
| 1233 | | 1234 | |
| 1234 | pub fn getPath(self: *const GeneratedFile) []const u8 { | 1235 | pub fn getPath(self: *const GeneratedFile) []const u8 { |
| 1235 | return self.getPathFn(self); | 1236 | return self.path orelse @panic("getPath() was called on a GeneratedFile that wasn't build yet. Is there a missing Step dependency?"); |
| 1236 | } | 1237 | } |
| 1237 | }; | 1238 | }; |
| 1238 | | 1239 | |
| ... | @@ -1414,6 +1415,11 @@ pub const LibExeObjStep = struct { | ... | @@ -1414,6 +1415,11 @@ pub const LibExeObjStep = struct { |
| 1414 | | 1415 | |
| 1415 | want_lto: ?bool = null, | 1416 | want_lto: ?bool = null, |
| 1416 | | 1417 | |
| | 1418 | output_path_source: GeneratedFile, |
| | 1419 | output_lib_path_source: GeneratedFile, |
| | 1420 | output_h_path_source: GeneratedFile, |
| | 1421 | output_pdb_path_source: GeneratedFile, |
| | 1422 | |
| 1417 | const LinkObject = union(enum) { | 1423 | const LinkObject = union(enum) { |
| 1418 | static_path: FileSource, | 1424 | static_path: FileSource, |
| 1419 | other_step: *LibExeObjStep, | 1425 | other_step: *LibExeObjStep, |
| ... | @@ -1444,36 +1450,26 @@ pub const LibExeObjStep = struct { | ... | @@ -1444,36 +1450,26 @@ pub const LibExeObjStep = struct { |
| 1444 | pub const Linkage = enum { dynamic, static }; | 1450 | pub const Linkage = enum { dynamic, static }; |
| 1445 | | 1451 | |
| 1446 | pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource, kind: SharedLibKind) *LibExeObjStep { | 1452 | pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource, kind: SharedLibKind) *LibExeObjStep { |
| 1447 | const self = builder.allocator.create(LibExeObjStep) catch unreachable; | 1453 | return initExtraArgs(builder, name, root_src, Kind.Lib, .dynamic, switch (kind) { |
| 1448 | self.* = initExtraArgs(builder, name, root_src, Kind.Lib, .dynamic, switch (kind) { | | |
| 1449 | .versioned => |ver| ver, | 1454 | .versioned => |ver| ver, |
| 1450 | .unversioned => null, | 1455 | .unversioned => null, |
| 1451 | }); | 1456 | }); |
| 1452 | return self; | | |
| 1453 | } | 1457 | } |
| 1454 | | 1458 | |
| 1455 | pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep { | 1459 | pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep { |
| 1456 | const self = builder.allocator.create(LibExeObjStep) catch unreachable; | 1460 | return initExtraArgs(builder, name, root_src, Kind.Lib, .static, null); |
| 1457 | self.* = initExtraArgs(builder, name, root_src, Kind.Lib, .static, null); | | |
| 1458 | return self; | | |
| 1459 | } | 1461 | } |
| 1460 | | 1462 | |
| 1461 | pub fn createObject(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep { | 1463 | pub fn createObject(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep { |
| 1462 | const self = builder.allocator.create(LibExeObjStep) catch unreachable; | 1464 | return initExtraArgs(builder, name, root_src, Kind.Obj, .static, null); |
| 1463 | self.* = initExtraArgs(builder, name, root_src, Kind.Obj, .static, null); | | |
| 1464 | return self; | | |
| 1465 | } | 1465 | } |
| 1466 | | 1466 | |
| 1467 | pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?FileSource, linkage: Linkage) *LibExeObjStep { | 1467 | pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?FileSource, linkage: Linkage) *LibExeObjStep { |
| 1468 | const self = builder.allocator.create(LibExeObjStep) catch unreachable; | 1468 | return initExtraArgs(builder, name, root_src, Kind.Exe, linkage, null); |
| 1469 | self.* = initExtraArgs(builder, name, root_src, Kind.Exe, linkage, null); | | |
| 1470 | return self; | | |
| 1471 | } | 1469 | } |
| 1472 | | 1470 | |
| 1473 | pub fn createTest(builder: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep { | 1471 | pub fn createTest(builder: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep { |
| 1474 | const self = builder.allocator.create(LibExeObjStep) catch unreachable; | 1472 | return initExtraArgs(builder, name, root_src, Kind.Test, .static, null); |
| 1475 | self.* = initExtraArgs(builder, name, root_src, Kind.Test, .static, null); | | |
| 1476 | return self; | | |
| 1477 | } | 1473 | } |
| 1478 | | 1474 | |
| 1479 | fn initExtraArgs( | 1475 | fn initExtraArgs( |
| ... | @@ -1483,13 +1479,15 @@ pub const LibExeObjStep = struct { | ... | @@ -1483,13 +1479,15 @@ pub const LibExeObjStep = struct { |
| 1483 | kind: Kind, | 1479 | kind: Kind, |
| 1484 | linkage: Linkage, | 1480 | linkage: Linkage, |
| 1485 | ver: ?Version, | 1481 | ver: ?Version, |
| 1486 | ) LibExeObjStep { | 1482 | ) *LibExeObjStep { |
| 1487 | const name = builder.dupe(name_raw); | 1483 | const name = builder.dupe(name_raw); |
| 1488 | const root_src: ?FileSource = if (root_src_raw) |rsrc| rsrc.dupe(builder) else null; | 1484 | const root_src: ?FileSource = if (root_src_raw) |rsrc| rsrc.dupe(builder) else null; |
| 1489 | if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) { | 1485 | if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) { |
| 1490 | panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name}); | 1486 | panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name}); |
| 1491 | } | 1487 | } |
| 1492 | var self = LibExeObjStep{ | 1488 | |
| | 1489 | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| | 1490 | self.* = LibExeObjStep{ |
| 1493 | .strip = false, | 1491 | .strip = false, |
| 1494 | .builder = builder, | 1492 | .builder = builder, |
| 1495 | .verbose_link = false, | 1493 | .verbose_link = false, |
| ... | @@ -1534,6 +1532,11 @@ pub const LibExeObjStep = struct { | ... | @@ -1534,6 +1532,11 @@ pub const LibExeObjStep = struct { |
| 1534 | .override_dest_dir = null, | 1532 | .override_dest_dir = null, |
| 1535 | .installed_path = null, | 1533 | .installed_path = null, |
| 1536 | .install_step = null, | 1534 | .install_step = null, |
| | 1535 | |
| | 1536 | .output_path_source = GeneratedFile{ .step = &self.step }, |
| | 1537 | .output_lib_path_source = GeneratedFile{ .step = &self.step }, |
| | 1538 | .output_h_path_source = GeneratedFile{ .step = &self.step }, |
| | 1539 | .output_pdb_path_source = GeneratedFile{ .step = &self.step }, |
| 1537 | }; | 1540 | }; |
| 1538 | self.computeOutFileNames(); | 1541 | self.computeOutFileNames(); |
| 1539 | if (root_src) |rs| rs.addStepDependencies(&self.step); | 1542 | if (root_src) |rs| rs.addStepDependencies(&self.step); |
| ... | @@ -1871,45 +1874,31 @@ pub const LibExeObjStep = struct { | ... | @@ -1871,45 +1874,31 @@ pub const LibExeObjStep = struct { |
| 1871 | self.libc_file = if (libc_file) |f| f.dupe(self.builder) else null; | 1874 | self.libc_file = if (libc_file) |f| f.dupe(self.builder) else null; |
| 1872 | } | 1875 | } |
| 1873 | | 1876 | |
| 1874 | /// Unless setOutputDir was called, this function must be called only in | 1877 | /// Returns the generated executable, library or object file. |
| 1875 | /// the make step, from a step that has declared a dependency on this one. | | |
| 1876 | /// To run an executable built with zig build, use `run`, or create an install step and invoke it. | 1878 | /// To run an executable built with zig build, use `run`, or create an install step and invoke it. |
| 1877 | pub fn getOutputPath(self: *LibExeObjStep) []const u8 { | 1879 | pub fn getOutputSource(self: *LibExeObjStep) FileSource { |
| 1878 | return fs.path.join( | 1880 | return FileSource{ .generated = &self.output_path_source }; |
| 1879 | self.builder.allocator, | | |
| 1880 | &[_][]const u8{ self.output_dir.?, self.out_filename }, | | |
| 1881 | ) catch unreachable; | | |
| 1882 | } | 1881 | } |
| 1883 | | 1882 | |
| 1884 | /// Unless setOutputDir was called, this function must be called only in | 1883 | /// Returns the generated import library. This function can only be called for libraries. |
| 1885 | /// the make step, from a step that has declared a dependency on this one. | 1884 | pub fn getOutputLibSource(self: *LibExeObjStep) FileSource { |
| 1886 | pub fn getOutputLibPath(self: *LibExeObjStep) []const u8 { | | |
| 1887 | assert(self.kind == Kind.Lib); | 1885 | assert(self.kind == Kind.Lib); |
| 1888 | return fs.path.join( | 1886 | return FileSource{ .generated = &self.output_lib_path_source }; |
| 1889 | self.builder.allocator, | | |
| 1890 | &[_][]const u8{ self.output_dir.?, self.out_lib_filename }, | | |
| 1891 | ) catch unreachable; | | |
| 1892 | } | 1887 | } |
| 1893 | | 1888 | |
| 1894 | /// Unless setOutputDir was called, this function must be called only in | 1889 | /// Returns the generated header file. |
| 1895 | /// the make step, from a step that has declared a dependency on this one. | 1890 | /// This function can only be called for libraries or object files which have `emit_h` set. |
| 1896 | pub fn getOutputHPath(self: *LibExeObjStep) []const u8 { | 1891 | pub fn getOutputHSource(self: *LibExeObjStep) FileSource { |
| 1897 | assert(self.kind != Kind.Exe); | 1892 | assert(self.kind != Kind.Exe); |
| 1898 | assert(self.emit_h); | 1893 | assert(self.emit_h); |
| 1899 | return fs.path.join( | 1894 | return FileSource{ .generated = &self.output_h_path_source }; |
| 1900 | self.builder.allocator, | | |
| 1901 | &[_][]const u8{ self.output_dir.?, self.out_h_filename }, | | |
| 1902 | ) catch unreachable; | | |
| 1903 | } | 1895 | } |
| 1904 | | 1896 | |
| 1905 | /// Unless setOutputDir was called, this function must be called only in | 1897 | /// Returns the generated PDB file. This function can only be called for Windows and UEFI. |
| 1906 | /// the make step, from a step that has declared a dependency on this one. | 1898 | pub fn getOutputPdbSource(self: *LibExeObjStep) FileSource { |
| 1907 | pub fn getOutputPdbPath(self: *LibExeObjStep) []const u8 { | 1899 | // TODO: Is this right? Isn't PDB for *any* PE/COFF file? |
| 1908 | assert(self.target.isWindows() or self.target.isUefi()); | 1900 | assert(self.target.isWindows() or self.target.isUefi()); |
| 1909 | return fs.path.join( | 1901 | return FileSource{ .generated = &self.output_pdb_path_source }; |
| 1910 | self.builder.allocator, | | |
| 1911 | &[_][]const u8{ self.output_dir.?, self.out_pdb_filename }, | | |
| 1912 | ) catch unreachable; | | |
| 1913 | } | 1902 | } |
| 1914 | | 1903 | |
| 1915 | pub fn addAssemblyFile(self: *LibExeObjStep, path: []const u8) void { | 1904 | pub fn addAssemblyFile(self: *LibExeObjStep, path: []const u8) void { |
| ... | @@ -2185,6 +2174,28 @@ pub const LibExeObjStep = struct { | ... | @@ -2185,6 +2174,28 @@ pub const LibExeObjStep = struct { |
| 2185 | return error.NeedAnObject; | 2174 | return error.NeedAnObject; |
| 2186 | } | 2175 | } |
| 2187 | | 2176 | |
| | 2177 | // Update generated files |
| | 2178 | self.output_path_source.path = |
| | 2179 | fs.path.join( |
| | 2180 | self.builder.allocator, |
| | 2181 | &[_][]const u8{ self.output_dir.?, self.out_filename }, |
| | 2182 | ) catch unreachable; |
| | 2183 | self.output_lib_path_source.path = |
| | 2184 | fs.path.join( |
| | 2185 | self.builder.allocator, |
| | 2186 | &[_][]const u8{ self.output_dir.?, self.out_lib_filename }, |
| | 2187 | ) catch unreachable; |
| | 2188 | self.output_h_path_source.path = |
| | 2189 | fs.path.join( |
| | 2190 | self.builder.allocator, |
| | 2191 | &[_][]const u8{ self.output_dir.?, self.out_h_filename }, |
| | 2192 | ) catch unreachable; |
| | 2193 | self.output_pdb_path_source.path = |
| | 2194 | fs.path.join( |
| | 2195 | self.builder.allocator, |
| | 2196 | &[_][]const u8{ self.output_dir.?, self.out_pdb_filename }, |
| | 2197 | ) catch unreachable; |
| | 2198 | |
| 2188 | var zig_args = ArrayList([]const u8).init(builder.allocator); | 2199 | var zig_args = ArrayList([]const u8).init(builder.allocator); |
| 2189 | defer zig_args.deinit(); | 2200 | defer zig_args.deinit(); |
| 2190 | | 2201 | |
| ... | @@ -2219,10 +2230,10 @@ pub const LibExeObjStep = struct { | ... | @@ -2219,10 +2230,10 @@ pub const LibExeObjStep = struct { |
| 2219 | .Exe => unreachable, | 2230 | .Exe => unreachable, |
| 2220 | .Test => unreachable, | 2231 | .Test => unreachable, |
| 2221 | .Obj => { | 2232 | .Obj => { |
| 2222 | try zig_args.append(other.getOutputPath()); | 2233 | try zig_args.append(other.getOutputSource().getPath(builder)); |
| 2223 | }, | 2234 | }, |
| 2224 | .Lib => { | 2235 | .Lib => { |
| 2225 | const full_path_lib = other.getOutputLibPath(); | 2236 | const full_path_lib = other.getOutputLibSource().getPath(builder); |
| 2226 | try zig_args.append(full_path_lib); | 2237 | try zig_args.append(full_path_lib); |
| 2227 | | 2238 | |
| 2228 | if (other.linkage == .dynamic and !self.target.isWindows()) { | 2239 | if (other.linkage == .dynamic and !self.target.isWindows()) { |
| ... | @@ -2296,7 +2307,7 @@ pub const LibExeObjStep = struct { | ... | @@ -2296,7 +2307,7 @@ pub const LibExeObjStep = struct { |
| 2296 | self.addBuildOption( | 2307 | self.addBuildOption( |
| 2297 | []const u8, | 2308 | []const u8, |
| 2298 | item.name, | 2309 | item.name, |
| 2299 | self.builder.pathFromRoot(item.artifact.getOutputPath()), | 2310 | self.builder.pathFromRoot(item.artifact.getOutputSource().getPath(self.builder)), |
| 2300 | ); | 2311 | ); |
| 2301 | } | 2312 | } |
| 2302 | for (self.build_options_file_source_args.items) |item| { | 2313 | for (self.build_options_file_source_args.items) |item| { |
| ... | @@ -2560,7 +2571,7 @@ pub const LibExeObjStep = struct { | ... | @@ -2560,7 +2571,7 @@ pub const LibExeObjStep = struct { |
| 2560 | try zig_args.append(self.builder.pathFromRoot(include_path)); | 2571 | try zig_args.append(self.builder.pathFromRoot(include_path)); |
| 2561 | }, | 2572 | }, |
| 2562 | .other_step => |other| if (other.emit_h) { | 2573 | .other_step => |other| if (other.emit_h) { |
| 2563 | const h_path = other.getOutputHPath(); | 2574 | const h_path = other.getOutputHSource().getPath(self.builder); |
| 2564 | try zig_args.append("-isystem"); | 2575 | try zig_args.append("-isystem"); |
| 2565 | try zig_args.append(fs.path.dirname(h_path).?); | 2576 | try zig_args.append(fs.path.dirname(h_path).?); |
| 2566 | }, | 2577 | }, |
| ... | @@ -2701,7 +2712,7 @@ pub const LibExeObjStep = struct { | ... | @@ -2701,7 +2712,7 @@ pub const LibExeObjStep = struct { |
| 2701 | } | 2712 | } |
| 2702 | | 2713 | |
| 2703 | if (self.kind == .Lib and self.linkage == .dynamic and self.version != null and self.target.wantSharedLibSymLinks()) { | 2714 | if (self.kind == .Lib and self.linkage == .dynamic and self.version != null and self.target.wantSharedLibSymLinks()) { |
| 2704 | try doAtomicSymLinks(builder.allocator, self.getOutputPath(), self.major_only_filename.?, self.name_only_filename.?); | 2715 | try doAtomicSymLinks(builder.allocator, self.getOutputSource().getPath(builder), self.major_only_filename.?, self.name_only_filename.?); |
| 2705 | } | 2716 | } |
| 2706 | } | 2717 | } |
| 2707 | }; | 2718 | }; |
| ... | @@ -2768,17 +2779,17 @@ pub const InstallArtifactStep = struct { | ... | @@ -2768,17 +2779,17 @@ pub const InstallArtifactStep = struct { |
| 2768 | const builder = self.builder; | 2779 | const builder = self.builder; |
| 2769 | | 2780 | |
| 2770 | const full_dest_path = builder.getInstallPath(self.dest_dir, self.artifact.out_filename); | 2781 | const full_dest_path = builder.getInstallPath(self.dest_dir, self.artifact.out_filename); |
| 2771 | try builder.updateFile(self.artifact.getOutputPath(), full_dest_path); | 2782 | try builder.updateFile(self.artifact.getOutputSource().getPath(builder), full_dest_path); |
| 2772 | if (self.artifact.isDynamicLibrary() and self.artifact.version != null and self.artifact.target.wantSharedLibSymLinks()) { | 2783 | if (self.artifact.isDynamicLibrary() and self.artifact.version != null and self.artifact.target.wantSharedLibSymLinks()) { |
| 2773 | try doAtomicSymLinks(builder.allocator, full_dest_path, self.artifact.major_only_filename.?, self.artifact.name_only_filename.?); | 2784 | try doAtomicSymLinks(builder.allocator, full_dest_path, self.artifact.major_only_filename.?, self.artifact.name_only_filename.?); |
| 2774 | } | 2785 | } |
| 2775 | if (self.pdb_dir) |pdb_dir| { | 2786 | if (self.pdb_dir) |pdb_dir| { |
| 2776 | const full_pdb_path = builder.getInstallPath(pdb_dir, self.artifact.out_pdb_filename); | 2787 | const full_pdb_path = builder.getInstallPath(pdb_dir, self.artifact.out_pdb_filename); |
| 2777 | try builder.updateFile(self.artifact.getOutputPdbPath(), full_pdb_path); | 2788 | try builder.updateFile(self.artifact.getOutputPdbSource().getPath(builder), full_pdb_path); |
| 2778 | } | 2789 | } |
| 2779 | if (self.h_dir) |h_dir| { | 2790 | if (self.h_dir) |h_dir| { |
| 2780 | const full_pdb_path = builder.getInstallPath(h_dir, self.artifact.out_h_filename); | 2791 | const full_pdb_path = builder.getInstallPath(h_dir, self.artifact.out_h_filename); |
| 2781 | try builder.updateFile(self.artifact.getOutputHPath(), full_pdb_path); | 2792 | try builder.updateFile(self.artifact.getOutputHSource().getPath(builder), full_pdb_path); |
| 2782 | } | 2793 | } |
| 2783 | self.artifact.installed_path = full_dest_path; | 2794 | self.artifact.installed_path = full_dest_path; |
| 2784 | } | 2795 | } |