aboutsummaryrefslogtreecommitdiff
path: root/src/link.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-03-31 16:34:55 -0400
committerAndrew Kelley <superjoe30@gmail.com>2018-03-31 16:34:55 -0400
commit67f11190d10caac1d08b76d60ec28eb2f5173946 (patch)
treeb276a0ae24321fd17e9dd5f99754dbf8b4c5a359 /src/link.cpp
parenteb6ff796c17b50969a8f0171ba089f31667b7278 (diff)
downloadzig-67f11190d10caac1d08b76d60ec28eb2f5173946.tar.gz
zig-67f11190d10caac1d08b76d60ec28eb2f5173946.zip
musl-friendly dynamic linking
Diffstat (limited to 'src/link.cpp')
-rw-r--r--src/link.cpp57
1 files changed, 35 insertions, 22 deletions
diff --git a/src/link.cpp b/src/link.cpp
index c089d69611..3c6e27e331 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<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) {
- const char *cc_exe = getenv("CC");
- cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
- ZigList<const char *> 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) {