From 4e3fcbea84de17afdf391293dc143a1fcc7b2ef7 Mon Sep 17 00:00:00 2001 From: kcbanner Date: Wed, 25 Mar 2026 00:58:37 -0400 Subject: [PATCH] - Build: support installing the compiler_rt.dll This is an extension of the existing hack used for the x86_64 backend combined with the Coff linker --- lib/std/Build/Step/Compile.zig | 16 ++++++++++++++++ lib/std/Build/Step/InstallArtifact.zig | 18 ++++++++++++++++++ lib/std/zig.zig | 4 ++++ 3 files changed, 38 insertions(+) diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index f4177a9a23..a1987e5633 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -219,6 +219,8 @@ generated_docs: ?*GeneratedFile, generated_asm: ?*GeneratedFile, generated_bin: ?*GeneratedFile, generated_pdb: ?*GeneratedFile, +// hack for stage2_x86_64 + coff +generated_compiler_rt_dyn_lib: ?*GeneratedFile, generated_implib: ?*GeneratedFile, generated_llvm_bc: ?*GeneratedFile, generated_llvm_ir: ?*GeneratedFile, @@ -441,6 +443,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile { .generated_asm = null, .generated_bin = null, .generated_pdb = null, + .generated_compiler_rt_dyn_lib = null, .generated_implib = null, .generated_llvm_bc = null, .generated_llvm_ir = null, @@ -691,6 +694,11 @@ pub fn producesPdbFile(compile: *Compile) bool { return compile.isDynamicLibrary() or compile.kind == .exe or compile.kind == .@"test"; } +pub fn producesCompilerRtDynLib(compile: *Compile) bool { + if (compile.rootModuleTarget().ofmt != .coff) return false; + return compile.use_llvm == false; +} + pub fn producesImplib(compile: *Compile) bool { return compile.isDll(); } @@ -869,6 +877,12 @@ pub fn getEmittedPdb(compile: *Compile) LazyPath { return compile.getEmittedFileGeneric(&compile.generated_pdb); } +/// Returns the generated compiler_rt dynamic library. +/// This is a hack for stage2_x86_64 + coff. +pub fn getEmittedCompilerRtDynLib(compile: *Compile) ?LazyPath { + return compile.getEmittedFileGeneric(&compile.generated_compiler_rt_dyn_lib); +} + /// Returns the path to the generated documentation directory. pub fn getEmittedDocs(compile: *Compile) LazyPath { return compile.getEmittedFileGeneric(&compile.generated_docs); @@ -1794,6 +1808,8 @@ fn make(step: *Step, options: Step.MakeOptions) !void { // zig fmt: off if (compile.generated_bin) |lp| lp.path = compile.outputPath(output_dir, .bin); if (compile.generated_pdb) |lp| lp.path = compile.outputPath(output_dir, .pdb); + // hack for stage2_x86_64 + coff + if (compile.generated_compiler_rt_dyn_lib) |lp| lp.path = compile.outputPath(output_dir, .compiler_rt_dyn_lib); if (compile.generated_implib) |lp| lp.path = compile.outputPath(output_dir, .implib); if (compile.generated_h) |lp| lp.path = compile.outputPath(output_dir, .h); if (compile.generated_docs) |lp| lp.path = compile.outputPath(output_dir, .docs); diff --git a/lib/std/Build/Step/InstallArtifact.zig b/lib/std/Build/Step/InstallArtifact.zig index c3c9d6c853..aafd18f01c 100644 --- a/lib/std/Build/Step/InstallArtifact.zig +++ b/lib/std/Build/Step/InstallArtifact.zig @@ -17,6 +17,10 @@ emitted_implib: ?LazyPath, pdb_dir: ?InstallDir, emitted_pdb: ?LazyPath, +// hack for stage2_x86_64 + coff +compiler_rt_dyn_lib_dir: ?InstallDir, +emitted_compiler_rt_dyn_lib: ?LazyPath, + h_dir: ?InstallDir, emitted_h: ?LazyPath, @@ -35,6 +39,7 @@ pub const Options = struct { /// Which installation directory to put the main output file into. dest_dir: Dir = .default, pdb_dir: Dir = .default, + compiler_rt_dyn_lib_dir: Dir = .default, h_dir: Dir = .default, implib_dir: Dir = .default, @@ -75,6 +80,11 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins .default => if (artifact.producesPdbFile()) dest_dir else null, .override => |o| o, }, + .compiler_rt_dyn_lib_dir = switch (options.compiler_rt_dyn_lib_dir) { + .disabled => null, + .default => if (artifact.producesCompilerRtDynLib()) dest_dir else null, + .override => |o| o, + }, .h_dir = switch (options.h_dir) { .disabled => null, .default => if (artifact.kind == .lib) .header else null, @@ -98,6 +108,7 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins .emitted_bin = null, .emitted_pdb = null, + .emitted_compiler_rt_dyn_lib = null, .emitted_h = null, .emitted_implib = null, @@ -107,6 +118,7 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins install_artifact.step.dependOn(&artifact.step); if (install_artifact.dest_dir != null) install_artifact.emitted_bin = artifact.getEmittedBin(); + if (install_artifact.compiler_rt_dyn_lib_dir != null) install_artifact.emitted_compiler_rt_dyn_lib = artifact.getEmittedCompilerRtDynLib(); if (install_artifact.pdb_dir != null) install_artifact.emitted_pdb = artifact.getEmittedPdb(); // https://github.com/ziglang/zig/issues/9698 //if (install_artifact.h_dir != null) install_artifact.emitted_h = artifact.getEmittedH(); @@ -135,6 +147,12 @@ fn make(step: *Step, options: Step.MakeOptions) !void { install_artifact.artifact.installed_path = full_dest_path; } + if (install_artifact.compiler_rt_dyn_lib_dir) |compiler_rt_dir| { + const full_compiler_rt_path = b.getInstallPath(compiler_rt_dir, install_artifact.emitted_compiler_rt_dyn_lib.?.basename(b, step)); + const p = try step.installFile(install_artifact.emitted_compiler_rt_dyn_lib.?, full_compiler_rt_path); + all_cached = all_cached and p == .fresh; + } + if (install_artifact.implib_dir) |implib_dir| { const full_implib_path = b.getInstallPath(implib_dir, install_artifact.emitted_implib.?.basename(b, step)); const p = try step.installFile(install_artifact.emitted_implib.?, full_implib_path); diff --git a/lib/std/zig.zig b/lib/std/zig.zig index fdb945c7ce..997fe8a925 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -985,11 +985,14 @@ pub const EmitArtifact = enum { docs, pdb, h, + compiler_rt_dyn_lib, /// If using `Server` to communicate with the compiler, it will place requested artifacts in /// paths under the output directory, where those paths are named according to this function. /// Returned string is allocated with `gpa` and owned by the caller. pub fn cacheName(ea: EmitArtifact, gpa: Allocator, opts: BinNameOptions) Allocator.Error![]const u8 { + // hack for stage2_x86_64 + coff + if (ea == .compiler_rt_dyn_lib) return "compiler_rt.dll"; const suffix: []const u8 = switch (ea) { .bin => return binNameAlloc(gpa, opts), .@"asm" => ".s", @@ -999,6 +1002,7 @@ pub const EmitArtifact = enum { .docs => "-docs", .pdb => ".pdb", .h => ".h", + .compiler_rt_dyn_lib => unreachable, }; return std.fmt.allocPrint(gpa, "{s}{s}", .{ opts.root_name, suffix }); }