| author | |
| committer | |
| log | 5c0181841081170a118d8e50af2a09f5006f59e1 |
| tree | 085e2f6ce612c883aeb328611b510462ddcf55b6 |
| parent | ce95a3b153e9f3e83232e641c26a41e7dbd01165 |
22 files changed, 289 insertions(+), 163 deletions(-)
build.zig-5| ... | @@ -59,7 +59,6 @@ pub fn build(b: *std.Build) !void { | ... | @@ -59,7 +59,6 @@ pub fn build(b: *std.Build) !void { |
| 59 | .target = target, | 59 | .target = target, |
| 60 | }); | 60 | }); |
| 61 | autodoc_test.overrideZigLibDir(.{ .path = "lib" }); | 61 | autodoc_test.overrideZigLibDir(.{ .path = "lib" }); |
| 62 | autodoc_test.emit_bin = .no_emit; // https://github.com/ziglang/zig/issues/16351 | ||
| 63 | const install_std_docs = b.addInstallDirectory(.{ | 62 | const install_std_docs = b.addInstallDirectory(.{ |
| 64 | .source_dir = autodoc_test.getEmittedDocs(), | 63 | .source_dir = autodoc_test.getEmittedDocs(), |
| 65 | .install_dir = .prefix, | 64 | .install_dir = .prefix, |
| ... | @@ -196,10 +195,6 @@ pub fn build(b: *std.Build) !void { | ... | @@ -196,10 +195,6 @@ pub fn build(b: *std.Build) !void { |
| 196 | exe.pie = pie; | 195 | exe.pie = pie; |
| 197 | exe.sanitize_thread = sanitize_thread; | 196 | exe.sanitize_thread = sanitize_thread; |
| 198 | exe.entitlements = entitlements; | 197 | exe.entitlements = entitlements; |
| 199 | // TODO -femit-bin/-fno-emit-bin should be inferred by the build system | ||
| 200 | // based on whether or not the exe is run or installed. | ||
| 201 | // https://github.com/ziglang/zig/issues/16351 | ||
| 202 | if (no_bin) exe.emit_bin = .no_emit; | ||
| 203 | 198 | ||
| 204 | exe.build_id = b.option( | 199 | exe.build_id = b.option( |
| 205 | std.Build.Step.Compile.BuildId, | 200 | std.Build.Step.Compile.BuildId, |
lib/std/Build.zig+3-49| ... | @@ -19,6 +19,8 @@ const NativeTargetInfo = std.zig.system.NativeTargetInfo; | ... | @@ -19,6 +19,8 @@ const NativeTargetInfo = std.zig.system.NativeTargetInfo; |
| 19 | const Sha256 = std.crypto.hash.sha2.Sha256; | 19 | const Sha256 = std.crypto.hash.sha2.Sha256; |
| 20 | const Build = @This(); | 20 | const Build = @This(); |
| 21 | 21 | ||
| 22 | const build_util = @import("Build/util.zig"); | ||
| 23 | |||
| 22 | pub const Cache = @import("Build/Cache.zig"); | 24 | pub const Cache = @import("Build/Cache.zig"); |
| 23 | 25 | ||
| 24 | /// deprecated: use `Step.Compile`. | 26 | /// deprecated: use `Step.Compile`. |
| ... | @@ -1679,7 +1681,7 @@ pub const LazyPath = union(enum) { | ... | @@ -1679,7 +1681,7 @@ pub const LazyPath = union(enum) { |
| 1679 | .generated => |gen| return gen.path orelse { | 1681 | .generated => |gen| return gen.path orelse { |
| 1680 | std.debug.getStderrMutex().lock(); | 1682 | std.debug.getStderrMutex().lock(); |
| 1681 | const stderr = std.io.getStdErr(); | 1683 | const stderr = std.io.getStdErr(); |
| 1682 | dumpBadGetPathHelp(gen.step, stderr, src_builder, asking_step) catch {}; | 1684 | build_util.dumpBadGetPathHelp(gen.step, stderr, src_builder, asking_step) catch {}; |
| 1683 | @panic("misconfigured build script"); | 1685 | @panic("misconfigured build script"); |
| 1684 | }, | 1686 | }, |
| 1685 | } | 1687 | } |
| ... | @@ -1694,54 +1696,6 @@ pub const LazyPath = union(enum) { | ... | @@ -1694,54 +1696,6 @@ pub const LazyPath = union(enum) { |
| 1694 | } | 1696 | } |
| 1695 | }; | 1697 | }; |
| 1696 | 1698 | ||
| 1697 | /// In this function the stderr mutex has already been locked. | ||
| 1698 | fn dumpBadGetPathHelp( | ||
| 1699 | s: *Step, | ||
| 1700 | stderr: fs.File, | ||
| 1701 | src_builder: *Build, | ||
| 1702 | asking_step: ?*Step, | ||
| 1703 | ) anyerror!void { | ||
| 1704 | const w = stderr.writer(); | ||
| 1705 | try w.print( | ||
| 1706 | \\getPath() was called on a GeneratedFile that wasn't built yet. | ||
| 1707 | \\ source package path: {s} | ||
| 1708 | \\ Is there a missing Step dependency on step '{s}'? | ||
| 1709 | \\ | ||
| 1710 | , .{ | ||
| 1711 | src_builder.build_root.path orelse ".", | ||
| 1712 | s.name, | ||
| 1713 | }); | ||
| 1714 | |||
| 1715 | const tty_config = std.io.tty.detectConfig(stderr); | ||
| 1716 | tty_config.setColor(w, .red) catch {}; | ||
| 1717 | try stderr.writeAll(" The step was created by this stack trace:\n"); | ||
| 1718 | tty_config.setColor(w, .reset) catch {}; | ||
| 1719 | |||
| 1720 | const debug_info = std.debug.getSelfDebugInfo() catch |err| { | ||
| 1721 | try w.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}); | ||
| 1722 | return; | ||
| 1723 | }; | ||
| 1724 | const ally = debug_info.allocator; | ||
| 1725 | std.debug.writeStackTrace(s.getStackTrace(), w, ally, debug_info, tty_config) catch |err| { | ||
| 1726 | try stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)}); | ||
| 1727 | return; | ||
| 1728 | }; | ||
| 1729 | if (asking_step) |as| { | ||
| 1730 | tty_config.setColor(w, .red) catch {}; | ||
| 1731 | try stderr.writeAll(" The step that is missing a dependency on the above step was created by this stack trace:\n"); | ||
| 1732 | tty_config.setColor(w, .reset) catch {}; | ||
| 1733 | |||
| 1734 | std.debug.writeStackTrace(as.getStackTrace(), w, ally, debug_info, tty_config) catch |err| { | ||
| 1735 | try stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)}); | ||
| 1736 | return; | ||
| 1737 | }; | ||
| 1738 | } | ||
| 1739 | |||
| 1740 | tty_config.setColor(w, .red) catch {}; | ||
| 1741 | try stderr.writeAll(" Hope that helps. Proceeding to panic.\n"); | ||
| 1742 | tty_config.setColor(w, .reset) catch {}; | ||
| 1743 | } | ||
| 1744 | |||
| 1745 | /// Allocates a new string for assigning a value to a named macro. | 1699 | /// Allocates a new string for assigning a value to a named macro. |
| 1746 | /// If the value is omitted, it is set to 1. | 1700 | /// If the value is omitted, it is set to 1. |
| 1747 | /// `name` and `value` need not live longer than the function call. | 1701 | /// `name` and `value` need not live longer than the function call. |
lib/std/Build/Step.zig+4-1| ... | @@ -423,7 +423,10 @@ pub fn evalZigProcess( | ... | @@ -423,7 +423,10 @@ pub fn evalZigProcess( |
| 423 | }); | 423 | }); |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | if (s.cast(Compile)) |compile| if (compile.emit_bin == .no_emit) return result; | 426 | if (s.cast(Compile)) |compile| { |
| 427 | if (compile.generated_bin == null) // TODO(xq): How to handle this properly?! | ||
| 428 | return result; | ||
| 429 | } | ||
| 427 | 430 | ||
| 428 | return result orelse return s.fail( | 431 | return result orelse return s.fail( |
| 429 | "the following command failed to communicate the compilation result:\n{s}", | 432 | "the following command failed to communicate the compilation result:\n{s}", |
lib/std/Build/Step/Compile.zig+181-81| ... | @@ -21,6 +21,8 @@ const InstallDir = std.Build.InstallDir; | ... | @@ -21,6 +21,8 @@ const InstallDir = std.Build.InstallDir; |
| 21 | const GeneratedFile = std.Build.GeneratedFile; | 21 | const GeneratedFile = std.Build.GeneratedFile; |
| 22 | const Compile = @This(); | 22 | const Compile = @This(); |
| 23 | 23 | ||
| 24 | const build_util = @import("../util.zig"); | ||
| 25 | |||
| 24 | pub const base_id: Step.Id = .compile; | 26 | pub const base_id: Step.Id = .compile; |
| 25 | 27 | ||
| 26 | step: Step, | 28 | step: Step, |
| ... | @@ -46,14 +48,6 @@ framework_dirs: ArrayList(LazyPath), | ... | @@ -46,14 +48,6 @@ framework_dirs: ArrayList(LazyPath), |
| 46 | frameworks: StringHashMap(FrameworkLinkInfo), | 48 | frameworks: StringHashMap(FrameworkLinkInfo), |
| 47 | verbose_link: bool, | 49 | verbose_link: bool, |
| 48 | verbose_cc: bool, | 50 | verbose_cc: bool, |
| 49 | emit_asm: EmitOption = .default, | ||
| 50 | emit_bin: EmitOption = .default, | ||
| 51 | emit_implib: EmitOption = .default, | ||
| 52 | emit_llvm_bc: EmitOption = .default, | ||
| 53 | emit_llvm_ir: EmitOption = .default, | ||
| 54 | // Lots of things depend on emit_h having a consistent path, | ||
| 55 | // so it is not an EmitOption for now. | ||
| 56 | emit_h: bool = false, | ||
| 57 | bundle_compiler_rt: ?bool = null, | 51 | bundle_compiler_rt: ?bool = null, |
| 58 | single_threaded: ?bool, | 52 | single_threaded: ?bool, |
| 59 | stack_protector: ?bool = null, | 53 | stack_protector: ?bool = null, |
| ... | @@ -87,6 +81,9 @@ export_symbol_names: []const []const u8 = &.{}, | ... | @@ -87,6 +81,9 @@ export_symbol_names: []const []const u8 = &.{}, |
| 87 | 81 | ||
| 88 | root_src: ?LazyPath, | 82 | root_src: ?LazyPath, |
| 89 | out_h_filename: []const u8, | 83 | out_h_filename: []const u8, |
| 84 | out_ll_filename: []const u8, | ||
| 85 | out_bc_filename: []const u8, | ||
| 86 | out_asm_filename: []const u8, | ||
| 90 | out_lib_filename: []const u8, | 87 | out_lib_filename: []const u8, |
| 91 | out_pdb_filename: []const u8, | 88 | out_pdb_filename: []const u8, |
| 92 | modules: std.StringArrayHashMap(*Module), | 89 | modules: std.StringArrayHashMap(*Module), |
| ... | @@ -210,12 +207,16 @@ use_lld: ?bool, | ... | @@ -210,12 +207,16 @@ use_lld: ?bool, |
| 210 | /// otherwise. | 207 | /// otherwise. |
| 211 | expect_errors: []const []const u8 = &.{}, | 208 | expect_errors: []const []const u8 = &.{}, |
| 212 | 209 | ||
| 213 | output_path_source: GeneratedFile, | 210 | emit_directory: GeneratedFile, |
| 214 | output_lib_path_source: GeneratedFile, | 211 | |
| 215 | output_h_path_source: GeneratedFile, | ||
| 216 | output_pdb_path_source: GeneratedFile, | ||
| 217 | output_dirname_source: GeneratedFile, | ||
| 218 | generated_docs: ?*GeneratedFile, | 212 | generated_docs: ?*GeneratedFile, |
| 213 | generated_asm: ?*GeneratedFile, | ||
| 214 | generated_bin: ?*GeneratedFile, | ||
| 215 | generated_pdb: ?*GeneratedFile, | ||
| 216 | generated_implib: ?*GeneratedFile, | ||
| 217 | generated_llvm_bc: ?*GeneratedFile, | ||
| 218 | generated_llvm_ir: ?*GeneratedFile, | ||
| 219 | generated_h: ?*GeneratedFile, | ||
| 219 | 220 | ||
| 220 | pub const CSourceFiles = struct { | 221 | pub const CSourceFiles = struct { |
| 221 | files: []const []const u8, | 222 | files: []const []const u8, |
| ... | @@ -373,22 +374,6 @@ pub const Kind = enum { | ... | @@ -373,22 +374,6 @@ pub const Kind = enum { |
| 373 | 374 | ||
| 374 | pub const Linkage = enum { dynamic, static }; | 375 | pub const Linkage = enum { dynamic, static }; |
| 375 | 376 | ||
| 376 | pub const EmitOption = union(enum) { | ||
| 377 | default: void, | ||
| 378 | no_emit: void, | ||
| 379 | emit: void, | ||
| 380 | emit_to: []const u8, | ||
| 381 | |||
| 382 | fn getArg(self: @This(), b: *std.Build, arg_name: []const u8) ?[]const u8 { | ||
| 383 | return switch (self) { | ||
| 384 | .no_emit => b.fmt("-fno-{s}", .{arg_name}), | ||
| 385 | .default => null, | ||
| 386 | .emit => b.fmt("-f{s}", .{arg_name}), | ||
| 387 | .emit_to => |path| b.fmt("-f{s}={s}", .{ arg_name, path }), | ||
| 388 | }; | ||
| 389 | } | ||
| 390 | }; | ||
| 391 | |||
| 392 | pub fn create(owner: *std.Build, options: Options) *Compile { | 377 | pub fn create(owner: *std.Build, options: Options) *Compile { |
| 393 | const name = owner.dupe(options.name); | 378 | const name = owner.dupe(options.name); |
| 394 | const root_src: ?LazyPath = if (options.root_source_file) |rsrc| rsrc.dupe(owner) else null; | 379 | const root_src: ?LazyPath = if (options.root_source_file) |rsrc| rsrc.dupe(owner) else null; |
| ... | @@ -454,6 +439,9 @@ pub fn create(owner: *std.Build, options: Options) *Compile { | ... | @@ -454,6 +439,9 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 454 | .version = options.version, | 439 | .version = options.version, |
| 455 | .out_filename = out_filename, | 440 | .out_filename = out_filename, |
| 456 | .out_h_filename = owner.fmt("{s}.h", .{name}), | 441 | .out_h_filename = owner.fmt("{s}.h", .{name}), |
| 442 | .out_ll_filename = owner.fmt("{s}.bc", .{name}), | ||
| 443 | .out_bc_filename = owner.fmt("{s}.ll", .{name}), | ||
| 444 | .out_asm_filename = owner.fmt("{s}.s", .{name}), | ||
| 457 | .out_lib_filename = undefined, | 445 | .out_lib_filename = undefined, |
| 458 | .out_pdb_filename = owner.fmt("{s}.pdb", .{name}), | 446 | .out_pdb_filename = owner.fmt("{s}.pdb", .{name}), |
| 459 | .major_only_filename = null, | 447 | .major_only_filename = null, |
| ... | @@ -480,12 +468,16 @@ pub fn create(owner: *std.Build, options: Options) *Compile { | ... | @@ -480,12 +468,16 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 480 | .installed_path = null, | 468 | .installed_path = null, |
| 481 | .force_undefined_symbols = StringHashMap(void).init(owner.allocator), | 469 | .force_undefined_symbols = StringHashMap(void).init(owner.allocator), |
| 482 | 470 | ||
| 483 | .output_path_source = GeneratedFile{ .step = &self.step }, | 471 | .emit_directory = GeneratedFile{ .step = &self.step }, |
| 484 | .output_lib_path_source = GeneratedFile{ .step = &self.step }, | 472 | |
| 485 | .output_h_path_source = GeneratedFile{ .step = &self.step }, | ||
| 486 | .output_pdb_path_source = GeneratedFile{ .step = &self.step }, | ||
| 487 | .output_dirname_source = GeneratedFile{ .step = &self.step }, | ||
| 488 | .generated_docs = null, | 473 | .generated_docs = null, |
| 474 | .generated_asm = null, | ||
| 475 | .generated_bin = null, | ||
| 476 | .generated_pdb = null, | ||
| 477 | .generated_implib = null, | ||
| 478 | .generated_llvm_bc = null, | ||
| 479 | .generated_llvm_ir = null, | ||
| 480 | .generated_h = null, | ||
| 489 | 481 | ||
| 490 | .target_info = target_info, | 482 | .target_info = target_info, |
| 491 | 483 | ||
| ... | @@ -692,6 +684,7 @@ pub fn isStaticLibrary(self: *Compile) bool { | ... | @@ -692,6 +684,7 @@ pub fn isStaticLibrary(self: *Compile) bool { |
| 692 | } | 684 | } |
| 693 | 685 | ||
| 694 | pub fn producesPdbFile(self: *Compile) bool { | 686 | pub fn producesPdbFile(self: *Compile) bool { |
| 687 | // TODO: Is this right? Isn't PDB for *any* PE/COFF file? | ||
| 695 | if (!self.target.isWindows() and !self.target.isUefi()) return false; | 688 | if (!self.target.isWindows() and !self.target.isUefi()) return false; |
| 696 | if (self.target.getObjectFormat() == .c) return false; | 689 | if (self.target.getObjectFormat() == .c) return false; |
| 697 | if (self.strip == true or (self.strip == null and self.optimize == .ReleaseSmall)) return false; | 690 | if (self.strip == true or (self.strip == null and self.optimize == .ReleaseSmall)) return false; |
| ... | @@ -968,54 +961,75 @@ pub fn setLibCFile(self: *Compile, libc_file: ?LazyPath) void { | ... | @@ -968,54 +961,75 @@ pub fn setLibCFile(self: *Compile, libc_file: ?LazyPath) void { |
| 968 | self.libc_file = if (libc_file) |f| f.dupe(b) else null; | 961 | self.libc_file = if (libc_file) |f| f.dupe(b) else null; |
| 969 | } | 962 | } |
| 970 | 963 | ||
| 971 | pub const getOutputSource = getEmittedBin; // DEPRECATED, use getEmittedBin | 964 | fn getEmittedFileGeneric(self: *Compile, output_file: *?*GeneratedFile) LazyPath { |
| 972 | 965 | if (output_file.*) |g| { | |
| 973 | /// Returns the generated executable, library or object file. | 966 | return .{ .generated = g }; |
| 974 | /// To run an executable built with zig build, use `run`, or create an install step and invoke it. | 967 | } |
| 975 | pub fn getEmittedBin(self: *Compile) LazyPath { | 968 | const arena = self.step.owner.allocator; |
| 976 | return .{ .generated = &self.output_path_source }; | 969 | const generated_file = arena.create(GeneratedFile) catch @panic("OOM"); |
| 970 | generated_file.* = .{ .step = &self.step }; | ||
| 971 | output_file.* = generated_file; | ||
| 972 | return .{ .generated = generated_file }; | ||
| 977 | } | 973 | } |
| 978 | 974 | ||
| 979 | pub const getOutputDirectorySource = getEmitDirectory; // DEPRECATED, use getEmitDirectory | 975 | pub const getOutputDirectorySource = getEmitDirectory; // DEPRECATED, use getEmitDirectory |
| 980 | 976 | ||
| 977 | /// Returns the path to the output directory. | ||
| 981 | pub fn getEmitDirectory(self: *Compile) LazyPath { | 978 | pub fn getEmitDirectory(self: *Compile) LazyPath { |
| 982 | return .{ .generated = &self.output_dirname_source }; | 979 | return .{ .generated = &self.emit_directory }; |
| 980 | } | ||
| 981 | |||
| 982 | pub const getOutputSource = getEmittedBin; // DEPRECATED, use getEmittedBin | ||
| 983 | |||
| 984 | /// Returns the path to the generated executable, library or object file. | ||
| 985 | /// To run an executable built with zig build, use `run`, or create an install step and invoke it. | ||
| 986 | pub fn getEmittedBin(self: *Compile) LazyPath { | ||
| 987 | return self.getEmittedFileGeneric(&self.generated_bin); | ||
| 983 | } | 988 | } |
| 984 | 989 | ||
| 985 | pub const getOutputLibSource = getEmittedImplib; // DEPRECATED, use getEmittedImplib | 990 | pub const getOutputLibSource = getEmittedImplib; // DEPRECATED, use getEmittedImplib |
| 986 | 991 | ||
| 987 | /// Returns the generated import library. This function can only be called for libraries. | 992 | /// Returns the path to the generated import library. This function can only be called for libraries. |
| 988 | pub fn getEmittedImplib(self: *Compile) LazyPath { | 993 | pub fn getEmittedImplib(self: *Compile) LazyPath { |
| 989 | assert(self.kind == .lib); | 994 | assert(self.kind == .lib); |
| 990 | return .{ .generated = &self.output_lib_path_source }; | 995 | return self.getEmittedFileGeneric(&self.generated_implib); |
| 991 | } | 996 | } |
| 992 | 997 | ||
| 993 | pub const getOutputHSource = getEmittedH; // DEPRECATED, use getEmittedH | 998 | pub const getOutputHSource = getEmittedH; // DEPRECATED, use getEmittedH |
| 994 | 999 | ||
| 995 | /// Returns the generated header file. | 1000 | /// Returns the path to the generated header file. |
| 996 | /// This function can only be called for libraries or object files which have `emit_h` set. | 1001 | /// This function can only be called for libraries or objects. |
| 997 | pub fn getEmittedH(self: *Compile) LazyPath { | 1002 | pub fn getEmittedH(self: *Compile) LazyPath { |
| 998 | assert(self.kind != .exe and self.kind != .@"test"); | 1003 | assert(self.kind != .exe and self.kind != .@"test"); |
| 999 | assert(self.emit_h); | 1004 | return self.getEmittedFileGeneric(&self.generated_h); |
| 1000 | return .{ .generated = &self.output_h_path_source }; | ||
| 1001 | } | 1005 | } |
| 1002 | 1006 | ||
| 1003 | pub const getOutputPdbSource = getEmittedPdb; // DEPRECATED, use getEmittedPdb | 1007 | pub const getOutputPdbSource = getEmittedPdb; // DEPRECATED, use getEmittedPdb |
| 1004 | 1008 | ||
| 1005 | /// Returns the generated PDB file. This function can only be called for Windows and UEFI. | 1009 | /// Returns the generated PDB file. This function can only be called for Windows and UEFI. |
| 1006 | pub fn getEmittedPdb(self: *Compile) LazyPath { | 1010 | pub fn getEmittedPdb(self: *Compile) LazyPath { |
| 1007 | // TODO: Is this right? Isn't PDB for *any* PE/COFF file? | 1011 | assert(self.producesPdbFile()); |
| 1008 | assert(self.target.isWindows() or self.target.isUefi()); | 1012 | return self.getEmittedFileGeneric(&self.generated_pdb); |
| 1009 | return .{ .generated = &self.output_pdb_path_source }; | ||
| 1010 | } | 1013 | } |
| 1011 | 1014 | ||
| 1015 | /// Returns the path to the generated documentation directory. | ||
| 1012 | pub fn getEmittedDocs(self: *Compile) LazyPath { | 1016 | pub fn getEmittedDocs(self: *Compile) LazyPath { |
| 1013 | if (self.generated_docs) |g| return .{ .generated = g }; | 1017 | return self.getEmittedFileGeneric(&self.generated_docs); |
| 1014 | const arena = self.step.owner.allocator; | 1018 | } |
| 1015 | const generated_file = arena.create(GeneratedFile) catch @panic("OOM"); | 1019 | |
| 1016 | generated_file.* = .{ .step = &self.step }; | 1020 | /// Returns the path to the generated assembly code. |
| 1017 | self.generated_docs = generated_file; | 1021 | pub fn getEmittedAsm(self: *Compile) LazyPath { |
| 1018 | return .{ .generated = generated_file }; | 1022 | return self.getEmittedFileGeneric(&self.generated_asm); |
| 1023 | } | ||
| 1024 | |||
| 1025 | /// Returns the path to the generated LLVM IR. | ||
| 1026 | pub fn getEmittedLlvmIr(self: *Compile) LazyPath { | ||
| 1027 | return self.getEmittedFileGeneric(&self.generated_llvm_ir); | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | /// Returns the path to the generated LLVM BC. | ||
| 1031 | pub fn getEmittedLlvmBc(self: *Compile) LazyPath { | ||
| 1032 | return self.getEmittedFileGeneric(&self.generated_llvm_bc); | ||
| 1019 | } | 1033 | } |
| 1020 | 1034 | ||
| 1021 | pub fn addAssemblyFile(self: *Compile, source: LazyPath) void { | 1035 | pub fn addAssemblyFile(self: *Compile, source: LazyPath) void { |
| ... | @@ -1149,6 +1163,12 @@ pub fn setExecCmd(self: *Compile, args: []const ?[]const u8) void { | ... | @@ -1149,6 +1163,12 @@ pub fn setExecCmd(self: *Compile, args: []const ?[]const u8) void { |
| 1149 | } | 1163 | } |
| 1150 | 1164 | ||
| 1151 | fn linkLibraryOrObject(self: *Compile, other: *Compile) void { | 1165 | fn linkLibraryOrObject(self: *Compile, other: *Compile) void { |
| 1166 | _ = other.getEmittedBin(); // Force emission of the binary | ||
| 1167 | |||
| 1168 | if (other.kind == .lib and other.target.isWindows()) { // TODO(xq): Is this the correct logic here? | ||
| 1169 | _ = other.getEmittedImplib(); // Force emission of the binary | ||
| 1170 | } | ||
| 1171 | |||
| 1152 | self.step.dependOn(&other.step); | 1172 | self.step.dependOn(&other.step); |
| 1153 | self.link_objects.append(.{ .other_step = other }) catch @panic("OOM"); | 1173 | self.link_objects.append(.{ .other_step = other }) catch @panic("OOM"); |
| 1154 | self.include_dirs.append(.{ .other_step = other }) catch @panic("OOM"); | 1174 | self.include_dirs.append(.{ .other_step = other }) catch @panic("OOM"); |
| ... | @@ -1268,6 +1288,30 @@ fn constructDepString( | ... | @@ -1268,6 +1288,30 @@ fn constructDepString( |
| 1268 | } | 1288 | } |
| 1269 | } | 1289 | } |
| 1270 | 1290 | ||
| 1291 | fn getGeneratedFilePath(self: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) []const u8 { | ||
| 1292 | const maybe_path: ?*GeneratedFile = @field(self, tag_name); | ||
| 1293 | |||
| 1294 | const generated_file = maybe_path orelse { | ||
| 1295 | std.debug.getStderrMutex().lock(); | ||
| 1296 | const stderr = std.io.getStdErr(); | ||
| 1297 | |||
| 1298 | build_util.dumpBadGetPathHelp(&self.step, stderr, self.step.owner, asking_step) catch {}; | ||
| 1299 | |||
| 1300 | @panic("missing emit option for " ++ tag_name); | ||
| 1301 | }; | ||
| 1302 | |||
| 1303 | const path = generated_file.path orelse { | ||
| 1304 | std.debug.getStderrMutex().lock(); | ||
| 1305 | const stderr = std.io.getStdErr(); | ||
| 1306 | |||
| 1307 | build_util.dumpBadGetPathHelp(&self.step, stderr, self.step.owner, asking_step) catch {}; | ||
| 1308 | |||
| 1309 | @panic(tag_name ++ " is null. Is there a missing step dependency?"); | ||
| 1310 | }; | ||
| 1311 | |||
| 1312 | return path; | ||
| 1313 | } | ||
| 1314 | |||
| 1271 | fn make(step: *Step, prog_node: *std.Progress.Node) !void { | 1315 | fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1272 | const b = step.owner; | 1316 | const b = step.owner; |
| 1273 | const self = @fieldParentPtr(Compile, "step", step); | 1317 | const self = @fieldParentPtr(Compile, "step", step); |
| ... | @@ -1353,7 +1397,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -1353,7 +1397,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1353 | break :l; | 1397 | break :l; |
| 1354 | } | 1398 | } |
| 1355 | 1399 | ||
| 1356 | const full_path_lib = other.getEmittedImplib().getPath(b); | 1400 | // TODO(xq): Is that the right way? |
| 1401 | const full_path_lib = if (other.isDynamicLibrary() and other.target.isWindows()) | ||
| 1402 | other.getGeneratedFilePath("generated_implib", &self.step) | ||
| 1403 | else | ||
| 1404 | other.getGeneratedFilePath("generated_bin", &self.step); | ||
| 1357 | try zig_args.append(full_path_lib); | 1405 | try zig_args.append(full_path_lib); |
| 1358 | 1406 | ||
| 1359 | if (other.linkage == Linkage.dynamic and !self.target.isWindows()) { | 1407 | if (other.linkage == Linkage.dynamic and !self.target.isWindows()) { |
| ... | @@ -1496,14 +1544,36 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -1496,14 +1544,36 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1496 | if (b.verbose_cc or self.verbose_cc) try zig_args.append("--verbose-cc"); | 1544 | if (b.verbose_cc or self.verbose_cc) try zig_args.append("--verbose-cc"); |
| 1497 | if (b.verbose_llvm_cpu_features) try zig_args.append("--verbose-llvm-cpu-features"); | 1545 | if (b.verbose_llvm_cpu_features) try zig_args.append("--verbose-llvm-cpu-features"); |
| 1498 | 1546 | ||
| 1499 | if (self.emit_asm.getArg(b, "emit-asm")) |arg| try zig_args.append(arg); | 1547 | const Emitter = struct { |
| 1500 | if (self.emit_bin.getArg(b, "emit-bin")) |arg| try zig_args.append(arg); | 1548 | ptr: ?*GeneratedFile, |
| 1501 | if (self.generated_docs != null) try zig_args.append("-femit-docs"); | 1549 | emit_suffix: []const u8, |
| 1502 | if (self.emit_implib.getArg(b, "emit-implib")) |arg| try zig_args.append(arg); | 1550 | }; |
| 1503 | if (self.emit_llvm_bc.getArg(b, "emit-llvm-bc")) |arg| try zig_args.append(arg); | ||
| 1504 | if (self.emit_llvm_ir.getArg(b, "emit-llvm-ir")) |arg| try zig_args.append(arg); | ||
| 1505 | 1551 | ||
| 1506 | if (self.emit_h) try zig_args.append("-femit-h"); | 1552 | const generated_files = [_]Emitter{ |
| 1553 | .{ .ptr = self.generated_asm, .emit_suffix = "asm" }, | ||
| 1554 | .{ .ptr = self.generated_bin, .emit_suffix = "bin" }, | ||
| 1555 | .{ .ptr = self.generated_docs, .emit_suffix = "docs" }, | ||
| 1556 | .{ .ptr = self.generated_implib, .emit_suffix = "implib" }, | ||
| 1557 | .{ .ptr = self.generated_llvm_bc, .emit_suffix = "llvm-bc" }, | ||
| 1558 | .{ .ptr = self.generated_llvm_ir, .emit_suffix = "llvm-ir" }, | ||
| 1559 | .{ .ptr = self.generated_h, .emit_suffix = "h" }, | ||
| 1560 | }; | ||
| 1561 | var any_emitted_file = false; | ||
| 1562 | for (generated_files) |file| { | ||
| 1563 | try zig_args.append(if (file.ptr != null) | ||
| 1564 | b.fmt("-femit-{s}", .{file.emit_suffix}) | ||
| 1565 | else | ||
| 1566 | b.fmt("-fno-emit-{s}", .{file.emit_suffix})); | ||
| 1567 | |||
| 1568 | if (file.ptr != null) any_emitted_file = true; | ||
| 1569 | } | ||
| 1570 | |||
| 1571 | if (!any_emitted_file) { | ||
| 1572 | std.debug.getStderrMutex().lock(); | ||
| 1573 | const stderr = std.io.getStdErr(); | ||
| 1574 | build_util.dumpBadGetPathHelp(&self.step, stderr, self.step.owner, null) catch {}; | ||
| 1575 | std.debug.panic("Artifact '{s}' has no emit options set, but it is made. Did you forget to call `getEmitted*()`?.", .{self.name}); | ||
| 1576 | } | ||
| 1507 | 1577 | ||
| 1508 | try addFlag(&zig_args, "strip", self.strip); | 1578 | try addFlag(&zig_args, "strip", self.strip); |
| 1509 | try addFlag(&zig_args, "unwind-tables", self.unwind_tables); | 1579 | try addFlag(&zig_args, "unwind-tables", self.unwind_tables); |
| ... | @@ -1755,10 +1825,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -1755,10 +1825,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1755 | try zig_args.append(common_include_path); | 1825 | try zig_args.append(common_include_path); |
| 1756 | }, | 1826 | }, |
| 1757 | .other_step => |other| { | 1827 | .other_step => |other| { |
| 1758 | if (other.emit_h) { | 1828 | if (other.generated_h) |header| { |
| 1759 | const h_path = other.getEmittedH().getPath(b); | ||
| 1760 | try zig_args.append("-isystem"); | 1829 | try zig_args.append("-isystem"); |
| 1761 | try zig_args.append(fs.path.dirname(h_path).?); | 1830 | try zig_args.append(fs.path.dirname(header.path.?).?); |
| 1762 | } | 1831 | } |
| 1763 | if (other.installed_headers.items.len > 0) { | 1832 | if (other.installed_headers.items.len > 0) { |
| 1764 | try zig_args.append("-I"); | 1833 | try zig_args.append("-I"); |
| ... | @@ -1989,33 +2058,64 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -1989,33 +2058,64 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1989 | if (maybe_output_bin_path) |output_bin_path| { | 2058 | if (maybe_output_bin_path) |output_bin_path| { |
| 1990 | const output_dir = fs.path.dirname(output_bin_path).?; | 2059 | const output_dir = fs.path.dirname(output_bin_path).?; |
| 1991 | 2060 | ||
| 1992 | self.output_dirname_source.path = output_dir; | 2061 | self.emit_directory.path = output_dir; |
| 1993 | |||
| 1994 | self.output_path_source.path = b.pathJoin( | ||
| 1995 | &.{ output_dir, self.out_filename }, | ||
| 1996 | ); | ||
| 1997 | 2062 | ||
| 1998 | if (self.kind == .lib) { | 2063 | // -femit-bin[=path] (default) Output machine code |
| 1999 | self.output_lib_path_source.path = b.pathJoin( | 2064 | if (self.generated_bin) |bin| { |
| 2000 | &.{ output_dir, self.out_lib_filename }, | 2065 | bin.path = b.pathJoin( |
| 2066 | &.{ output_dir, self.out_filename }, | ||
| 2001 | ); | 2067 | ); |
| 2002 | } | 2068 | } |
| 2003 | 2069 | ||
| 2004 | if (self.emit_h) { | 2070 | // output PDB if someone requested it |
| 2005 | self.output_h_path_source.path = b.pathJoin( | 2071 | if (self.generated_pdb) |pdb| { |
| 2006 | &.{ output_dir, self.out_h_filename }, | 2072 | std.debug.assert(self.producesPdbFile()); |
| 2073 | pdb.path = b.pathJoin( | ||
| 2074 | &.{ output_dir, self.out_pdb_filename }, | ||
| 2007 | ); | 2075 | ); |
| 2008 | } | 2076 | } |
| 2009 | 2077 | ||
| 2010 | if (self.target.isWindows() or self.target.isUefi()) { | 2078 | // -femit-implib[=path] (default) Produce an import .lib when building a Windows DLL |
| 2011 | self.output_pdb_path_source.path = b.pathJoin( | 2079 | if (self.kind == .lib) { |
| 2012 | &.{ output_dir, self.out_pdb_filename }, | 2080 | if (self.generated_implib) |lib| { |
| 2081 | lib.path = b.pathJoin( | ||
| 2082 | &.{ output_dir, self.out_lib_filename }, | ||
| 2083 | ); | ||
| 2084 | } | ||
| 2085 | } | ||
| 2086 | |||
| 2087 | // -femit-h[=path] Generate a C header file (.h) | ||
| 2088 | if (self.generated_h) |lazy_path| { | ||
| 2089 | lazy_path.path = b.pathJoin( | ||
| 2090 | &.{ output_dir, self.out_h_filename }, | ||
| 2013 | ); | 2091 | ); |
| 2014 | } | 2092 | } |
| 2015 | 2093 | ||
| 2094 | // -femit-docs[=path] Create a docs/ dir with html documentation | ||
| 2016 | if (self.generated_docs) |generated_docs| { | 2095 | if (self.generated_docs) |generated_docs| { |
| 2017 | generated_docs.path = b.pathJoin(&.{ output_dir, "docs" }); | 2096 | generated_docs.path = b.pathJoin(&.{ output_dir, "docs" }); |
| 2018 | } | 2097 | } |
| 2098 | |||
| 2099 | // -femit-asm[=path] Output .s (assembly code) | ||
| 2100 | if (self.generated_asm) |lazy_path| { | ||
| 2101 | lazy_path.path = b.pathJoin( | ||
| 2102 | &.{ output_dir, self.out_asm_filename }, | ||
| 2103 | ); | ||
| 2104 | } | ||
| 2105 | |||
| 2106 | // -femit-llvm-ir[=path] Produce a .ll file with optimized LLVM IR (requires LLVM extensions) | ||
| 2107 | if (self.generated_llvm_ir) |lazy_path| { | ||
| 2108 | lazy_path.path = b.pathJoin( | ||
| 2109 | &.{ output_dir, self.out_ll_filename }, | ||
| 2110 | ); | ||
| 2111 | } | ||
| 2112 | |||
| 2113 | // -femit-llvm-bc[=path] Produce an optimized LLVM module as a .bc file (requires LLVM extensions) | ||
| 2114 | if (self.generated_llvm_bc) |lazy_path| { | ||
| 2115 | lazy_path.path = b.pathJoin( | ||
| 2116 | &.{ output_dir, self.out_bc_filename }, | ||
| 2117 | ); | ||
| 2118 | } | ||
| 2019 | } | 2119 | } |
| 2020 | 2120 | ||
| 2021 | if (self.kind == .lib and self.linkage != null and self.linkage.? == .dynamic and | 2121 | if (self.kind == .lib and self.linkage != null and self.linkage.? == .dynamic and |
lib/std/Build/Step/InstallArtifact.zig+9-7| ... | @@ -37,11 +37,12 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile) *InstallArtifact { | ... | @@ -37,11 +37,12 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile) *InstallArtifact { |
| 37 | break :blk InstallDir{ .lib = {} }; | 37 | break :blk InstallDir{ .lib = {} }; |
| 38 | } | 38 | } |
| 39 | } else null, | 39 | } else null, |
| 40 | .h_dir = if (artifact.kind == .lib and artifact.emit_h) .header else null, | 40 | .h_dir = if (artifact.kind == .lib and artifact.generated_h != null) .header else null, |
| 41 | .dest_sub_path = null, | 41 | .dest_sub_path = null, |
| 42 | }; | 42 | }; |
| 43 | self.step.dependOn(&artifact.step); | 43 | self.step.dependOn(&artifact.step); |
| 44 | 44 | ||
| 45 | _ = artifact.getEmittedBin(); // force creation | ||
| 45 | owner.pushInstalledFile(self.dest_dir, artifact.out_filename); | 46 | owner.pushInstalledFile(self.dest_dir, artifact.out_filename); |
| 46 | if (self.artifact.isDynamicLibrary()) { | 47 | if (self.artifact.isDynamicLibrary()) { |
| 47 | if (artifact.major_only_filename) |name| { | 48 | if (artifact.major_only_filename) |name| { |
| ... | @@ -55,9 +56,11 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile) *InstallArtifact { | ... | @@ -55,9 +56,11 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile) *InstallArtifact { |
| 55 | } | 56 | } |
| 56 | } | 57 | } |
| 57 | if (self.pdb_dir) |pdb_dir| { | 58 | if (self.pdb_dir) |pdb_dir| { |
| 59 | _ = artifact.getEmittedPdb(); // force creation | ||
| 58 | owner.pushInstalledFile(pdb_dir, artifact.out_pdb_filename); | 60 | owner.pushInstalledFile(pdb_dir, artifact.out_pdb_filename); |
| 59 | } | 61 | } |
| 60 | if (self.h_dir) |h_dir| { | 62 | if (self.h_dir) |h_dir| { |
| 63 | _ = artifact.getEmittedH(); // force creation | ||
| 61 | owner.pushInstalledFile(h_dir, artifact.out_h_filename); | 64 | owner.pushInstalledFile(h_dir, artifact.out_h_filename); |
| 62 | } | 65 | } |
| 63 | return self; | 66 | return self; |
| ... | @@ -66,7 +69,6 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile) *InstallArtifact { | ... | @@ -66,7 +69,6 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile) *InstallArtifact { |
| 66 | fn make(step: *Step, prog_node: *std.Progress.Node) !void { | 69 | fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 67 | _ = prog_node; | 70 | _ = prog_node; |
| 68 | const self = @fieldParentPtr(InstallArtifact, "step", step); | 71 | const self = @fieldParentPtr(InstallArtifact, "step", step); |
| 69 | const src_builder = self.artifact.step.owner; | ||
| 70 | const dest_builder = step.owner; | 72 | const dest_builder = step.owner; |
| 71 | 73 | ||
| 72 | const dest_sub_path = if (self.dest_sub_path) |sub_path| sub_path else self.artifact.out_filename; | 74 | const dest_sub_path = if (self.dest_sub_path) |sub_path| sub_path else self.artifact.out_filename; |
| ... | @@ -76,7 +78,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -76,7 +78,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 76 | var all_cached = true; | 78 | var all_cached = true; |
| 77 | 79 | ||
| 78 | { | 80 | { |
| 79 | const full_src_path = self.artifact.getEmittedBin().getPath(src_builder); | 81 | const full_src_path = self.artifact.generated_bin.?.path.?; |
| 80 | const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_dest_path, .{}) catch |err| { | 82 | const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_dest_path, .{}) catch |err| { |
| 81 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ | 83 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ |
| 82 | full_src_path, full_dest_path, @errorName(err), | 84 | full_src_path, full_dest_path, @errorName(err), |
| ... | @@ -93,9 +95,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -93,9 +95,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 93 | } | 95 | } |
| 94 | if (self.artifact.isDynamicLibrary() and | 96 | if (self.artifact.isDynamicLibrary() and |
| 95 | self.artifact.target.isWindows() and | 97 | self.artifact.target.isWindows() and |
| 96 | self.artifact.emit_implib != .no_emit) | 98 | self.artifact.generated_implib != null) |
| 97 | { | 99 | { |
| 98 | const full_src_path = self.artifact.getEmittedImplib().getPath(src_builder); | 100 | const full_src_path = self.artifact.generated_implib.?.path.?; |
| 99 | const full_implib_path = dest_builder.getInstallPath(self.dest_dir, self.artifact.out_lib_filename); | 101 | const full_implib_path = dest_builder.getInstallPath(self.dest_dir, self.artifact.out_lib_filename); |
| 100 | const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_implib_path, .{}) catch |err| { | 102 | const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_implib_path, .{}) catch |err| { |
| 101 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ | 103 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ |
| ... | @@ -105,7 +107,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -105,7 +107,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 105 | all_cached = all_cached and p == .fresh; | 107 | all_cached = all_cached and p == .fresh; |
| 106 | } | 108 | } |
| 107 | if (self.pdb_dir) |pdb_dir| { | 109 | if (self.pdb_dir) |pdb_dir| { |
| 108 | const full_src_path = self.artifact.getEmittedPdb().getPath(src_builder); | 110 | const full_src_path = self.artifact.generated_pdb.?.path.?; |
| 109 | const full_pdb_path = dest_builder.getInstallPath(pdb_dir, self.artifact.out_pdb_filename); | 111 | const full_pdb_path = dest_builder.getInstallPath(pdb_dir, self.artifact.out_pdb_filename); |
| 110 | const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_pdb_path, .{}) catch |err| { | 112 | const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_pdb_path, .{}) catch |err| { |
| 111 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ | 113 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ |
| ... | @@ -115,7 +117,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -115,7 +117,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 115 | all_cached = all_cached and p == .fresh; | 117 | all_cached = all_cached and p == .fresh; |
| 116 | } | 118 | } |
| 117 | if (self.h_dir) |h_dir| { | 119 | if (self.h_dir) |h_dir| { |
| 118 | const full_src_path = self.artifact.getEmittedH().getPath(src_builder); | 120 | const full_src_path = self.artifact.generated_h.?.path.?; |
| 119 | const full_h_path = dest_builder.getInstallPath(h_dir, self.artifact.out_h_filename); | 121 | const full_h_path = dest_builder.getInstallPath(h_dir, self.artifact.out_h_filename); |
| 120 | const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_h_path, .{}) catch |err| { | 122 | const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_h_path, .{}) catch |err| { |
| 121 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ | 123 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ |
lib/std/Build/Step/Run.zig+5-2| ... | @@ -164,6 +164,10 @@ pub fn enableTestRunnerMode(self: *Run) void { | ... | @@ -164,6 +164,10 @@ pub fn enableTestRunnerMode(self: *Run) void { |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | pub fn addArtifactArg(self: *Run, artifact: *Step.Compile) void { | 166 | pub fn addArtifactArg(self: *Run, artifact: *Step.Compile) void { |
| 167 | // enforce creation of the binary file by invoking getEmittedBin | ||
| 168 | const bin_file = artifact.getEmittedBin(); | ||
| 169 | bin_file.addStepDependencies(&self.step); | ||
| 170 | |||
| 167 | self.argv.append(Arg{ .artifact = artifact }) catch @panic("OOM"); | 171 | self.argv.append(Arg{ .artifact = artifact }) catch @panic("OOM"); |
| 168 | self.step.dependOn(&artifact.step); | 172 | self.step.dependOn(&artifact.step); |
| 169 | } | 173 | } |
| ... | @@ -456,8 +460,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { | ... | @@ -456,8 +460,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 456 | // On Windows we don't have rpaths so we have to add .dll search paths to PATH | 460 | // On Windows we don't have rpaths so we have to add .dll search paths to PATH |
| 457 | self.addPathForDynLibs(artifact); | 461 | self.addPathForDynLibs(artifact); |
| 458 | } | 462 | } |
| 459 | const file_path = artifact.installed_path orelse | 463 | const file_path = artifact.installed_path orelse artifact.generated_bin.?.path.?; // the path is guaranteed to be set |
| 460 | artifact.getEmittedBin().getPath(b); | ||
| 461 | 464 | ||
| 462 | try argv_list.append(file_path); | 465 | try argv_list.append(file_path); |
| 463 | 466 |
lib/std/Build/util.zig created+53| ... | @@ -0,0 +1,53 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const fs = std.fs; | ||
| 3 | |||
| 4 | const Build = std.Build; | ||
| 5 | const Step = std.Build.Step; | ||
| 6 | |||
| 7 | /// In this function the stderr mutex has already been locked. | ||
| 8 | pub fn dumpBadGetPathHelp( | ||
| 9 | s: *Step, | ||
| 10 | stderr: fs.File, | ||
| 11 | src_builder: *Build, | ||
| 12 | asking_step: ?*Step, | ||
| 13 | ) anyerror!void { | ||
| 14 | const w = stderr.writer(); | ||
| 15 | try w.print( | ||
| 16 | \\getPath() was called on a GeneratedFile that wasn't built yet. | ||
| 17 | \\ source package path: {s} | ||
| 18 | \\ Is there a missing Step dependency on step '{s}'? | ||
| 19 | \\ | ||
| 20 | , .{ | ||
| 21 | src_builder.build_root.path orelse ".", | ||
| 22 | s.name, | ||
| 23 | }); | ||
| 24 | |||
| 25 | const tty_config = std.io.tty.detectConfig(stderr); | ||
| 26 | tty_config.setColor(w, .red) catch {}; | ||
| 27 | try stderr.writeAll(" The step was created by this stack trace:\n"); | ||
| 28 | tty_config.setColor(w, .reset) catch {}; | ||
| 29 | |||
| 30 | const debug_info = std.debug.getSelfDebugInfo() catch |err| { | ||
| 31 | try w.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}); | ||
| 32 | return; | ||
| 33 | }; | ||
| 34 | const ally = debug_info.allocator; | ||
| 35 | std.debug.writeStackTrace(s.getStackTrace(), w, ally, debug_info, tty_config) catch |err| { | ||
| 36 | try stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)}); | ||
| 37 | return; | ||
| 38 | }; | ||
| 39 | if (asking_step) |as| { | ||
| 40 | tty_config.setColor(w, .red) catch {}; | ||
| 41 | try stderr.writeAll(" The step that is missing a dependency on the above step was created by this stack trace:\n"); | ||
| 42 | tty_config.setColor(w, .reset) catch {}; | ||
| 43 | |||
| 44 | std.debug.writeStackTrace(as.getStackTrace(), w, ally, debug_info, tty_config) catch |err| { | ||
| 45 | try stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)}); | ||
| 46 | return; | ||
| 47 | }; | ||
| 48 | } | ||
| 49 | |||
| 50 | tty_config.setColor(w, .red) catch {}; | ||
| 51 | try stderr.writeAll(" Hope that helps. Proceeding to panic.\n"); | ||
| 52 | tty_config.setColor(w, .reset) catch {}; | ||
| 53 | } | ||
test/link/glibc_compat/build.zig+1| ... | @@ -13,6 +13,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -13,6 +13,7 @@ pub fn build(b: *std.Build) void { |
| 13 | ) catch unreachable, | 13 | ) catch unreachable, |
| 14 | }); | 14 | }); |
| 15 | exe.linkLibC(); | 15 | exe.linkLibC(); |
| 16 | _ = exe.getEmittedBin(); // force emission | ||
| 16 | test_step.dependOn(&exe.step); | 17 | test_step.dependOn(&exe.step); |
| 17 | } | 18 | } |
| 18 | } | 19 | } |
test/link/macho/needed_library/build.zig+1| ... | @@ -23,6 +23,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize | ... | @@ -23,6 +23,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 23 | }); | 23 | }); |
| 24 | dylib.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &.{} }); | 24 | dylib.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &.{} }); |
| 25 | dylib.linkLibC(); | 25 | dylib.linkLibC(); |
| 26 | _ = dylib.getEmittedBin(); // enforce emission | ||
| 26 | 27 | ||
| 27 | // -dead_strip_dylibs | 28 | // -dead_strip_dylibs |
| 28 | // -needed-la | 29 | // -needed-la |
test/link/macho/search_strategy/build.zig+2| ... | @@ -60,6 +60,7 @@ fn createScenario( | ... | @@ -60,6 +60,7 @@ fn createScenario( |
| 60 | static.override_dest_dir = std.Build.InstallDir{ | 60 | static.override_dest_dir = std.Build.InstallDir{ |
| 61 | .custom = "static", | 61 | .custom = "static", |
| 62 | }; | 62 | }; |
| 63 | _ = static.getEmittedBin(); // enforce emission | ||
| 63 | 64 | ||
| 64 | const dylib = b.addSharedLibrary(.{ | 65 | const dylib = b.addSharedLibrary(.{ |
| 65 | .name = name, | 66 | .name = name, |
| ... | @@ -72,6 +73,7 @@ fn createScenario( | ... | @@ -72,6 +73,7 @@ fn createScenario( |
| 72 | dylib.override_dest_dir = std.Build.InstallDir{ | 73 | dylib.override_dest_dir = std.Build.InstallDir{ |
| 73 | .custom = "dynamic", | 74 | .custom = "dynamic", |
| 74 | }; | 75 | }; |
| 76 | _ = dylib.getEmittedBin(); // enforce emission | ||
| 75 | 77 | ||
| 76 | const exe = b.addExecutable(.{ | 78 | const exe = b.addExecutable(.{ |
| 77 | .name = name, | 79 | .name = name, |
test/src/Cases.zig+4-1| ... | @@ -551,7 +551,10 @@ pub fn lowerToBuildSteps( | ... | @@ -551,7 +551,10 @@ pub fn lowerToBuildSteps( |
| 551 | }), | 551 | }), |
| 552 | }; | 552 | }; |
| 553 | 553 | ||
| 554 | artifact.emit_bin = if (case.emit_bin) .default else .no_emit; | 554 | if (case.emit_bin) |
| 555 | _ = artifact.getEmittedBin(); | ||
| 556 | |||
| 557 | _ = artifact.getEmittedBin(); // TODO(xq): The test cases break if we set all to -fno-emit-X | ||
| 555 | 558 | ||
| 556 | if (case.link_libc) artifact.linkLibC(); | 559 | if (case.link_libc) artifact.linkLibC(); |
| 557 | 560 |
test/standalone.zig+8-10| ... | @@ -140,16 +140,14 @@ pub const build_cases = [_]BuildCase{ | ... | @@ -140,16 +140,14 @@ pub const build_cases = [_]BuildCase{ |
| 140 | .build_root = "test/standalone/install_raw_hex", | 140 | .build_root = "test/standalone/install_raw_hex", |
| 141 | .import = @import("standalone/install_raw_hex/build.zig"), | 141 | .import = @import("standalone/install_raw_hex/build.zig"), |
| 142 | }, | 142 | }, |
| 143 | // TODO take away EmitOption.emit_to option and make it give a FileSource | 143 | .{ |
| 144 | //.{ | 144 | .build_root = "test/standalone/emit_asm_and_bin", |
| 145 | // .build_root = "test/standalone/emit_asm_and_bin", | 145 | .import = @import("standalone/emit_asm_and_bin/build.zig"), |
| 146 | // .import = @import("standalone/emit_asm_and_bin/build.zig"), | 146 | }, |
| 147 | //}, | 147 | .{ |
| 148 | // TODO take away EmitOption.emit_to option and make it give a FileSource | 148 | .build_root = "test/standalone/issue_12588", |
| 149 | //.{ | 149 | .import = @import("standalone/issue_12588/build.zig"), |
| 150 | // .build_root = "test/standalone/issue_12588", | 150 | }, |
| 151 | // .import = @import("standalone/issue_12588/build.zig"), | ||
| 152 | //}, | ||
| 153 | .{ | 151 | .{ |
| 154 | .build_root = "test/standalone/child_process", | 152 | .build_root = "test/standalone/child_process", |
| 155 | .import = @import("standalone/child_process/build.zig"), | 153 | .import = @import("standalone/child_process/build.zig"), |
test/standalone/embed_generated_file/build.zig+2| ... | @@ -22,5 +22,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -22,5 +22,7 @@ pub fn build(b: *std.Build) void { |
| 22 | .source_file = bootloader.getEmittedBin(), | 22 | .source_file = bootloader.getEmittedBin(), |
| 23 | }); | 23 | }); |
| 24 | 24 | ||
| 25 | _ = exe.getEmittedBin(); // enforce emission | ||
| 26 | |||
| 25 | test_step.dependOn(&exe.step); | 27 | test_step.dependOn(&exe.step); |
| 26 | } | 28 | } |
test/standalone/emit_asm_and_bin/build.zig+2-2| ... | @@ -8,8 +8,8 @@ pub fn build(b: *std.Build) void { | ... | @@ -8,8 +8,8 @@ pub fn build(b: *std.Build) void { |
| 8 | .root_source_file = .{ .path = "main.zig" }, | 8 | .root_source_file = .{ .path = "main.zig" }, |
| 9 | .optimize = b.standardOptimizeOption(.{}), | 9 | .optimize = b.standardOptimizeOption(.{}), |
| 10 | }); | 10 | }); |
| 11 | main.emit_asm = .{ .emit_to = b.pathFromRoot("main.s") }; | 11 | _ = main.getEmittedBin(); // main.emit_asm = .{ .emit_to = b.pathFromRoot("main.s") }; |
| 12 | main.emit_bin = .{ .emit_to = b.pathFromRoot("main") }; | 12 | _ = main.getEmittedAsm(); // main.emit_bin = .{ .emit_to = b.pathFromRoot("main") }; |
| 13 | 13 | ||
| 14 | test_step.dependOn(&b.addRunArtifact(main).step); | 14 | test_step.dependOn(&b.addRunArtifact(main).step); |
| 15 | } | 15 | } |
test/standalone/issue_12588/build.zig+2-3| ... | @@ -13,9 +13,8 @@ pub fn build(b: *std.Build) void { | ... | @@ -13,9 +13,8 @@ pub fn build(b: *std.Build) void { |
| 13 | .optimize = optimize, | 13 | .optimize = optimize, |
| 14 | .target = target, | 14 | .target = target, |
| 15 | }); | 15 | }); |
| 16 | obj.emit_llvm_ir = .{ .emit_to = b.pathFromRoot("main.ll") }; | 16 | _ = obj.getEmittedLlvmIr(); |
| 17 | obj.emit_llvm_bc = .{ .emit_to = b.pathFromRoot("main.bc") }; | 17 | _ = obj.getEmittedLlvmBc(); |
| 18 | obj.emit_bin = .no_emit; | ||
| 19 | b.default_step.dependOn(&obj.step); | 18 | b.default_step.dependOn(&obj.step); |
| 20 | 19 | ||
| 21 | test_step.dependOn(&obj.step); | 20 | test_step.dependOn(&obj.step); |
test/standalone/issue_339/build.zig+2| ... | @@ -14,5 +14,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -14,5 +14,7 @@ pub fn build(b: *std.Build) void { |
| 14 | .optimize = optimize, | 14 | .optimize = optimize, |
| 15 | }); | 15 | }); |
| 16 | 16 | ||
| 17 | _ = obj.getEmittedBin(); // enforce emission | ||
| 18 | |||
| 17 | test_step.dependOn(&obj.step); | 19 | test_step.dependOn(&obj.step); |
| 18 | } | 20 | } |
test/standalone/issue_5825/build.zig+2| ... | @@ -27,5 +27,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -27,5 +27,7 @@ pub fn build(b: *std.Build) void { |
| 27 | exe.linkSystemLibrary("ntdll"); | 27 | exe.linkSystemLibrary("ntdll"); |
| 28 | exe.addObject(obj); | 28 | exe.addObject(obj); |
| 29 | 29 | ||
| 30 | _ = exe.getEmittedBin(); // enforce emission | ||
| 31 | |||
| 30 | test_step.dependOn(&exe.step); | 32 | test_step.dependOn(&exe.step); |
| 31 | } | 33 | } |
test/standalone/issue_794/build.zig+1| ... | @@ -8,6 +8,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -8,6 +8,7 @@ pub fn build(b: *std.Build) void { |
| 8 | .root_source_file = .{ .path = "main.zig" }, | 8 | .root_source_file = .{ .path = "main.zig" }, |
| 9 | }); | 9 | }); |
| 10 | test_artifact.addIncludePath(.{ .path = "a_directory" }); | 10 | test_artifact.addIncludePath(.{ .path = "a_directory" }); |
| 11 | _ = test_artifact.getEmittedBin(); // enforce emission | ||
| 11 | 12 | ||
| 12 | test_step.dependOn(&test_artifact.step); | 13 | test_step.dependOn(&test_artifact.step); |
| 13 | } | 14 | } |
test/standalone/main_pkg_path/build.zig+1-1| ... | @@ -7,7 +7,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -7,7 +7,7 @@ pub fn build(b: *std.Build) void { |
| 7 | const test_exe = b.addTest(.{ | 7 | const test_exe = b.addTest(.{ |
| 8 | .root_source_file = .{ .path = "a/test.zig" }, | 8 | .root_source_file = .{ .path = "a/test.zig" }, |
| 9 | }); | 9 | }); |
| 10 | test_exe.setMainPkgPath(.{.path="."}); | 10 | test_exe.setMainPkgPath(.{ .path = "." }); |
| 11 | 11 | ||
| 12 | test_step.dependOn(&b.addRunArtifact(test_exe).step); | 12 | test_step.dependOn(&b.addRunArtifact(test_exe).step); |
| 13 | } | 13 | } |
test/standalone/strip_empty_loop/build.zig+3| ... | @@ -14,5 +14,8 @@ pub fn build(b: *std.Build) void { | ... | @@ -14,5 +14,8 @@ pub fn build(b: *std.Build) void { |
| 14 | .target = target, | 14 | .target = target, |
| 15 | }); | 15 | }); |
| 16 | main.strip = true; | 16 | main.strip = true; |
| 17 | |||
| 18 | _ = main.getEmittedBin(); // enforce emission | ||
| 19 | |||
| 17 | test_step.dependOn(&main.step); | 20 | test_step.dependOn(&main.step); |
| 18 | } | 21 | } |
test/standalone/use_alias/build.zig+1-1| ... | @@ -10,7 +10,7 @@ pub fn build(b: *std.Build) void { | ... | @@ -10,7 +10,7 @@ pub fn build(b: *std.Build) void { |
| 10 | .root_source_file = .{ .path = "main.zig" }, | 10 | .root_source_file = .{ .path = "main.zig" }, |
| 11 | .optimize = optimize, | 11 | .optimize = optimize, |
| 12 | }); | 12 | }); |
| 13 | main.addIncludePath(.{.path="."}); | 13 | main.addIncludePath(.{ .path = "." }); |
| 14 | 14 | ||
| 15 | test_step.dependOn(&b.addRunArtifact(main).step); | 15 | test_step.dependOn(&b.addRunArtifact(main).step); |
| 16 | } | 16 | } |
test/tests.zig+2| ... | @@ -588,6 +588,8 @@ pub fn addStandaloneTests( | ... | @@ -588,6 +588,8 @@ pub fn addStandaloneTests( |
| 588 | }); | 588 | }); |
| 589 | if (case.link_libc) exe.linkLibC(); | 589 | if (case.link_libc) exe.linkLibC(); |
| 590 | 590 | ||
| 591 | _ = exe.getEmittedBin(); // Force emission | ||
| 592 | |||
| 591 | step.dependOn(&exe.step); | 593 | step.dependOn(&exe.step); |
| 592 | } | 594 | } |
| 593 | 595 |