authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-06-09 18:38:39-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-06-19 18:41:12-04:00
loged37a1a33c2576c00697643463a4720728e04023
tree65ce43d8a48cbda27c0cdf68f072a4812608ace5
parente92b12906338207975ee73aa99db63cb9240bf04

coff: add hack to build a compiler-rt dynamic library

This is not meant to be a long-term solution, but it's the easiest thing to get working quickly at the moment. The main intention of this hack is to allow more tests to be enabled. By the time the coff linker is far enough along to be enabled by default, this will no longer be required.

3 files changed, 61 insertions(+), 6 deletions(-)

lib/compiler_rt/common.zig+3-3
......@@ -16,10 +16,10 @@ else
1616/// Determines the symbol's visibility to other objects.
1717/// For WebAssembly this allows the symbol to be resolved to other modules, but will not
1818/// export it to the host runtime.
19pub const visibility: std.builtin.SymbolVisibility = if (linkage != .internal)
20 .hidden
19pub const visibility: std.builtin.SymbolVisibility = if (linkage == .internal or builtin.link_mode == .dynamic)
20 .default
2121else
22 .default;
22 .hidden;
2323
2424pub const PreferredLoadStoreElement = element: {
2525 if (std.simd.suggestVectorLength(u8)) |vec_size| {
src/Compilation.zig+43-3
......@@ -224,6 +224,8 @@ compiler_rt_lib: ?CrtFile = null,
224224/// Populated when we build the compiler_rt_obj object. A Job to build this is indicated
225225/// by setting `queued_jobs.compiler_rt_obj` and resolved before calling linker.flush().
226226compiler_rt_obj: ?CrtFile = null,
227/// hack for stage2_x86_64 + coff
228compiler_rt_dyn_lib: ?CrtFile = null,
227229/// Populated when we build the libfuzzer static library. A Job to build this
228230/// is indicated by setting `queued_jobs.fuzzer_lib` and resolved before
229231/// calling linker.flush().
......@@ -291,6 +293,8 @@ emit_llvm_bc: ?[]const u8,
291293emit_docs: ?[]const u8,
292294
293295const QueuedJobs = struct {
296 /// hack for stage2_x86_64 + coff
297 compiler_rt_dyn_lib: bool = false,
294298 compiler_rt_lib: bool = false,
295299 compiler_rt_obj: bool = false,
296300 ubsan_rt_lib: bool = false,
......@@ -1753,7 +1757,7 @@ fn addModuleTableToCacheHash(
17531757 }
17541758}
17551759
1756const RtStrat = enum { none, lib, obj, zcu };
1760const RtStrat = enum { none, lib, obj, zcu, dyn_lib };
17571761
17581762pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compilation {
17591763 const output_mode = options.config.output_mode;
......@@ -1816,7 +1820,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
18161820 if (options.skip_linker_dependencies) break :s .none;
18171821 const want = options.want_compiler_rt orelse is_exe_or_dyn_lib;
18181822 if (!want) break :s .none;
1819 if (have_zcu and output_mode == .Obj) break :s .zcu;
1823 if (have_zcu) {
1824 if (output_mode == .Obj) break :s .zcu;
1825 if (target.ofmt == .coff and target_util.zigBackend(target, use_llvm) == .stage2_x86_64)
1826 break :s if (is_exe_or_dyn_lib) .dyn_lib else .zcu;
1827 }
18201828 if (is_exe_or_dyn_lib) break :s .lib;
18211829 break :s .obj;
18221830 };
......@@ -2441,6 +2449,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
24412449 // for a compiler-rt object to put in it.
24422450 comp.queued_jobs.compiler_rt_obj = true;
24432451 comp.link_task_queue.pending_prelink_tasks += 1;
2452 } else if (comp.compiler_rt_strat == .dyn_lib) {
2453 // hack for stage2_x86_64 + coff
2454 log.debug("queuing a job to build compiler_rt_dyn_lib", .{});
2455 comp.queued_jobs.compiler_rt_dyn_lib = true;
2456 comp.link_task_queue.pending_prelink_tasks += 1;
24442457 }
24452458
24462459 if (comp.ubsan_rt_strat == .lib) {
......@@ -4254,6 +4267,7 @@ fn performAllTheWork(
42544267 "compiler_rt.zig",
42554268 "compiler_rt",
42564269 .Lib,
4270 .static,
42574271 .compiler_rt,
42584272 main_progress_node,
42594273 RtOptions{
......@@ -4270,6 +4284,7 @@ fn performAllTheWork(
42704284 "compiler_rt.zig",
42714285 "compiler_rt",
42724286 .Obj,
4287 .static,
42734288 .compiler_rt,
42744289 main_progress_node,
42754290 RtOptions{
......@@ -4280,12 +4295,31 @@ fn performAllTheWork(
42804295 });
42814296 }
42824297
4298 // hack for stage2_x86_64 + coff
4299 if (comp.queued_jobs.compiler_rt_dyn_lib and comp.compiler_rt_dyn_lib == null) {
4300 comp.link_task_wait_group.spawnManager(buildRt, .{
4301 comp,
4302 "compiler_rt.zig",
4303 "compiler_rt",
4304 .Lib,
4305 .dynamic,
4306 .compiler_rt,
4307 main_progress_node,
4308 RtOptions{
4309 .checks_valgrind = true,
4310 .allow_lto = false,
4311 },
4312 &comp.compiler_rt_dyn_lib,
4313 });
4314 }
4315
42834316 if (comp.queued_jobs.fuzzer_lib and comp.fuzzer_lib == null) {
42844317 comp.link_task_wait_group.spawnManager(buildRt, .{
42854318 comp,
42864319 "fuzzer.zig",
42874320 "fuzzer",
42884321 .Lib,
4322 .static,
42894323 .libfuzzer,
42904324 main_progress_node,
42914325 RtOptions{},
......@@ -4299,6 +4333,7 @@ fn performAllTheWork(
42994333 "ubsan_rt.zig",
43004334 "ubsan_rt",
43014335 .Lib,
4336 .static,
43024337 .libubsan,
43034338 main_progress_node,
43044339 RtOptions{
......@@ -4314,6 +4349,7 @@ fn performAllTheWork(
43144349 "ubsan_rt.zig",
43154350 "ubsan_rt",
43164351 .Obj,
4352 .static,
43174353 .libubsan,
43184354 main_progress_node,
43194355 RtOptions{
......@@ -5390,6 +5426,7 @@ fn buildRt(
53905426 root_source_name: []const u8,
53915427 root_name: []const u8,
53925428 output_mode: std.builtin.OutputMode,
5429 link_mode: std.builtin.LinkMode,
53935430 misc_task: MiscTask,
53945431 prog_node: std.Progress.Node,
53955432 options: RtOptions,
......@@ -5399,6 +5436,7 @@ fn buildRt(
53995436 root_source_name,
54005437 root_name,
54015438 output_mode,
5439 link_mode,
54025440 misc_task,
54035441 prog_node,
54045442 options,
......@@ -5554,6 +5592,7 @@ fn buildLibZigC(comp: *Compilation, prog_node: std.Progress.Node) void {
55545592 "c.zig",
55555593 "zigc",
55565594 .Lib,
5595 .static,
55575596 .libzigc,
55585597 prog_node,
55595598 .{},
......@@ -7231,6 +7270,7 @@ fn buildOutputFromZig(
72317270 src_basename: []const u8,
72327271 root_name: []const u8,
72337272 output_mode: std.builtin.OutputMode,
7273 link_mode: std.builtin.LinkMode,
72347274 misc_task_tag: MiscTask,
72357275 prog_node: std.Progress.Node,
72367276 options: RtOptions,
......@@ -7251,7 +7291,7 @@ fn buildOutputFromZig(
72517291
72527292 const config = try Config.resolve(.{
72537293 .output_mode = output_mode,
7254 .link_mode = .static,
7294 .link_mode = link_mode,
72557295 .resolved_target = comp.root_mod.resolved_target,
72567296 .is_test = false,
72577297 .have_zcu = true,
src/link/Coff.zig+15
......@@ -1715,6 +1715,21 @@ fn flushInner(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id) !void {
17151715 }
17161716
17171717 assert(!coff.imports_count_dirty);
1718
1719 // hack for stage2_x86_64 + coff
1720 if (comp.compiler_rt_dyn_lib) |crt_file| {
1721 const compiler_rt_sub_path = try std.fs.path.join(gpa, &.{
1722 std.fs.path.dirname(coff.base.emit.sub_path) orelse "",
1723 std.fs.path.basename(crt_file.full_object_path.sub_path),
1724 });
1725 defer gpa.free(compiler_rt_sub_path);
1726 try crt_file.full_object_path.root_dir.handle.copyFile(
1727 crt_file.full_object_path.sub_path,
1728 coff.base.emit.root_dir.handle,
1729 compiler_rt_sub_path,
1730 .{},
1731 );
1732 }
17181733}
17191734
17201735pub fn getNavVAddr(