diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-09-23 11:01:15 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-09-23 11:01:15 -0700 |
| commit | 02886a8b93ccfe652ac5797784bddc398047f7eb (patch) | |
| tree | 3632552b4d7434277fb0ab88fbfc229ab0585528 /src | |
| parent | c0b774fbc65e3e406a38d37b02fffda7c5d3df26 (diff) | |
| download | zig-02886a8b93ccfe652ac5797784bddc398047f7eb.tar.gz zig-02886a8b93ccfe652ac5797784bddc398047f7eb.zip | |
stage2: support rpaths
Diffstat (limited to 'src')
| -rw-r--r-- | src/Compilation.zig | 2 | ||||
| -rw-r--r-- | src/link.zig | 1 | ||||
| -rw-r--r-- | src/link/Elf.zig | 58 | ||||
| -rw-r--r-- | src/main.zig | 5 |
4 files changed, 39 insertions, 27 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 656baa898b..1297341926 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -316,6 +316,7 @@ pub const InitOptions = struct { function_sections: ?bool = null, linker_allow_shlib_undefined: ?bool = null, linker_bind_global_refs_locally: ?bool = null, + each_lib_rpath: ?bool = null, disable_c_depfile: bool = false, linker_z_nodelete: bool = false, linker_z_defs: bool = false, @@ -714,6 +715,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .error_return_tracing = error_return_tracing, .llvm_cpu_features = llvm_cpu_features, .is_compiler_rt_or_libc = options.is_compiler_rt_or_libc, + .each_lib_rpath = options.each_lib_rpath orelse false, }); errdefer bin_file.destroy(); comp.* = .{ diff --git a/src/link.zig b/src/link.zig index 71d49286ba..82d67f2a7a 100644 --- a/src/link.zig +++ b/src/link.zig @@ -65,6 +65,7 @@ pub const Options = struct { dll_export_fns: bool, error_return_tracing: bool, is_compiler_rt_or_libc: bool, + each_lib_rpath: bool, gc_sections: ?bool = null, allow_shlib_undefined: ?bool = null, linker_script: ?[]const u8 = null, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index b275026e8e..d4900ccb25 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1272,6 +1272,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { ch.hash.add(self.base.options.rdynamic); ch.hash.addListOfBytes(self.base.options.extra_lld_args); ch.hash.addListOfBytes(self.base.options.lib_dirs); + ch.hash.addListOfBytes(self.base.options.rpath_list); + ch.hash.add(self.base.options.each_lib_rpath); ch.hash.add(self.base.options.is_compiler_rt_or_libc); ch.hash.add(self.base.options.z_nodelete); ch.hash.add(self.base.options.z_defs); @@ -1392,7 +1394,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { } const full_out_path = if (directory.path) |dir_path| - try std.fs.path.join(arena, &[_][]const u8{dir_path, self.base.options.sub_path}) + try fs.path.join(arena, &[_][]const u8{dir_path, self.base.options.sub_path}) else self.base.options.sub_path; try argv.append("-o"); @@ -1420,32 +1422,34 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { } } - // TODO rpaths - // TODO add to cache hash above too - //for (size_t i = 0; i < g->rpath_list.length; i += 1) { - // Buf *rpath = g->rpath_list.at(i); - // add_rpath(lj, rpath); - //} - //if (g->each_lib_rpath) { - // for (size_t i = 0; i < g->lib_dirs.length; i += 1) { - // const char *lib_dir = g->lib_dirs.at(i); - // for (size_t i = 0; i < g->link_libs_list.length; i += 1) { - // LinkLib *link_lib = g->link_libs_list.at(i); - // if (buf_eql_str(link_lib->name, "c")) { - // continue; - // } - // bool does_exist; - // Buf *test_path = buf_sprintf("%s/lib%s.so", lib_dir, buf_ptr(link_lib->name)); - // if (os_file_exists(test_path, &does_exist) != ErrorNone) { - // zig_panic("link: unable to check if file exists: %s", buf_ptr(test_path)); - // } - // if (does_exist) { - // add_rpath(lj, buf_create_from_str(lib_dir)); - // break; - // } - // } - // } - //} + // rpaths + var rpath_table = std.StringHashMap(void).init(self.base.allocator); + defer rpath_table.deinit(); + for (self.base.options.rpath_list) |rpath| { + if ((try rpath_table.fetchPut(rpath, {})) == null) { + try argv.append("-rpath"); + try argv.append(rpath); + } + } + if (self.base.options.each_lib_rpath) { + var test_path = std.ArrayList(u8).init(self.base.allocator); + defer test_path.deinit(); + for (self.base.options.lib_dirs) |lib_dir_path| { + for (self.base.options.system_libs) |link_lib| { + test_path.shrinkRetainingCapacity(0); + const sep = fs.path.sep_str; + try test_path.writer().print("{}" ++ sep ++ "lib{}.so", .{ lib_dir_path, link_lib }); + fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { + error.FileNotFound => continue, + else => |e| return e, + }; + if ((try rpath_table.fetchPut(lib_dir_path, {})) == null) { + try argv.append("-rpath"); + try argv.append(lib_dir_path); + } + } + } + } for (self.base.options.lib_dirs) |lib_dir| { try argv.append("-L"); diff --git a/src/main.zig b/src/main.zig index 73676fb75e..a33e8bfc3b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -251,6 +251,7 @@ const usage_build_generic = \\ -L[d], --library-directory [d] Add a directory to the library search path \\ -T[script] Use a custom linker script \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) + \\ --each-lib-rpath Add rpath for each used dynamic library \\ --version [ver] Dynamic library semver \\ -rdynamic Add all symbols to the dynamic symbol table \\ -rpath [path] Add directory to the runtime library search path @@ -361,6 +362,7 @@ pub fn buildOutputType( var use_lld: ?bool = null; var use_clang: ?bool = null; var link_eh_frame_hdr = false; + var each_lib_rpath = false; var libc_paths_file: ?[]const u8 = null; var machine_code_model: std.builtin.CodeModel = .default; var runtime_args_start: ?usize = null; @@ -613,6 +615,8 @@ pub fn buildOutputType( if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg}); i += 1; override_lib_dir = args[i]; + } else if (mem.eql(u8, arg, "--each-lib-rpath")) { + each_lib_rpath = true; } else if (mem.eql(u8, arg, "--enable-cache")) { enable_cache = true; } else if (mem.eql(u8, arg, "--test-cmd-bin")) { @@ -1421,6 +1425,7 @@ pub fn buildOutputType( .color = color, .time_report = time_report, .is_test = arg_mode == .zig_test, + .each_lib_rpath = each_lib_rpath, .test_evented_io = test_evented_io, .test_filter = test_filter, .test_name_prefix = test_name_prefix, |
