From 67f11190d10caac1d08b76d60ec28eb2f5173946 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 31 Mar 2018 16:34:55 -0400 Subject: [PATCH] musl-friendly dynamic linking --- build.zig | 5 +++++ src/link.cpp | 57 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/build.zig b/build.zig index 88775498cabf..b72641a2efa4 100644 --- a/build.zig +++ b/build.zig @@ -45,6 +45,11 @@ pub fn build(b: &Builder) !void { var exe = b.addExecutable("zig", "src-self-hosted/main.zig"); exe.setBuildMode(mode); + + // This is for finding /lib/libz.a on alpine linux. + // TODO turn this into -Dextra-lib-path=/lib option + exe.addLibPath("/lib"); + exe.addIncludeDir("src"); exe.addIncludeDir(cmake_binary_dir); addCppLib(b, exe, cmake_binary_dir, "zig_cpp"); diff --git a/src/link.cpp b/src/link.cpp index c089d69611c0..3c6e27e33164 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -164,32 +164,45 @@ static void add_rpath(LinkJob *lj, Buf *rpath) { lj->rpath_table.put(rpath, true); } +static Buf *try_dynamic_linker_path(const char *ld_name) { + const char *cc_exe = getenv("CC"); + cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe; + ZigList args = {}; + args.append(buf_ptr(buf_sprintf("-print-file-name=%s", ld_name))); + Termination term; + Buf *out_stderr = buf_alloc(); + Buf *out_stdout = buf_alloc(); + int err; + if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) { + return nullptr; + } + if (term.how != TerminationIdClean || term.code != 0) { + return nullptr; + } + if (buf_ends_with_str(out_stdout, "\n")) { + buf_resize(out_stdout, buf_len(out_stdout) - 1); + } + if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, ld_name)) { + return nullptr; + } + return out_stdout; +} + static Buf *get_dynamic_linker_path(CodeGen *g) { if (g->is_native_target && g->zig_target.arch.arch == ZigLLVM_x86_64) { - const char *cc_exe = getenv("CC"); - cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe; - ZigList args = {}; - args.append("-print-file-name=ld-linux-x86-64.so.2"); - Termination term; - Buf *out_stderr = buf_alloc(); - Buf *out_stdout = buf_alloc(); - int err; - if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) { - return target_dynamic_linker(&g->zig_target); - } - if (term.how != TerminationIdClean || term.code != 0) { - return target_dynamic_linker(&g->zig_target); - } - if (buf_ends_with_str(out_stdout, "\n")) { - buf_resize(out_stdout, buf_len(out_stdout) - 1); - } - if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, "ld-linux-x86-64.so.2")) { - return target_dynamic_linker(&g->zig_target); + static const char *ld_names[] = { + "ld-linux-x86-64.so.2", + "ld-musl-x86_64.so.1", + }; + for (size_t i = 0; i < array_length(ld_names); i += 1) { + const char *ld_name = ld_names[i]; + Buf *result = try_dynamic_linker_path(ld_name); + if (result != nullptr) { + return result; + } } - return out_stdout; - } else { - return target_dynamic_linker(&g->zig_target); } + return target_dynamic_linker(&g->zig_target); } static void construct_linker_job_elf(LinkJob *lj) {