authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-23 11:01:15-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-23 11:01:15-07:00
log02886a8b93ccfe652ac5797784bddc398047f7eb
tree3632552b4d7434277fb0ab88fbfc229ab0585528
parentc0b774fbc65e3e406a38d37b02fffda7c5d3df26

stage2: support rpaths


5 files changed, 39 insertions(+), 28 deletions(-)

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