Skip to content

Commit 14873f9

Browse files
authored
Merge pull request ziglang#24068 from alexrp/android-pic-pie
compiler: Rework PIE option logic.
2 parents 80f2aeb + c8b92f3 commit 14873f9

File tree

4 files changed

+28
-11
lines changed

4 files changed

+28
-11
lines changed

src/Compilation.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ pub fn libCxxNeedsLibUnwind(target: std.Target) bool {
4343
};
4444
}
4545

46-
pub 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.
5147
pub 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.
6662
pub 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

7071
pub fn alwaysSingleThreaded(target: std.Target) bool {

0 commit comments

Comments
 (0)