aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-06-27 09:24:18 +0200
committerJakub Konka <kubkon@jakubkonka.com>2022-06-27 19:53:38 +0200
commitefc5c97bff87d4c28ae9642fe69d9bc2c7e9eeb7 (patch)
tree12b31bae7ed111c1f62541c7d46f20ad6d222717 /src
parenta76775b50a65fd0ea0fd17d6ef3c42058df13997 (diff)
downloadzig-efc5c97bff87d4c28ae9642fe69d9bc2c7e9eeb7.tar.gz
zig-efc5c97bff87d4c28ae9642fe69d9bc2c7e9eeb7.zip
macho: implement -dead_strip_dylibs linker flag
Diffstat (limited to 'src')
-rw-r--r--src/Compilation.zig8
-rw-r--r--src/link.zig3
-rw-r--r--src/link/Coff.zig2
-rw-r--r--src/link/Elf.zig2
-rw-r--r--src/link/MachO.zig14
-rw-r--r--src/link/Wasm.zig2
-rw-r--r--src/main.zig7
7 files changed, 31 insertions, 7 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 652938d741..fffa777f22 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -911,6 +911,8 @@ pub const InitOptions = struct {
headerpad_size: ?u32 = null,
/// (Darwin) set enough space as if all paths were MATPATHLEN
headerpad_max_install_names: bool = false,
+ /// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols
+ dead_strip_dylibs: bool = false,
};
fn addPackageTableToCacheHash(
@@ -1754,6 +1756,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
.search_strategy = options.search_strategy,
.headerpad_size = options.headerpad_size,
.headerpad_max_install_names = options.headerpad_max_install_names,
+ .dead_strip_dylibs = options.dead_strip_dylibs,
});
errdefer bin_file.destroy();
comp.* = .{
@@ -2369,7 +2372,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo
/// to remind the programmer to update multiple related pieces of code that
/// are in different locations. Bump this number when adding or deleting
/// anything from the link cache manifest.
-pub const link_hash_implementation_version = 6;
+pub const link_hash_implementation_version = 7;
fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void {
const gpa = comp.gpa;
@@ -2379,7 +2382,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
- comptime assert(link_hash_implementation_version == 6);
+ comptime assert(link_hash_implementation_version == 7);
if (comp.bin_file.options.module) |mod| {
const main_zig_file = try mod.main_pkg.root_src_directory.join(arena, &[_][]const u8{
@@ -2488,6 +2491,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
man.hash.addOptional(comp.bin_file.options.search_strategy);
man.hash.addOptional(comp.bin_file.options.headerpad_size);
man.hash.add(comp.bin_file.options.headerpad_max_install_names);
+ man.hash.add(comp.bin_file.options.dead_strip_dylibs);
// COFF specific stuff
man.hash.addOptional(comp.bin_file.options.subsystem);
diff --git a/src/link.zig b/src/link.zig
index 21d54d531c..18e10dc74c 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -199,6 +199,9 @@ pub const Options = struct {
/// (Darwin) set enough space as if all paths were MATPATHLEN
headerpad_max_install_names: bool = false,
+ /// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols
+ dead_strip_dylibs: bool = false,
+
pub fn effectiveOutputMode(options: Options) std.builtin.OutputMode {
return if (options.use_lld) .Obj else options.output_mode;
}
diff --git a/src/link/Coff.zig b/src/link/Coff.zig
index 77059a7fd9..0e7d7c89ee 100644
--- a/src/link/Coff.zig
+++ b/src/link/Coff.zig
@@ -969,7 +969,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !
man = comp.cache_parent.obtain();
self.base.releaseLock();
- comptime assert(Compilation.link_hash_implementation_version == 6);
+ comptime assert(Compilation.link_hash_implementation_version == 7);
for (self.base.options.objects) |obj| {
_ = try man.addFile(obj.path, null);
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index 79545d1e1a..faeb7c9d27 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -1298,7 +1298,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
// We are about to obtain this lock, so here we give other processes a chance first.
self.base.releaseLock();
- comptime assert(Compilation.link_hash_implementation_version == 6);
+ comptime assert(Compilation.link_hash_implementation_version == 7);
try man.addOptionalFile(self.base.options.linker_script);
try man.addOptionalFile(self.base.options.version_script);
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 4ddee493b8..bd354ba1ce 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -541,7 +541,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
// We are about to obtain this lock, so here we give other processes a chance first.
self.base.releaseLock();
- comptime assert(Compilation.link_hash_implementation_version == 6);
+ comptime assert(Compilation.link_hash_implementation_version == 7);
for (self.base.options.objects) |obj| {
_ = try man.addFile(obj.path, null);
@@ -558,6 +558,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
man.hash.addOptional(self.base.options.search_strategy);
man.hash.addOptional(self.base.options.headerpad_size);
man.hash.add(self.base.options.headerpad_max_install_names);
+ man.hash.add(self.base.options.dead_strip_dylibs);
man.hash.addListOfBytes(self.base.options.lib_dirs);
man.hash.addListOfBytes(self.base.options.framework_dirs);
man.hash.addListOfBytes(self.base.options.frameworks);
@@ -987,6 +988,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
try argv.append("-headerpad_max_install_names");
}
+ if (self.base.options.dead_strip_dylibs) {
+ try argv.append("-dead_strip_dylibs");
+ }
+
if (self.base.options.entry) |entry| {
try argv.append("-e");
try argv.append(entry);
@@ -1425,7 +1430,12 @@ pub fn parseDylib(self: *MachO, path: []const u8, opts: DylibCreateOpts) ParseDy
try self.dylibs.append(self.base.allocator, dylib);
try self.dylibs_map.putNoClobber(self.base.allocator, dylib.id.?.name, dylib_id);
- if (!(opts.is_dependent or self.referenced_dylibs.contains(dylib_id))) {
+ const should_link_dylib_even_if_unreachable = blk: {
+ if (self.base.options.dead_strip_dylibs) break :blk false;
+ break :blk !(opts.is_dependent or self.referenced_dylibs.contains(dylib_id));
+ };
+
+ if (should_link_dylib_even_if_unreachable) {
try self.addLoadDylibLC(dylib_id);
try self.referenced_dylibs.putNoClobber(self.base.allocator, dylib_id, {});
}
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index b074799771..467aa89621 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -2546,7 +2546,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
// We are about to obtain this lock, so here we give other processes a chance first.
self.base.releaseLock();
- comptime assert(Compilation.link_hash_implementation_version == 6);
+ comptime assert(Compilation.link_hash_implementation_version == 7);
for (self.base.options.objects) |obj| {
_ = try man.addFile(obj.path, null);
diff --git a/src/main.zig b/src/main.zig
index d63e235360..8f9d3e5a13 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -452,6 +452,7 @@ const usage_build_generic =
\\ -search_dylibs_first (Darwin) search `libx.dylib` in each dir in library search paths, then `libx.a`
\\ -headerpad [value] (Darwin) set minimum space for future expansion of the load commands in hexadecimal notation
\\ -headerpad_max_install_names (Darwin) set enough space as if all paths were MAXPATHLEN
+ \\ -dead_strip_dylibs (Darwin) remove dylibs that are unreachable by the entry point or exported symbols
\\ --import-memory (WebAssembly) import memory from the environment
\\ --import-table (WebAssembly) import function table from the host environment
\\ --export-table (WebAssembly) export function table to the host environment
@@ -703,6 +704,7 @@ fn buildOutputType(
var search_strategy: ?link.File.MachO.SearchStrategy = null;
var headerpad_size: ?u32 = null;
var headerpad_max_install_names: bool = false;
+ var dead_strip_dylibs: bool = false;
// e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names.
// This array is populated by zig cc frontend and then has to be converted to zig-style
@@ -937,6 +939,8 @@ fn buildOutputType(
};
} else if (mem.eql(u8, arg, "-headerpad_max_install_names")) {
headerpad_max_install_names = true;
+ } else if (mem.eql(u8, arg, "-dead_strip_dylibs")) {
+ dead_strip_dylibs = true;
} else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) {
linker_script = args_iter.next() orelse {
fatal("expected parameter after {s}", .{arg});
@@ -1700,6 +1704,8 @@ fn buildOutputType(
};
} else if (mem.eql(u8, arg, "-headerpad_max_install_names")) {
headerpad_max_install_names = true;
+ } else if (mem.eql(u8, arg, "-dead_strip_dylibs")) {
+ dead_strip_dylibs = true;
} else if (mem.eql(u8, arg, "--gc-sections")) {
linker_gc_sections = true;
} else if (mem.eql(u8, arg, "--no-gc-sections")) {
@@ -2821,6 +2827,7 @@ fn buildOutputType(
.search_strategy = search_strategy,
.headerpad_size = headerpad_size,
.headerpad_max_install_names = headerpad_max_install_names,
+ .dead_strip_dylibs = dead_strip_dylibs,
}) catch |err| switch (err) {
error.LibCUnavailable => {
const target = target_info.target;