Commit fc28a71d9f

David Rubin <daviru007@icloud.com>
2025-01-06 22:05:36
Target: update the extra features before resolving the dynamic linker
1 parent 7aa95bc
Changed files (1)
lib
std
lib/std/zig/system.zig
@@ -345,7 +345,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
         os.version_range.linux.android = android;
     }
 
-    const cpu = switch (query.cpu_model) {
+    var cpu = switch (query.cpu_model) {
         .native => detectNativeCpuAndFeatures(query_cpu_arch, os, query),
         .baseline => Target.Cpu.baseline(query_cpu_arch, os),
         .determined_by_arch_os => if (query.cpu_arch == null)
@@ -357,55 +357,22 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
         break :backup_cpu_detection Target.Cpu.baseline(query_cpu_arch, os);
     };
 
-    var result = try detectAbiAndDynamicLinker(cpu, os, query);
-
-    // It's possible that we detect the native ABI, but fail to detect the OS version or were told
-    // to use the default OS version range. In that case, while we can't determine the exact native
-    // OS version, we do at least know that some ABIs require a particular OS version (by way of
-    // `std.zig.target.available_libcs`). So in this case, adjust the OS version to the minimum that
-    // we know is required.
-    if (result.abi != query_abi and query.os_version_min == null) {
-        const result_ver_range = &result.os.version_range;
-        const abi_ver_range = result.os.tag.defaultVersionRange(result.cpu.arch, result.abi).version_range;
-
-        switch (result.os.tag.versionRangeTag()) {
-            .none => {},
-            .semver => if (result_ver_range.semver.min.order(abi_ver_range.semver.min) == .lt) {
-                result_ver_range.semver.min = abi_ver_range.semver.min;
-            },
-            inline .hurd, .linux => |t| {
-                if (@field(result_ver_range, @tagName(t)).range.min.order(@field(abi_ver_range, @tagName(t)).range.min) == .lt) {
-                    @field(result_ver_range, @tagName(t)).range.min = @field(abi_ver_range, @tagName(t)).range.min;
-                }
-
-                if (@field(result_ver_range, @tagName(t)).glibc.order(@field(abi_ver_range, @tagName(t)).glibc) == .lt and
-                    query.glibc_version == null)
-                {
-                    @field(result_ver_range, @tagName(t)).glibc = @field(abi_ver_range, @tagName(t)).glibc;
-                }
-            },
-            .windows => if (!result_ver_range.windows.min.isAtLeast(abi_ver_range.windows.min)) {
-                result_ver_range.windows.min = abi_ver_range.windows.min;
-            },
-        }
-    }
-
     // For x86, we need to populate some CPU feature flags depending on architecture
     // and mode:
     //  * 16bit_mode => if the abi is code16
     //  * 32bit_mode => if the arch is x86
     // However, the "mode" flags can be used as overrides, so if the user explicitly
     // sets one of them, that takes precedence.
-    switch (result.cpu.arch) {
+    switch (query_cpu_arch) {
         .x86 => {
             if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{
                 .@"16bit_mode", .@"32bit_mode",
             })) {
-                switch (result.abi) {
-                    .code16 => result.cpu.features.addFeature(
+                switch (query_abi) {
+                    .code16 => cpu.features.addFeature(
                         @intFromEnum(Target.x86.Feature.@"16bit_mode"),
                     ),
-                    else => result.cpu.features.addFeature(
+                    else => cpu.features.addFeature(
                         @intFromEnum(Target.x86.Feature.@"32bit_mode"),
                     ),
                 }
@@ -416,32 +383,65 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
             //     What do we do if the user specifies +thumb_mode?
         },
         .thumb, .thumbeb => {
-            result.cpu.features.addFeature(
+            cpu.features.addFeature(
                 @intFromEnum(Target.arm.Feature.thumb_mode),
             );
         },
         else => {},
     }
     updateCpuFeatures(
-        &result.cpu.features,
-        result.cpu.arch.allFeaturesList(),
+        &cpu.features,
+        cpu.arch.allFeaturesList(),
         query.cpu_features_add,
         query.cpu_features_sub,
     );
 
-    if (result.cpu.arch == .hexagon) {
+    if (cpu.arch == .hexagon) {
         // Both LLVM and LLD have broken support for the small data area. Yet LLVM has the feature
         // on by default for all Hexagon CPUs. Clang sort of solves this by defaulting the `-gpsize`
         // command line parameter for the Hexagon backend to 0, so that no constants get placed in
         // the SDA. (This of course breaks down if the user passes `-G <n>` to Clang...) We can't do
         // the `-gpsize` hack because we can have multiple concurrent LLVM emit jobs, and command
         // line options in LLVM are shared globally. So just force this feature off. Lovely stuff.
-        result.cpu.features.removeFeature(@intFromEnum(Target.hexagon.Feature.small_data));
+        cpu.features.removeFeature(@intFromEnum(Target.hexagon.Feature.small_data));
     }
 
     // https://github.com/llvm/llvm-project/issues/105978
-    if (result.cpu.arch.isArm() and result.floatAbi() == .soft) {
-        result.cpu.features.removeFeature(@intFromEnum(Target.arm.Feature.vfp2));
+    if (cpu.arch.isArm() and query_abi.floatAbi() == .soft) {
+        cpu.features.removeFeature(@intFromEnum(Target.arm.Feature.vfp2));
+    }
+
+    var result = try detectAbiAndDynamicLinker(cpu, os, query);
+
+    // It's possible that we detect the native ABI, but fail to detect the OS version or were told
+    // to use the default OS version range. In that case, while we can't determine the exact native
+    // OS version, we do at least know that some ABIs require a particular OS version (by way of
+    // `std.zig.target.available_libcs`). So in this case, adjust the OS version to the minimum that
+    // we know is required.
+    if (result.abi != query_abi and query.os_version_min == null) {
+        const result_ver_range = &result.os.version_range;
+        const abi_ver_range = result.os.tag.defaultVersionRange(result.cpu.arch, result.abi).version_range;
+
+        switch (result.os.tag.versionRangeTag()) {
+            .none => {},
+            .semver => if (result_ver_range.semver.min.order(abi_ver_range.semver.min) == .lt) {
+                result_ver_range.semver.min = abi_ver_range.semver.min;
+            },
+            inline .hurd, .linux => |t| {
+                if (@field(result_ver_range, @tagName(t)).range.min.order(@field(abi_ver_range, @tagName(t)).range.min) == .lt) {
+                    @field(result_ver_range, @tagName(t)).range.min = @field(abi_ver_range, @tagName(t)).range.min;
+                }
+
+                if (@field(result_ver_range, @tagName(t)).glibc.order(@field(abi_ver_range, @tagName(t)).glibc) == .lt and
+                    query.glibc_version == null)
+                {
+                    @field(result_ver_range, @tagName(t)).glibc = @field(abi_ver_range, @tagName(t)).glibc;
+                }
+            },
+            .windows => if (!result_ver_range.windows.min.isAtLeast(abi_ver_range.windows.min)) {
+                result_ver_range.windows.min = abi_ver_range.windows.min;
+            },
+        }
     }
 
     return result;