Commit 561e556aaf

Jacob Young <jacobly0@users.noreply.github.com>
2025-09-24 18:09:05
target: check for backend support for the new linker
Closes #25343
1 parent 9b3b7aa
Changed files (2)
src
src/Compilation/Config.zig
@@ -34,7 +34,6 @@ any_error_tracing: bool,
 any_sanitize_thread: bool,
 any_sanitize_c: std.zig.SanitizeC,
 any_fuzz: bool,
-pie: bool,
 /// If this is true then linker code is responsible for making an LLVM IR
 /// Module, outputting it to an object file, and then linking that together
 /// with link options and other objects. Otherwise (depending on `use_lld`)
@@ -48,8 +47,9 @@ use_lib_llvm: bool,
 /// and updates the final binary.
 use_lld: bool,
 c_frontend: CFrontend,
-lto: std.zig.LtoMode,
 use_new_linker: bool,
+pie: bool,
+lto: std.zig.LtoMode,
 incremental: bool,
 /// WASI-only. Type of WASI execution model ("command" or "reactor").
 /// Always set to `command` for non-WASI targets.
@@ -100,13 +100,13 @@ pub const Options = struct {
     link_libc: ?bool = null,
     link_libcpp: ?bool = null,
     link_libunwind: ?bool = null,
-    pie: ?bool = null,
     use_llvm: ?bool = null,
     use_lib_llvm: ?bool = null,
     use_lld: ?bool = null,
     use_clang: ?bool = null,
-    lto: ?std.zig.LtoMode = null,
     use_new_linker: ?bool = null,
+    pie: ?bool = null,
+    lto: ?std.zig.LtoMode = null,
     incremental: bool = false,
     /// WASI-only. Type of WASI execution model ("command" or "reactor").
     wasi_exec_model: ?std.builtin.WasiExecModel = null,
@@ -324,33 +324,6 @@ pub fn resolve(options: Options) ResolveError!Config {
         break :b !import_memory;
     };
 
-    const pie: bool = b: {
-        switch (options.output_mode) {
-            .Exe => if (target.os.tag == .fuchsia or
-                (target.abi.isAndroid() and link_mode == .dynamic))
-            {
-                if (options.pie == false) return error.TargetRequiresPie;
-                break :b true;
-            },
-            .Lib => if (link_mode == .dynamic) {
-                if (options.pie == true) return error.DynamicLibraryPrecludesPie;
-                break :b false;
-            },
-            .Obj => {},
-        }
-        if (options.any_sanitize_thread) {
-            if (options.pie == false) return error.SanitizeThreadRequiresPie;
-            break :b true;
-        }
-        if (options.pie) |pie| break :b pie;
-        break :b if (options.output_mode == .Exe) switch (target.os.tag) {
-            .fuchsia,
-            .openbsd,
-            => true,
-            else => target.os.tag.isDarwin(),
-        } else false;
-    };
-
     const is_dyn_lib = switch (options.output_mode) {
         .Obj, .Exe => false,
         .Lib => link_mode == .dynamic,
@@ -405,6 +378,7 @@ pub fn resolve(options: Options) ResolveError!Config {
         // we are confident in the robustness of the backend.
         break :b !target_util.selfHostedBackendIsAsRobustAsLlvm(target);
     };
+    const backend = target_util.zigBackend(target, use_llvm);
 
     if (options.emit_bin and options.have_zcu) {
         if (!use_lib_llvm and use_llvm) {
@@ -413,7 +387,7 @@ pub fn resolve(options: Options) ResolveError!Config {
             return error.EmittingBinaryRequiresLlvmLibrary;
         }
 
-        if (target_util.zigBackend(target, use_llvm) == .other) {
+        if (backend == .other) {
             // There is no compiler backend available for this target.
             return error.ZigLacksTargetSupport;
         }
@@ -451,26 +425,13 @@ pub fn resolve(options: Options) ResolveError!Config {
         break :b use_llvm;
     };
 
-    const lto: std.zig.LtoMode = b: {
-        if (!use_lld) {
-            // zig ld LTO support is tracked by
-            // https://github.com/ziglang/zig/issues/8680
-            if (options.lto != null and options.lto != .none) return error.LtoRequiresLld;
-            break :b .none;
-        }
-
-        if (options.lto) |x| break :b x;
-
-        break :b .none;
-    };
-
     const use_new_linker = b: {
         if (use_lld) {
             if (options.use_new_linker == true) return error.NewLinkerIncompatibleWithLld;
             break :b false;
         }
 
-        if (!target_util.hasNewLinkerSupport(target.ofmt)) {
+        if (!target_util.hasNewLinkerSupport(target.ofmt, backend)) {
             if (options.use_new_linker == true) return error.NewLinkerIncompatibleObjectFormat;
             break :b false;
         }
@@ -480,6 +441,46 @@ pub fn resolve(options: Options) ResolveError!Config {
         break :b options.incremental;
     };
 
+    const pie = b: {
+        switch (options.output_mode) {
+            .Exe => if (target.os.tag == .fuchsia or
+                (target.abi.isAndroid() and link_mode == .dynamic))
+            {
+                if (options.pie == false) return error.TargetRequiresPie;
+                break :b true;
+            },
+            .Lib => if (link_mode == .dynamic) {
+                if (options.pie == true) return error.DynamicLibraryPrecludesPie;
+                break :b false;
+            },
+            .Obj => {},
+        }
+        if (options.any_sanitize_thread) {
+            if (options.pie == false) return error.SanitizeThreadRequiresPie;
+            break :b true;
+        }
+        if (options.pie) |pie| break :b pie;
+        break :b if (options.output_mode == .Exe) switch (target.os.tag) {
+            .fuchsia,
+            .openbsd,
+            => true,
+            else => target.os.tag.isDarwin(),
+        } else false;
+    };
+
+    const lto: std.zig.LtoMode = b: {
+        if (!use_lld) {
+            // zig ld LTO support is tracked by
+            // https://github.com/ziglang/zig/issues/8680
+            if (options.lto != null and options.lto != .none) return error.LtoRequiresLld;
+            break :b .none;
+        }
+
+        if (options.lto) |x| break :b x;
+
+        break :b .none;
+    };
+
     const root_strip = b: {
         if (options.root_strip) |x| break :b x;
         if (root_optimize_mode == .ReleaseSmall) break :b true;
@@ -501,7 +502,6 @@ pub fn resolve(options: Options) ResolveError!Config {
         };
     };
 
-    const backend = target_util.zigBackend(target, use_llvm);
     const backend_supports_error_tracing = target_util.backendSupportsFeature(backend, .error_return_trace);
 
     const root_error_tracing = b: {
@@ -551,9 +551,9 @@ pub fn resolve(options: Options) ResolveError!Config {
         .any_fuzz = options.any_fuzz,
         .san_cov_trace_pc_guard = options.san_cov_trace_pc_guard,
         .root_error_tracing = root_error_tracing,
+        .use_new_linker = use_new_linker,
         .pie = pie,
         .lto = lto,
-        .use_new_linker = use_new_linker,
         .incremental = options.incremental,
         .import_memory = import_memory,
         .export_memory = export_memory,
src/target.zig
@@ -231,9 +231,12 @@ pub fn hasLldSupport(ofmt: std.Target.ObjectFormat) bool {
     };
 }
 
-pub fn hasNewLinkerSupport(ofmt: std.Target.ObjectFormat) bool {
+pub fn hasNewLinkerSupport(ofmt: std.Target.ObjectFormat, backend: std.builtin.CompilerBackend) bool {
     return switch (ofmt) {
-        .elf => true,
+        .elf => switch (backend) {
+            .stage2_x86_64 => true,
+            else => false,
+        },
         else => false,
     };
 }