authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-06-05 01:14:03+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-06-05 01:14:03+02:00
log14873f9a3434a0d753ca8438f389a7931956cf26
tree48528df4b76310258f7f9ec9641920262ed775a5
parent80f2aeb8bee41707eb5be5a0dcf21ff2b8137919
parentc8b92f3a8ed740148c225608b6504fb8461249bc
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #24068 from alexrp/android-pic-pie

compiler: Rework PIE option logic.

4 files changed, 28 insertions(+), 11 deletions(-)

src/Compilation.zig+3
......@@ -6228,6 +6228,9 @@ pub fn addCCArgs(
62286228 }
62296229
62306230 if (target_util.supports_fpic(target)) {
6231 // PIE needs to go before PIC because Clang interprets `-fno-PIE` to imply `-fno-PIC`, which
6232 // we don't necessarily want.
6233 try argv.append(if (comp.config.pie) "-fPIE" else "-fno-PIE");
62316234 try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC");
62326235 }
62336236
src/Compilation/Config.zig+18-6
......@@ -135,6 +135,7 @@ pub const ResolveError = error{
135135 LibCppRequiresLibC,
136136 LibUnwindRequiresLibC,
137137 TargetCannotDynamicLink,
138 TargetCannotStaticLinkExecutables,
138139 LibCRequiresDynamicLinking,
139140 SharedLibrariesRequireDynamicLinking,
140141 ExportMemoryAndDynamicIncompatible,
......@@ -360,6 +361,10 @@ pub fn resolve(options: Options) ResolveError!Config {
360361 if (options.link_mode == .dynamic) return error.TargetCannotDynamicLink;
361362 break :b .static;
362363 }
364 if (target.os.tag == .fuchsia and options.output_mode == .Exe) {
365 if (options.link_mode == .static) return error.TargetCannotStaticLinkExecutables;
366 break :b .dynamic;
367 }
363368 if (explicitly_exe_or_dyn_lib and link_libc and
364369 (target_util.osRequiresLibC(target) or
365370 // For these libcs, Zig can only provide dynamic libc when cross-compiling.
......@@ -416,22 +421,29 @@ pub fn resolve(options: Options) ResolveError!Config {
416421
417422 const pie: bool = b: {
418423 switch (options.output_mode) {
419 .Obj, .Exe => {},
424 .Exe => if (target.os.tag == .fuchsia or
425 (target.abi.isAndroid() and link_mode == .dynamic))
426 {
427 if (options.pie == false) return error.TargetRequiresPie;
428 break :b true;
429 },
420430 .Lib => if (link_mode == .dynamic) {
421431 if (options.pie == true) return error.DynamicLibraryPrecludesPie;
422432 break :b false;
423433 },
424 }
425 if (target_util.requiresPIE(target)) {
426 if (options.pie == false) return error.TargetRequiresPie;
427 break :b true;
434 .Obj => {},
428435 }
429436 if (options.any_sanitize_thread) {
430437 if (options.pie == false) return error.SanitizeThreadRequiresPie;
431438 break :b true;
432439 }
433440 if (options.pie) |pie| break :b pie;
434 break :b false;
441 break :b if (options.output_mode == .Exe) switch (target.os.tag) {
442 .fuchsia,
443 .openbsd,
444 => true,
445 else => target.os.tag.isDarwin(),
446 } else false;
435447 };
436448
437449 const root_strip = b: {
src/main.zig+1
......@@ -4118,6 +4118,7 @@ fn createModule(
41184118 error.LibCppRequiresLibC => fatal("libc++ requires linking libc", .{}),
41194119 error.LibUnwindRequiresLibC => fatal("libunwind requires linking libc", .{}),
41204120 error.TargetCannotDynamicLink => fatal("dynamic linking unavailable on the specified target", .{}),
4121 error.TargetCannotStaticLinkExecutables => fatal("static linking of executables unavailable on the specified target", .{}),
41214122 error.LibCRequiresDynamicLinking => fatal("libc of the specified target requires dynamic linking", .{}),
41224123 error.SharedLibrariesRequireDynamicLinking => fatal("using shared libraries requires dynamic linking", .{}),
41234124 error.ExportMemoryAndDynamicIncompatible => fatal("exporting memory is incompatible with dynamic linking", .{}),
src/target.zig+6-5
......@@ -43,10 +43,6 @@ pub fn libCxxNeedsLibUnwind(target: std.Target) bool {
4343 };
4444}
4545
46pub fn requiresPIE(target: std.Target) bool {
47 return target.abi.isAndroid() or target.os.tag.isDarwin() or target.os.tag == .openbsd;
48}
49
5046/// This function returns whether non-pic code is completely invalid on the given target.
5147pub fn requiresPIC(target: std.Target, linking_libc: bool) bool {
5248 return target.abi.isAndroid() or
......@@ -64,7 +60,12 @@ pub fn picLevel(target: std.Target) u32 {
6460/// This is not whether the target supports Position Independent Code, but whether the -fPIC
6561/// C compiler argument is valid to Clang.
6662pub fn supports_fpic(target: std.Target) bool {
67 return target.os.tag != .windows and target.os.tag != .uefi;
63 return switch (target.os.tag) {
64 .windows,
65 .uefi,
66 => target.abi == .gnu or target.abi == .cygnus,
67 else => true,
68 };
6869}
6970
7071pub fn alwaysSingleThreaded(target: std.Target) bool {