authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-01-24 02:09:41+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-01-24 02:09:41+01:00
log1b544f447ac373ad676ccf921a2e8f2d05def15f
tree38b4cf8f07e79b8d3f876e692618460af064e2a4
parent5c42193b177e4b56ca91acb256cad36dd7cd4dec
parente437efd6015cdc369a2ca632565d105e9f04f20f

Merge pull request 'enable `thumb-windows-gnu` module tests' (#30968) from alexrp/zig:windows-pic into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/30968

5 files changed, 78 insertions(+), 38 deletions(-)

src/Compilation/Config.zig+1-1
......@@ -255,7 +255,7 @@ pub fn resolve(options: Options) ResolveError!Config {
255255 .Exe => true,
256256 };
257257
258 if (target_util.cannotDynamicLink(target)) {
258 if (!target_util.canDynamicLink(target)) {
259259 if (options.link_mode == .dynamic) return error.TargetCannotDynamicLink;
260260 break :b .static;
261261 }
src/Package/Module.zig+1-1
......@@ -178,7 +178,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
178178 return error.PieRequiresPic;
179179 break :b true;
180180 }
181 if (options.global.link_mode == .dynamic) {
181 if (options.global.link_mode == .dynamic and target_util.requiresPicForDynamicLink(target)) {
182182 if (options.inherited.pic == false)
183183 return error.DynamicLinkingRequiresPic;
184184 break :b true;
src/Sema.zig+9-1
......@@ -9180,7 +9180,15 @@ pub fn handleExternLibName(
91809180 );
91819181 break :blk;
91829182 }
9183 if (!target.cpu.arch.isWasm() and !block.ownerModule().pic) {
9183 if (!target_util.canDynamicLink(target)) {
9184 return sema.fail(
9185 block,
9186 src_loc,
9187 "dependency on dynamic library '{s}' cannot be satisfied because target does not support dynamic linking",
9188 .{lib_name},
9189 );
9190 }
9191 if (!block.ownerModule().pic and target_util.requiresPicForDynamicLink(target)) {
91849192 return sema.fail(
91859193 block,
91869194 src_loc,
src/target.zig+29-8
......@@ -10,10 +10,24 @@ const Feature = @import("Zcu.zig").Feature;
1010
1111pub const default_stack_protector_buffer_size = 4;
1212
13pub fn cannotDynamicLink(target: *const std.Target) bool {
14 return switch (target.os.tag) {
15 .freestanding => true,
16 else => target.cpu.arch.isSpirV(),
13pub fn canDynamicLink(target: *const std.Target) bool {
14 return switch (target.cpu.arch) {
15 .amdgcn,
16 .bpfeb,
17 .bpfel,
18 .nvptx,
19 .nvptx64,
20 .spirv32,
21 .spirv64,
22 => false,
23 .wasm32,
24 .wasm64,
25 => true,
26 else => switch (target.os.tag) {
27 // This list is likely incomplete.
28 .freestanding, .uefi => false,
29 else => true,
30 },
1731 };
1832}
1933
......@@ -41,11 +55,20 @@ pub fn libCxxNeedsLibUnwind(target: *const std.Target) bool {
4155/// This function returns whether non-pic code is completely invalid on the given target.
4256pub fn requiresPIC(target: *const std.Target, linking_libc: bool) bool {
4357 return target.abi.isAndroid() or
44 target.os.tag == .windows or target.os.tag == .uefi or
58 ((target.os.tag == .windows or target.os.tag == .uefi) and (target.cpu.arch == .aarch64 or target.cpu.arch == .x86_64)) or
4559 target.requiresLibC() or
4660 (linking_libc and target.isGnuLibC());
4761}
4862
63pub fn requiresPicForDynamicLink(target: *const std.Target) bool {
64 assert(canDynamicLink(target));
65
66 return switch (target.os.tag) {
67 .windows => target.cpu.arch == .aarch64 or target.cpu.arch == .x86_64,
68 else => !target.cpu.arch.isWasm(),
69 };
70}
71
4972pub fn picLevel(target: *const std.Target) u32 {
5073 // MIPS always uses PIC level 1; other platforms vary in their default PIC levels, but they
5174 // support both level 1 and 2, in which case we prefer 2.
......@@ -56,9 +79,7 @@ pub fn picLevel(target: *const std.Target) u32 {
5679/// C compiler argument is valid to Clang.
5780pub fn supports_fpic(target: *const std.Target) bool {
5881 return switch (target.os.tag) {
59 .windows,
60 .uefi,
61 => target.abi == .gnu,
82 .windows, .uefi => false, // Technically allowed for `Abi.gnu`, but completely ignored by Clang (by design) anyway.
6283 else => true,
6384 };
6485}
test/tests.zig+38-27
......@@ -28,6 +28,8 @@ const TestTarget = struct {
2828 use_lld: ?bool = null,
2929 pic: ?bool = null,
3030 strip: ?bool = null,
31 function_sections: ?bool = null,
32 data_sections: ?bool = null,
3133 skip_modules: []const []const u8 = &.{},
3234
3335 // This is intended for targets that, for any reason, shouldn't be run as part of a normal test
......@@ -40,7 +42,7 @@ const test_targets = blk: {
4042 // getBaselineCpuFeatures calls populateDependencies which has a O(N ^ 2) algorithm
4143 // (where N is roughly 160, which technically makes it O(1), but it adds up to a
4244 // lot of branches)
43 @setEvalBranchQuota(60000);
45 @setEvalBranchQuota(80_000);
4446 break :blk [_]TestTarget{
4547 // Native Targets
4648
......@@ -1526,36 +1528,43 @@ const test_targets = blk: {
15261528 },
15271529
15281530 .{
1529 .target = .{
1530 .cpu_arch = .thumb,
1531 .os_tag = .windows,
1532 .abi = .msvc,
1533 },
1531 .target = std.Target.Query.parse(.{
1532 .arch_os_abi = "thumb-windows-msvc",
1533 .cpu_features = "baseline+long_calls",
1534 }) catch unreachable,
1535 .pic = false, // Long calls don't work with PIC.
1536 .function_sections = true,
1537 .data_sections = true,
15341538 },
15351539 .{
1536 .target = .{
1537 .cpu_arch = .thumb,
1538 .os_tag = .windows,
1539 .abi = .msvc,
1540 },
1540 .target = std.Target.Query.parse(.{
1541 .arch_os_abi = "thumb-windows-msvc",
1542 .cpu_features = "baseline+long_calls",
1543 }) catch unreachable,
15411544 .link_libc = true,
1545 .pic = false, // Long calls don't work with PIC.
1546 .function_sections = true,
1547 .data_sections = true,
1548 },
1549 .{
1550 .target = std.Target.Query.parse(.{
1551 .arch_os_abi = "thumb-windows-gnu",
1552 .cpu_features = "baseline+long_calls",
1553 }) catch unreachable,
1554 .pic = false, // Long calls don't work with PIC.
1555 .function_sections = true,
1556 .data_sections = true,
1557 },
1558 .{
1559 .target = std.Target.Query.parse(.{
1560 .arch_os_abi = "thumb-windows-gnu",
1561 .cpu_features = "baseline+long_calls",
1562 }) catch unreachable,
1563 .link_libc = true,
1564 .pic = false, // Long calls don't work with PIC.
1565 .function_sections = true,
1566 .data_sections = true,
15421567 },
1543 // https://github.com/ziglang/zig/issues/24016
1544 // .{
1545 // .target = .{
1546 // .cpu_arch = .thumb,
1547 // .os_tag = .windows,
1548 // .abi = .gnu,
1549 // },
1550 // },
1551 // .{
1552 // .target = .{
1553 // .cpu_arch = .thumb,
1554 // .os_tag = .windows,
1555 // .abi = .gnu,
1556 // },
1557 // .link_libc = true,
1558 // },
15591568
15601569 .{
15611570 .target = .{
......@@ -2454,6 +2463,8 @@ fn addOneModuleTest(
24542463 if (options.build_options) |build_options| {
24552464 these_tests.root_module.addOptions("build_options", build_options);
24562465 }
2466 if (test_target.function_sections) |fs| these_tests.link_function_sections = fs;
2467 if (test_target.data_sections) |ds| these_tests.link_data_sections = ds;
24572468 const single_threaded_suffix = if (test_target.single_threaded == true) "-single" else "";
24582469 const backend_suffix = if (test_target.use_llvm == true)
24592470 "-llvm"