diff --git a/src/Compilation/Config.zig b/src/Compilation/Config.zig index 45f7e509de..a4f8eefab7 100644 --- a/src/Compilation/Config.zig +++ b/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,6 +425,49 @@ pub fn resolve(options: Options) ResolveError!Config { break :b use_llvm; }; + 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, backend)) { + if (options.use_new_linker == true) return error.NewLinkerIncompatibleObjectFormat; + break :b false; + } + + if (options.use_new_linker) |x| break :b x; + + 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 @@ -464,22 +481,6 @@ pub fn resolve(options: Options) ResolveError!Config { 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 (options.use_new_linker == true) return error.NewLinkerIncompatibleObjectFormat; - break :b false; - } - - if (options.use_new_linker) |x| break :b x; - - break :b options.incremental; - }; - 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, diff --git a/src/target.zig b/src/target.zig index f67483d1e8..64506c991b 100644 --- a/src/target.zig +++ b/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, }; }