authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-09-24 12:09:05-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-24 16:08:26-07:00
log561e556aaf1df2d655bc9fd6bc2df21a5981c3e0
tree33b146e44d268699d4f08add6c122795e8760efd
parent9b3b7aa911424c70b02987934a56000f06d79e9d

target: check for backend support for the new linker

Closes #25343

2 files changed, 53 insertions(+), 50 deletions(-)

src/Compilation/Config.zig+48-48
...@@ -34,7 +34,6 @@ any_error_tracing: bool,...@@ -34,7 +34,6 @@ any_error_tracing: bool,
34any_sanitize_thread: bool,34any_sanitize_thread: bool,
35any_sanitize_c: std.zig.SanitizeC,35any_sanitize_c: std.zig.SanitizeC,
36any_fuzz: bool,36any_fuzz: bool,
37pie: bool,
38/// If this is true then linker code is responsible for making an LLVM IR37/// If this is true then linker code is responsible for making an LLVM IR
39/// Module, outputting it to an object file, and then linking that together38/// Module, outputting it to an object file, and then linking that together
40/// with link options and other objects. Otherwise (depending on `use_lld`)39/// with link options and other objects. Otherwise (depending on `use_lld`)
...@@ -48,8 +47,9 @@ use_lib_llvm: bool,...@@ -48,8 +47,9 @@ use_lib_llvm: bool,
48/// and updates the final binary.47/// and updates the final binary.
49use_lld: bool,48use_lld: bool,
50c_frontend: CFrontend,49c_frontend: CFrontend,
51lto: std.zig.LtoMode,
52use_new_linker: bool,50use_new_linker: bool,
51pie: bool,
52lto: std.zig.LtoMode,
53incremental: bool,53incremental: bool,
54/// WASI-only. Type of WASI execution model ("command" or "reactor").54/// WASI-only. Type of WASI execution model ("command" or "reactor").
55/// Always set to `command` for non-WASI targets.55/// Always set to `command` for non-WASI targets.
...@@ -100,13 +100,13 @@ pub const Options = struct {...@@ -100,13 +100,13 @@ pub const Options = struct {
100 link_libc: ?bool = null,100 link_libc: ?bool = null,
101 link_libcpp: ?bool = null,101 link_libcpp: ?bool = null,
102 link_libunwind: ?bool = null,102 link_libunwind: ?bool = null,
103 pie: ?bool = null,
104 use_llvm: ?bool = null,103 use_llvm: ?bool = null,
105 use_lib_llvm: ?bool = null,104 use_lib_llvm: ?bool = null,
106 use_lld: ?bool = null,105 use_lld: ?bool = null,
107 use_clang: ?bool = null,106 use_clang: ?bool = null,
108 lto: ?std.zig.LtoMode = null,
109 use_new_linker: ?bool = null,107 use_new_linker: ?bool = null,
108 pie: ?bool = null,
109 lto: ?std.zig.LtoMode = null,
110 incremental: bool = false,110 incremental: bool = false,
111 /// WASI-only. Type of WASI execution model ("command" or "reactor").111 /// WASI-only. Type of WASI execution model ("command" or "reactor").
112 wasi_exec_model: ?std.builtin.WasiExecModel = null,112 wasi_exec_model: ?std.builtin.WasiExecModel = null,
...@@ -324,33 +324,6 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -324,33 +324,6 @@ pub fn resolve(options: Options) ResolveError!Config {
324 break :b !import_memory;324 break :b !import_memory;
325 };325 };
326326
327 const pie: bool = b: {
328 switch (options.output_mode) {
329 .Exe => if (target.os.tag == .fuchsia or
330 (target.abi.isAndroid() and link_mode == .dynamic))
331 {
332 if (options.pie == false) return error.TargetRequiresPie;
333 break :b true;
334 },
335 .Lib => if (link_mode == .dynamic) {
336 if (options.pie == true) return error.DynamicLibraryPrecludesPie;
337 break :b false;
338 },
339 .Obj => {},
340 }
341 if (options.any_sanitize_thread) {
342 if (options.pie == false) return error.SanitizeThreadRequiresPie;
343 break :b true;
344 }
345 if (options.pie) |pie| break :b pie;
346 break :b if (options.output_mode == .Exe) switch (target.os.tag) {
347 .fuchsia,
348 .openbsd,
349 => true,
350 else => target.os.tag.isDarwin(),
351 } else false;
352 };
353
354 const is_dyn_lib = switch (options.output_mode) {327 const is_dyn_lib = switch (options.output_mode) {
355 .Obj, .Exe => false,328 .Obj, .Exe => false,
356 .Lib => link_mode == .dynamic,329 .Lib => link_mode == .dynamic,
...@@ -405,6 +378,7 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -405,6 +378,7 @@ pub fn resolve(options: Options) ResolveError!Config {
405 // we are confident in the robustness of the backend.378 // we are confident in the robustness of the backend.
406 break :b !target_util.selfHostedBackendIsAsRobustAsLlvm(target);379 break :b !target_util.selfHostedBackendIsAsRobustAsLlvm(target);
407 };380 };
381 const backend = target_util.zigBackend(target, use_llvm);
408382
409 if (options.emit_bin and options.have_zcu) {383 if (options.emit_bin and options.have_zcu) {
410 if (!use_lib_llvm and use_llvm) {384 if (!use_lib_llvm and use_llvm) {
...@@ -413,7 +387,7 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -413,7 +387,7 @@ pub fn resolve(options: Options) ResolveError!Config {
413 return error.EmittingBinaryRequiresLlvmLibrary;387 return error.EmittingBinaryRequiresLlvmLibrary;
414 }388 }
415389
416 if (target_util.zigBackend(target, use_llvm) == .other) {390 if (backend == .other) {
417 // There is no compiler backend available for this target.391 // There is no compiler backend available for this target.
418 return error.ZigLacksTargetSupport;392 return error.ZigLacksTargetSupport;
419 }393 }
...@@ -451,26 +425,13 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -451,26 +425,13 @@ pub fn resolve(options: Options) ResolveError!Config {
451 break :b use_llvm;425 break :b use_llvm;
452 };426 };
453427
454 const lto: std.zig.LtoMode = b: {
455 if (!use_lld) {
456 // zig ld LTO support is tracked by
457 // https://github.com/ziglang/zig/issues/8680
458 if (options.lto != null and options.lto != .none) return error.LtoRequiresLld;
459 break :b .none;
460 }
461
462 if (options.lto) |x| break :b x;
463
464 break :b .none;
465 };
466
467 const use_new_linker = b: {428 const use_new_linker = b: {
468 if (use_lld) {429 if (use_lld) {
469 if (options.use_new_linker == true) return error.NewLinkerIncompatibleWithLld;430 if (options.use_new_linker == true) return error.NewLinkerIncompatibleWithLld;
470 break :b false;431 break :b false;
471 }432 }
472433
473 if (!target_util.hasNewLinkerSupport(target.ofmt)) {434 if (!target_util.hasNewLinkerSupport(target.ofmt, backend)) {
474 if (options.use_new_linker == true) return error.NewLinkerIncompatibleObjectFormat;435 if (options.use_new_linker == true) return error.NewLinkerIncompatibleObjectFormat;
475 break :b false;436 break :b false;
476 }437 }
...@@ -480,6 +441,46 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -480,6 +441,46 @@ pub fn resolve(options: Options) ResolveError!Config {
480 break :b options.incremental;441 break :b options.incremental;
481 };442 };
482443
444 const pie = b: {
445 switch (options.output_mode) {
446 .Exe => if (target.os.tag == .fuchsia or
447 (target.abi.isAndroid() and link_mode == .dynamic))
448 {
449 if (options.pie == false) return error.TargetRequiresPie;
450 break :b true;
451 },
452 .Lib => if (link_mode == .dynamic) {
453 if (options.pie == true) return error.DynamicLibraryPrecludesPie;
454 break :b false;
455 },
456 .Obj => {},
457 }
458 if (options.any_sanitize_thread) {
459 if (options.pie == false) return error.SanitizeThreadRequiresPie;
460 break :b true;
461 }
462 if (options.pie) |pie| break :b pie;
463 break :b if (options.output_mode == .Exe) switch (target.os.tag) {
464 .fuchsia,
465 .openbsd,
466 => true,
467 else => target.os.tag.isDarwin(),
468 } else false;
469 };
470
471 const lto: std.zig.LtoMode = b: {
472 if (!use_lld) {
473 // zig ld LTO support is tracked by
474 // https://github.com/ziglang/zig/issues/8680
475 if (options.lto != null and options.lto != .none) return error.LtoRequiresLld;
476 break :b .none;
477 }
478
479 if (options.lto) |x| break :b x;
480
481 break :b .none;
482 };
483
483 const root_strip = b: {484 const root_strip = b: {
484 if (options.root_strip) |x| break :b x;485 if (options.root_strip) |x| break :b x;
485 if (root_optimize_mode == .ReleaseSmall) break :b true;486 if (root_optimize_mode == .ReleaseSmall) break :b true;
...@@ -501,7 +502,6 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -501,7 +502,6 @@ pub fn resolve(options: Options) ResolveError!Config {
501 };502 };
502 };503 };
503504
504 const backend = target_util.zigBackend(target, use_llvm);
505 const backend_supports_error_tracing = target_util.backendSupportsFeature(backend, .error_return_trace);505 const backend_supports_error_tracing = target_util.backendSupportsFeature(backend, .error_return_trace);
506506
507 const root_error_tracing = b: {507 const root_error_tracing = b: {
...@@ -551,9 +551,9 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -551,9 +551,9 @@ pub fn resolve(options: Options) ResolveError!Config {
551 .any_fuzz = options.any_fuzz,551 .any_fuzz = options.any_fuzz,
552 .san_cov_trace_pc_guard = options.san_cov_trace_pc_guard,552 .san_cov_trace_pc_guard = options.san_cov_trace_pc_guard,
553 .root_error_tracing = root_error_tracing,553 .root_error_tracing = root_error_tracing,
554 .use_new_linker = use_new_linker,
554 .pie = pie,555 .pie = pie,
555 .lto = lto,556 .lto = lto,
556 .use_new_linker = use_new_linker,
557 .incremental = options.incremental,557 .incremental = options.incremental,
558 .import_memory = import_memory,558 .import_memory = import_memory,
559 .export_memory = export_memory,559 .export_memory = export_memory,
src/target.zig+5-2
...@@ -231,9 +231,12 @@ pub fn hasLldSupport(ofmt: std.Target.ObjectFormat) bool {...@@ -231,9 +231,12 @@ pub fn hasLldSupport(ofmt: std.Target.ObjectFormat) bool {
231 };231 };
232}232}
233233
234pub fn hasNewLinkerSupport(ofmt: std.Target.ObjectFormat) bool {234pub fn hasNewLinkerSupport(ofmt: std.Target.ObjectFormat, backend: std.builtin.CompilerBackend) bool {
235 return switch (ofmt) {235 return switch (ofmt) {
236 .elf => true,236 .elf => switch (backend) {
237 .stage2_x86_64 => true,
238 else => false,
239 },
237 else => false,240 else => false,
238 };241 };
239}242}