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,
3434any_sanitize_thread: bool,
3535any_sanitize_c: std.zig.SanitizeC,
3636any_fuzz: bool,
37pie: bool,
3837/// If this is true then linker code is responsible for making an LLVM IR
3938/// Module, outputting it to an object file, and then linking that together
4039/// with link options and other objects. Otherwise (depending on `use_lld`)
......@@ -48,8 +47,9 @@ use_lib_llvm: bool,
4847/// and updates the final binary.
4948use_lld: bool,
5049c_frontend: CFrontend,
51lto: std.zig.LtoMode,
5250use_new_linker: bool,
51pie: bool,
52lto: std.zig.LtoMode,
5353incremental: bool,
5454/// WASI-only. Type of WASI execution model ("command" or "reactor").
5555/// Always set to `command` for non-WASI targets.
......@@ -100,13 +100,13 @@ pub const Options = struct {
100100 link_libc: ?bool = null,
101101 link_libcpp: ?bool = null,
102102 link_libunwind: ?bool = null,
103 pie: ?bool = null,
104103 use_llvm: ?bool = null,
105104 use_lib_llvm: ?bool = null,
106105 use_lld: ?bool = null,
107106 use_clang: ?bool = null,
108 lto: ?std.zig.LtoMode = null,
109107 use_new_linker: ?bool = null,
108 pie: ?bool = null,
109 lto: ?std.zig.LtoMode = null,
110110 incremental: bool = false,
111111 /// WASI-only. Type of WASI execution model ("command" or "reactor").
112112 wasi_exec_model: ?std.builtin.WasiExecModel = null,
......@@ -324,33 +324,6 @@ pub fn resolve(options: Options) ResolveError!Config {
324324 break :b !import_memory;
325325 };
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
354327 const is_dyn_lib = switch (options.output_mode) {
355328 .Obj, .Exe => false,
356329 .Lib => link_mode == .dynamic,
......@@ -405,6 +378,7 @@ pub fn resolve(options: Options) ResolveError!Config {
405378 // we are confident in the robustness of the backend.
406379 break :b !target_util.selfHostedBackendIsAsRobustAsLlvm(target);
407380 };
381 const backend = target_util.zigBackend(target, use_llvm);
408382
409383 if (options.emit_bin and options.have_zcu) {
410384 if (!use_lib_llvm and use_llvm) {
......@@ -413,7 +387,7 @@ pub fn resolve(options: Options) ResolveError!Config {
413387 return error.EmittingBinaryRequiresLlvmLibrary;
414388 }
415389
416 if (target_util.zigBackend(target, use_llvm) == .other) {
390 if (backend == .other) {
417391 // There is no compiler backend available for this target.
418392 return error.ZigLacksTargetSupport;
419393 }
......@@ -451,26 +425,13 @@ pub fn resolve(options: Options) ResolveError!Config {
451425 break :b use_llvm;
452426 };
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
467428 const use_new_linker = b: {
468429 if (use_lld) {
469430 if (options.use_new_linker == true) return error.NewLinkerIncompatibleWithLld;
470431 break :b false;
471432 }
472433
473 if (!target_util.hasNewLinkerSupport(target.ofmt)) {
434 if (!target_util.hasNewLinkerSupport(target.ofmt, backend)) {
474435 if (options.use_new_linker == true) return error.NewLinkerIncompatibleObjectFormat;
475436 break :b false;
476437 }
......@@ -480,6 +441,46 @@ pub fn resolve(options: Options) ResolveError!Config {
480441 break :b options.incremental;
481442 };
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
483484 const root_strip = b: {
484485 if (options.root_strip) |x| break :b x;
485486 if (root_optimize_mode == .ReleaseSmall) break :b true;
......@@ -501,7 +502,6 @@ pub fn resolve(options: Options) ResolveError!Config {
501502 };
502503 };
503504
504 const backend = target_util.zigBackend(target, use_llvm);
505505 const backend_supports_error_tracing = target_util.backendSupportsFeature(backend, .error_return_trace);
506506
507507 const root_error_tracing = b: {
......@@ -551,9 +551,9 @@ pub fn resolve(options: Options) ResolveError!Config {
551551 .any_fuzz = options.any_fuzz,
552552 .san_cov_trace_pc_guard = options.san_cov_trace_pc_guard,
553553 .root_error_tracing = root_error_tracing,
554 .use_new_linker = use_new_linker,
554555 .pie = pie,
555556 .lto = lto,
556 .use_new_linker = use_new_linker,
557557 .incremental = options.incremental,
558558 .import_memory = import_memory,
559559 .export_memory = export_memory,
src/target.zig+5-2
......@@ -231,9 +231,12 @@ pub fn hasLldSupport(ofmt: std.Target.ObjectFormat) bool {
231231 };
232232}
233233
234pub fn hasNewLinkerSupport(ofmt: std.Target.ObjectFormat) bool {
234pub fn hasNewLinkerSupport(ofmt: std.Target.ObjectFormat, backend: std.builtin.CompilerBackend) bool {
235235 return switch (ofmt) {
236 .elf => true,
236 .elf => switch (backend) {
237 .stage2_x86_64 => true,
238 else => false,
239 },
237240 else => false,
238241 };
239242}