diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index a1d741bc9b..78aa278005 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -909,6 +909,7 @@ const Stage2Target = extern struct { os_builtin_str: ?[*:0]const u8, dynamic_linker: ?[*:0]const u8, + standard_dynamic_linker_path: ?[*:0]const u8, fn fromTarget(self: *Stage2Target, cross_target: CrossTarget) !void { const allocator = std.heap.c_allocator; @@ -1119,6 +1120,12 @@ const Stage2Target = extern struct { } }; + const std_dl = target.standardDynamicLinkerPath(); + const std_dl_z = if (std_dl.get()) |dl| + (try mem.dupeZ(std.heap.c_allocator, u8, dl)).ptr + else + null; + const cache_hash_slice = cache_hash.toOwnedSlice(); self.* = .{ .arch = @enumToInt(target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch @@ -1134,6 +1141,7 @@ const Stage2Target = extern struct { .is_native = cross_target.isNative(), .glibc_or_darwin_version = glibc_or_darwin_version, .dynamic_linker = dynamic_linker, + .standard_dynamic_linker_path = std_dl_z, }; } }; diff --git a/src/all_types.hpp b/src/all_types.hpp index 6719d78a92..3f143b35c1 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2267,6 +2267,7 @@ struct CodeGen { Buf *zig_lib_dir; Buf *zig_std_dir; Buf *version_script_path; + Buf *override_soname; const char **llvm_argv; size_t llvm_argv_len; diff --git a/src/codegen.cpp b/src/codegen.cpp index 8fae16e551..c2ce2ac3eb 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -10510,6 +10510,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_str(ch, g->libc->kernel32_lib_dir); } cache_buf_opt(ch, g->version_script_path); + cache_buf_opt(ch, g->override_soname); // gen_c_objects appends objects to g->link_objects which we want to include in the hash gen_c_objects(g); diff --git a/src/glibc.cpp b/src/glibc.cpp index da5c1d5290..75b77ec122 100644 --- a/src/glibc.cpp +++ b/src/glibc.cpp @@ -16,6 +16,7 @@ static const ZigGLibCLib glibc_libs[] = { {"pthread", 0}, {"dl", 2}, {"rt", 1}, + {"ld", 2}, }; Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbose) { @@ -330,6 +331,8 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con return err; } + bool is_ld = (strcmp(lib->name, "ld") == 0); + CodeGen *child_gen = create_child_codegen(g, zig_file_path, OutTypeLib, nullptr, lib->name, progress_node); codegen_set_lib_version(child_gen, lib->sover, 0, 0); child_gen->is_dynamic = true; @@ -337,6 +340,13 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con child_gen->version_script_path = map_file_path; child_gen->enable_cache = false; child_gen->output_dir = dummy_dir; + if (is_ld) { + assert(g->zig_target->standard_dynamic_linker_path != nullptr); + Buf *ld_basename = buf_alloc(); + os_path_split(buf_create_from_str(g->zig_target->standard_dynamic_linker_path), + nullptr, ld_basename); + child_gen->override_soname = ld_basename; + } codegen_build_and_link(child_gen); } diff --git a/src/link.cpp b/src/link.cpp index 3f7772bb08..0ae47c8432 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1651,7 +1651,6 @@ static void construct_linker_job_elf(LinkJob *lj) { bool is_lib = g->out_type == OutTypeLib; bool is_dyn_lib = g->is_dynamic && is_lib; - Buf *soname = nullptr; if (!g->have_dynamic_link) { if (g->zig_target->arch == ZigLLVM_arm || g->zig_target->arch == ZigLLVM_armeb || g->zig_target->arch == ZigLLVM_thumb || g->zig_target->arch == ZigLLVM_thumbeb) @@ -1662,15 +1661,13 @@ static void construct_linker_job_elf(LinkJob *lj) { } } else if (is_dyn_lib) { lj->args.append("-shared"); - - assert(buf_len(&g->bin_file_output_path) != 0); - soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major); } if (target_requires_pie(g->zig_target) && g->out_type == OutTypeExe) { lj->args.append("-pie"); } + assert(buf_len(&g->bin_file_output_path) != 0); lj->args.append("-o"); lj->args.append(buf_ptr(&g->bin_file_output_path)); @@ -1740,6 +1737,9 @@ static void construct_linker_job_elf(LinkJob *lj) { } if (is_dyn_lib) { + Buf *soname = (g->override_soname == nullptr) ? + buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major) : + g->override_soname; lj->args.append("-soname"); lj->args.append(buf_ptr(soname)); diff --git a/src/stage2.h b/src/stage2.h index 24fd664b3c..9ba7e062b1 100644 --- a/src/stage2.h +++ b/src/stage2.h @@ -291,6 +291,7 @@ struct ZigTarget { size_t cache_hash_len; const char *os_builtin_str; const char *dynamic_linker; + const char *standard_dynamic_linker_path; }; // ABI warning