diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-04-04 17:22:26 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-04-04 17:22:26 -0400 |
| commit | cca93908e6d57f18054d153ca01d6869739306f2 (patch) | |
| tree | b7316e13386963e5b08aebc1f5707498b64a9ebb /src/link.cpp | |
| parent | c541ac240c3ad17dda964f9de085a5e8f5472c7a (diff) | |
| parent | 8938429ea12ff2857ace5380932a7cd68d3b4ab1 (diff) | |
| download | zig-cca93908e6d57f18054d153ca01d6869739306f2.tar.gz zig-cca93908e6d57f18054d153ca01d6869739306f2.zip | |
Merge remote-tracking branch 'origin/master' into llvm7
Diffstat (limited to 'src/link.cpp')
| -rw-r--r-- | src/link.cpp | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/src/link.cpp b/src/link.cpp index f0537ffa0f..3c6e27e331 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -164,6 +164,47 @@ 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<const char *> 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) { + 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 target_dynamic_linker(&g->zig_target); +} + static void construct_linker_job_elf(LinkJob *lj) { CodeGen *g = lj->codegen; @@ -259,12 +300,16 @@ static void construct_linker_job_elf(LinkJob *lj) { lj->args.append(buf_ptr(g->libc_static_lib_dir)); } - if (g->dynamic_linker && buf_len(g->dynamic_linker) > 0) { - lj->args.append("-dynamic-linker"); - lj->args.append(buf_ptr(g->dynamic_linker)); - } else { - lj->args.append("-dynamic-linker"); - lj->args.append(buf_ptr(target_dynamic_linker(&g->zig_target))); + if (!g->is_static) { + if (g->dynamic_linker != nullptr) { + assert(buf_len(g->dynamic_linker) != 0); + lj->args.append("-dynamic-linker"); + lj->args.append(buf_ptr(g->dynamic_linker)); + } else { + Buf *resolved_dynamic_linker = get_dynamic_linker_path(g); + lj->args.append("-dynamic-linker"); + lj->args.append(buf_ptr(resolved_dynamic_linker)); + } } if (shared) { @@ -423,7 +468,9 @@ static void construct_linker_job_coff(LinkJob *lj) { lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->kernel32_lib_dir)))); lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_lib_dir)))); - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_static_lib_dir)))); + if (g->libc_static_lib_dir != nullptr) { + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->libc_static_lib_dir)))); + } } if (lj->link_in_crt) { |
