| ... | @@ -181,8 +181,12 @@ pub const DetectError = error{ | ... | @@ -181,8 +181,12 @@ pub const DetectError = error{ |
| 181 | /// components by detecting the native system, and then resolves | 181 | /// components by detecting the native system, and then resolves |
| 182 | /// standard/default parts relative to that. | 182 | /// standard/default parts relative to that. |
| 183 | pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { | 183 | pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { |
| | 184 | // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the |
| | 185 | // native CPU architecture as being different than the current target), we use this: |
| | 186 | const query_cpu_arch = query.cpu_arch orelse builtin.cpu.arch; |
| 184 | const query_os_tag = query.os_tag orelse builtin.os.tag; | 187 | const query_os_tag = query.os_tag orelse builtin.os.tag; |
| 185 | var os = query_os_tag.defaultVersionRange(query.cpu_arch orelse builtin.cpu.arch); | 188 | const query_abi = query.abi orelse builtin.abi; |
| | 189 | var os = query_os_tag.defaultVersionRange(query_cpu_arch, query_abi); |
| 186 | if (query.os_tag == null) { | 190 | if (query.os_tag == null) { |
| 187 | switch (builtin.target.os.tag) { | 191 | switch (builtin.target.os.tag) { |
| 188 | .linux => { | 192 | .linux => { |
| ... | @@ -338,29 +342,58 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { | ... | @@ -338,29 +342,58 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { |
| 338 | os.version_range.linux.android = android; | 342 | os.version_range.linux.android = android; |
| 339 | } | 343 | } |
| 340 | | 344 | |
| 341 | // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the | | |
| 342 | // native CPU architecture as being different than the current target), we use this: | | |
| 343 | const cpu_arch = query.cpu_arch orelse builtin.cpu.arch; | | |
| 344 | | | |
| 345 | const cpu = switch (query.cpu_model) { | 345 | const cpu = switch (query.cpu_model) { |
| 346 | .native => detectNativeCpuAndFeatures(cpu_arch, os, query), | 346 | .native => detectNativeCpuAndFeatures(query_cpu_arch, os, query), |
| 347 | .baseline => Target.Cpu.baseline(cpu_arch, os), | 347 | .baseline => Target.Cpu.baseline(query_cpu_arch, os), |
| 348 | .determined_by_arch_os => if (query.cpu_arch == null) | 348 | .determined_by_arch_os => if (query.cpu_arch == null) |
| 349 | detectNativeCpuAndFeatures(cpu_arch, os, query) | 349 | detectNativeCpuAndFeatures(query_cpu_arch, os, query) |
| 350 | else | 350 | else |
| 351 | Target.Cpu.baseline(cpu_arch, os), | 351 | Target.Cpu.baseline(query_cpu_arch, os), |
| 352 | .explicit => |model| model.toCpu(cpu_arch), | 352 | .explicit => |model| model.toCpu(query_cpu_arch), |
| 353 | } orelse backup_cpu_detection: { | 353 | } orelse backup_cpu_detection: { |
| 354 | break :backup_cpu_detection Target.Cpu.baseline(cpu_arch, os); | 354 | break :backup_cpu_detection Target.Cpu.baseline(query_cpu_arch, os); |
| 355 | }; | 355 | }; |
| | 356 | |
| 356 | var result = try detectAbiAndDynamicLinker(cpu, os, query); | 357 | var result = try detectAbiAndDynamicLinker(cpu, os, query); |
| | 358 | |
| | 359 | // It's possible that we detect the native ABI, but fail to detect the OS version or were told |
| | 360 | // to use the default OS version range. In that case, while we can't determine the exact native |
| | 361 | // OS version, we do at least know that some ABIs require a particular OS version (by way of |
| | 362 | // `std.zig.target.available_libcs`). So in this case, adjust the OS version to the minimum that |
| | 363 | // we know is required. |
| | 364 | if (result.abi != query_abi and query.os_version_min == null) { |
| | 365 | const result_ver_range = &result.os.version_range; |
| | 366 | const abi_ver_range = result.os.tag.defaultVersionRange(result.cpu.arch, result.abi).version_range; |
| | 367 | |
| | 368 | switch (result.os.tag.versionRangeTag()) { |
| | 369 | .none => {}, |
| | 370 | .semver => if (result_ver_range.semver.min.order(abi_ver_range.semver.min) == .lt) { |
| | 371 | result_ver_range.semver.min = abi_ver_range.semver.min; |
| | 372 | }, |
| | 373 | inline .hurd, .linux => |t| { |
| | 374 | if (@field(result_ver_range, @tagName(t)).range.min.order(@field(abi_ver_range, @tagName(t)).range.min) == .lt) { |
| | 375 | @field(result_ver_range, @tagName(t)).range.min = @field(abi_ver_range, @tagName(t)).range.min; |
| | 376 | } |
| | 377 | |
| | 378 | if (@field(result_ver_range, @tagName(t)).glibc.order(@field(abi_ver_range, @tagName(t)).glibc) == .lt and |
| | 379 | query.glibc_version == null) |
| | 380 | { |
| | 381 | @field(result_ver_range, @tagName(t)).glibc = @field(abi_ver_range, @tagName(t)).glibc; |
| | 382 | } |
| | 383 | }, |
| | 384 | .windows => if (!result_ver_range.windows.min.isAtLeast(abi_ver_range.windows.min)) { |
| | 385 | result_ver_range.windows.min = abi_ver_range.windows.min; |
| | 386 | }, |
| | 387 | } |
| | 388 | } |
| | 389 | |
| 357 | // For x86, we need to populate some CPU feature flags depending on architecture | 390 | // For x86, we need to populate some CPU feature flags depending on architecture |
| 358 | // and mode: | 391 | // and mode: |
| 359 | // * 16bit_mode => if the abi is code16 | 392 | // * 16bit_mode => if the abi is code16 |
| 360 | // * 32bit_mode => if the arch is x86 | 393 | // * 32bit_mode => if the arch is x86 |
| 361 | // However, the "mode" flags can be used as overrides, so if the user explicitly | 394 | // However, the "mode" flags can be used as overrides, so if the user explicitly |
| 362 | // sets one of them, that takes precedence. | 395 | // sets one of them, that takes precedence. |
| 363 | switch (cpu_arch) { | 396 | switch (result.cpu.arch) { |
| 364 | .x86 => { | 397 | .x86 => { |
| 365 | if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{ | 398 | if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{ |
| 366 | .@"16bit_mode", .@"32bit_mode", | 399 | .@"16bit_mode", .@"32bit_mode", |
| ... | @@ -388,12 +421,12 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { | ... | @@ -388,12 +421,12 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { |
| 388 | } | 421 | } |
| 389 | updateCpuFeatures( | 422 | updateCpuFeatures( |
| 390 | &result.cpu.features, | 423 | &result.cpu.features, |
| 391 | cpu_arch.allFeaturesList(), | 424 | result.cpu.arch.allFeaturesList(), |
| 392 | query.cpu_features_add, | 425 | query.cpu_features_add, |
| 393 | query.cpu_features_sub, | 426 | query.cpu_features_sub, |
| 394 | ); | 427 | ); |
| 395 | | 428 | |
| 396 | if (cpu_arch == .hexagon) { | 429 | if (result.cpu.arch == .hexagon) { |
| 397 | // Both LLVM and LLD have broken support for the small data area. Yet LLVM has the feature | 430 | // Both LLVM and LLD have broken support for the small data area. Yet LLVM has the feature |
| 398 | // on by default for all Hexagon CPUs. Clang sort of solves this by defaulting the `-gpsize` | 431 | // on by default for all Hexagon CPUs. Clang sort of solves this by defaulting the `-gpsize` |
| 399 | // command line parameter for the Hexagon backend to 0, so that no constants get placed in | 432 | // command line parameter for the Hexagon backend to 0, so that no constants get placed in |