| author | |
| committer | |
| log | 02886a8b93ccfe652ac5797784bddc398047f7eb |
| tree | 3632552b4d7434277fb0ab88fbfc229ab0585528 |
| parent | c0b774fbc65e3e406a38d37b02fffda7c5d3df26 |
5 files changed, 39 insertions(+), 28 deletions(-)
BRANCH_TODO-1| ... | ... | @@ -1,4 +1,3 @@ |
| 1 | * support rpaths in ELF linker code | |
| 2 | 1 | * musl |
| 3 | 2 | * implement proper parsing of LLD stderr/stdout and exposing compile errors |
| 4 | 3 | * tests passing with -Dskip-non-native |
src/Compilation.zig+2| ... | ... | @@ -316,6 +316,7 @@ pub const InitOptions = struct { |
| 316 | 316 | function_sections: ?bool = null, |
| 317 | 317 | linker_allow_shlib_undefined: ?bool = null, |
| 318 | 318 | linker_bind_global_refs_locally: ?bool = null, |
| 319 | each_lib_rpath: ?bool = null, | |
| 319 | 320 | disable_c_depfile: bool = false, |
| 320 | 321 | linker_z_nodelete: bool = false, |
| 321 | 322 | linker_z_defs: bool = false, |
| ... | ... | @@ -714,6 +715,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 714 | 715 | .error_return_tracing = error_return_tracing, |
| 715 | 716 | .llvm_cpu_features = llvm_cpu_features, |
| 716 | 717 | .is_compiler_rt_or_libc = options.is_compiler_rt_or_libc, |
| 718 | .each_lib_rpath = options.each_lib_rpath orelse false, | |
| 717 | 719 | }); |
| 718 | 720 | errdefer bin_file.destroy(); |
| 719 | 721 | comp.* = .{ |
src/link.zig+1| ... | ... | @@ -65,6 +65,7 @@ pub const Options = struct { |
| 65 | 65 | dll_export_fns: bool, |
| 66 | 66 | error_return_tracing: bool, |
| 67 | 67 | is_compiler_rt_or_libc: bool, |
| 68 | each_lib_rpath: bool, | |
| 68 | 69 | gc_sections: ?bool = null, |
| 69 | 70 | allow_shlib_undefined: ?bool = null, |
| 70 | 71 | linker_script: ?[]const u8 = null, |
src/link/Elf.zig+31-27| ... | ... | @@ -1272,6 +1272,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1272 | 1272 | ch.hash.add(self.base.options.rdynamic); |
| 1273 | 1273 | ch.hash.addListOfBytes(self.base.options.extra_lld_args); |
| 1274 | 1274 | ch.hash.addListOfBytes(self.base.options.lib_dirs); |
| 1275 | ch.hash.addListOfBytes(self.base.options.rpath_list); | |
| 1276 | ch.hash.add(self.base.options.each_lib_rpath); | |
| 1275 | 1277 | ch.hash.add(self.base.options.is_compiler_rt_or_libc); |
| 1276 | 1278 | ch.hash.add(self.base.options.z_nodelete); |
| 1277 | 1279 | ch.hash.add(self.base.options.z_defs); |
| ... | ... | @@ -1392,7 +1394,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1392 | 1394 | } |
| 1393 | 1395 | |
| 1394 | 1396 | const full_out_path = if (directory.path) |dir_path| |
| 1395 | try std.fs.path.join(arena, &[_][]const u8{dir_path, self.base.options.sub_path}) | |
| 1397 | try fs.path.join(arena, &[_][]const u8{dir_path, self.base.options.sub_path}) | |
| 1396 | 1398 | else |
| 1397 | 1399 | self.base.options.sub_path; |
| 1398 | 1400 | try argv.append("-o"); |
| ... | ... | @@ -1420,32 +1422,34 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1420 | 1422 | } |
| 1421 | 1423 | } |
| 1422 | 1424 | |
| 1423 | // TODO rpaths | |
| 1424 | // TODO add to cache hash above too | |
| 1425 | //for (size_t i = 0; i < g->rpath_list.length; i += 1) { | |
| 1426 | // Buf *rpath = g->rpath_list.at(i); | |
| 1427 | // add_rpath(lj, rpath); | |
| 1428 | //} | |
| 1429 | //if (g->each_lib_rpath) { | |
| 1430 | // for (size_t i = 0; i < g->lib_dirs.length; i += 1) { | |
| 1431 | // const char *lib_dir = g->lib_dirs.at(i); | |
| 1432 | // for (size_t i = 0; i < g->link_libs_list.length; i += 1) { | |
| 1433 | // LinkLib *link_lib = g->link_libs_list.at(i); | |
| 1434 | // if (buf_eql_str(link_lib->name, "c")) { | |
| 1435 | // continue; | |
| 1436 | // } | |
| 1437 | // bool does_exist; | |
| 1438 | // Buf *test_path = buf_sprintf("%s/lib%s.so", lib_dir, buf_ptr(link_lib->name)); | |
| 1439 | // if (os_file_exists(test_path, &does_exist) != ErrorNone) { | |
| 1440 | // zig_panic("link: unable to check if file exists: %s", buf_ptr(test_path)); | |
| 1441 | // } | |
| 1442 | // if (does_exist) { | |
| 1443 | // add_rpath(lj, buf_create_from_str(lib_dir)); | |
| 1444 | // break; | |
| 1445 | // } | |
| 1446 | // } | |
| 1447 | // } | |
| 1448 | //} | |
| 1425 | // rpaths | |
| 1426 | var rpath_table = std.StringHashMap(void).init(self.base.allocator); | |
| 1427 | defer rpath_table.deinit(); | |
| 1428 | for (self.base.options.rpath_list) |rpath| { | |
| 1429 | if ((try rpath_table.fetchPut(rpath, {})) == null) { | |
| 1430 | try argv.append("-rpath"); | |
| 1431 | try argv.append(rpath); | |
| 1432 | } | |
| 1433 | } | |
| 1434 | if (self.base.options.each_lib_rpath) { | |
| 1435 | var test_path = std.ArrayList(u8).init(self.base.allocator); | |
| 1436 | defer test_path.deinit(); | |
| 1437 | for (self.base.options.lib_dirs) |lib_dir_path| { | |
| 1438 | for (self.base.options.system_libs) |link_lib| { | |
| 1439 | test_path.shrinkRetainingCapacity(0); | |
| 1440 | const sep = fs.path.sep_str; | |
| 1441 | try test_path.writer().print("{}" ++ sep ++ "lib{}.so", .{ lib_dir_path, link_lib }); | |
| 1442 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { | |
| 1443 | error.FileNotFound => continue, | |
| 1444 | else => |e| return e, | |
| 1445 | }; | |
| 1446 | if ((try rpath_table.fetchPut(lib_dir_path, {})) == null) { | |
| 1447 | try argv.append("-rpath"); | |
| 1448 | try argv.append(lib_dir_path); | |
| 1449 | } | |
| 1450 | } | |
| 1451 | } | |
| 1452 | } | |
| 1449 | 1453 | |
| 1450 | 1454 | for (self.base.options.lib_dirs) |lib_dir| { |
| 1451 | 1455 | try argv.append("-L"); |
src/main.zig+5| ... | ... | @@ -251,6 +251,7 @@ const usage_build_generic = |
| 251 | 251 | \\ -L[d], --library-directory [d] Add a directory to the library search path |
| 252 | 252 | \\ -T[script] Use a custom linker script |
| 253 | 253 | \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) |
| 254 | \\ --each-lib-rpath Add rpath for each used dynamic library | |
| 254 | 255 | \\ --version [ver] Dynamic library semver |
| 255 | 256 | \\ -rdynamic Add all symbols to the dynamic symbol table |
| 256 | 257 | \\ -rpath [path] Add directory to the runtime library search path |
| ... | ... | @@ -361,6 +362,7 @@ pub fn buildOutputType( |
| 361 | 362 | var use_lld: ?bool = null; |
| 362 | 363 | var use_clang: ?bool = null; |
| 363 | 364 | var link_eh_frame_hdr = false; |
| 365 | var each_lib_rpath = false; | |
| 364 | 366 | var libc_paths_file: ?[]const u8 = null; |
| 365 | 367 | var machine_code_model: std.builtin.CodeModel = .default; |
| 366 | 368 | var runtime_args_start: ?usize = null; |
| ... | ... | @@ -613,6 +615,8 @@ pub fn buildOutputType( |
| 613 | 615 | if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg}); |
| 614 | 616 | i += 1; |
| 615 | 617 | override_lib_dir = args[i]; |
| 618 | } else if (mem.eql(u8, arg, "--each-lib-rpath")) { | |
| 619 | each_lib_rpath = true; | |
| 616 | 620 | } else if (mem.eql(u8, arg, "--enable-cache")) { |
| 617 | 621 | enable_cache = true; |
| 618 | 622 | } else if (mem.eql(u8, arg, "--test-cmd-bin")) { |
| ... | ... | @@ -1421,6 +1425,7 @@ pub fn buildOutputType( |
| 1421 | 1425 | .color = color, |
| 1422 | 1426 | .time_report = time_report, |
| 1423 | 1427 | .is_test = arg_mode == .zig_test, |
| 1428 | .each_lib_rpath = each_lib_rpath, | |
| 1424 | 1429 | .test_evented_io = test_evented_io, |
| 1425 | 1430 | .test_filter = test_filter, |
| 1426 | 1431 | .test_name_prefix = test_name_prefix, |