authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-03-31 16:34:55-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-03-31 16:34:55-04:00
log67f11190d10caac1d08b76d60ec28eb2f5173946
treeb276a0ae24321fd17e9dd5f99754dbf8b4c5a359
parenteb6ff796c17b50969a8f0171ba089f31667b7278

musl-friendly dynamic linking


2 files changed, 40 insertions(+), 22 deletions(-)

build.zig+5
......@@ -45,6 +45,11 @@ pub fn build(b: &Builder) !void {
4545
4646 var exe = b.addExecutable("zig", "src-self-hosted/main.zig");
4747 exe.setBuildMode(mode);
48
49 // This is for finding /lib/libz.a on alpine linux.
50 // TODO turn this into -Dextra-lib-path=/lib option
51 exe.addLibPath("/lib");
52
4853 exe.addIncludeDir("src");
4954 exe.addIncludeDir(cmake_binary_dir);
5055 addCppLib(b, exe, cmake_binary_dir, "zig_cpp");
src/link.cpp+35-22
......@@ -164,32 +164,45 @@ static void add_rpath(LinkJob *lj, Buf *rpath) {
164164 lj->rpath_table.put(rpath, true);
165165}
166166
167static Buf *try_dynamic_linker_path(const char *ld_name) {
168 const char *cc_exe = getenv("CC");
169 cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
170 ZigList<const char *> args = {};
171 args.append(buf_ptr(buf_sprintf("-print-file-name=%s", ld_name)));
172 Termination term;
173 Buf *out_stderr = buf_alloc();
174 Buf *out_stdout = buf_alloc();
175 int err;
176 if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) {
177 return nullptr;
178 }
179 if (term.how != TerminationIdClean || term.code != 0) {
180 return nullptr;
181 }
182 if (buf_ends_with_str(out_stdout, "\n")) {
183 buf_resize(out_stdout, buf_len(out_stdout) - 1);
184 }
185 if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, ld_name)) {
186 return nullptr;
187 }
188 return out_stdout;
189}
190
167191static Buf *get_dynamic_linker_path(CodeGen *g) {
168192 if (g->is_native_target && g->zig_target.arch.arch == ZigLLVM_x86_64) {
169 const char *cc_exe = getenv("CC");
170 cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
171 ZigList<const char *> args = {};
172 args.append("-print-file-name=ld-linux-x86-64.so.2");
173 Termination term;
174 Buf *out_stderr = buf_alloc();
175 Buf *out_stdout = buf_alloc();
176 int err;
177 if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) {
178 return target_dynamic_linker(&g->zig_target);
179 }
180 if (term.how != TerminationIdClean || term.code != 0) {
181 return target_dynamic_linker(&g->zig_target);
182 }
183 if (buf_ends_with_str(out_stdout, "\n")) {
184 buf_resize(out_stdout, buf_len(out_stdout) - 1);
185 }
186 if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, "ld-linux-x86-64.so.2")) {
187 return target_dynamic_linker(&g->zig_target);
193 static const char *ld_names[] = {
194 "ld-linux-x86-64.so.2",
195 "ld-musl-x86_64.so.1",
196 };
197 for (size_t i = 0; i < array_length(ld_names); i += 1) {
198 const char *ld_name = ld_names[i];
199 Buf *result = try_dynamic_linker_path(ld_name);
200 if (result != nullptr) {
201 return result;
202 }
188203 }
189 return out_stdout;
190 } else {
191 return target_dynamic_linker(&g->zig_target);
192204 }
205 return target_dynamic_linker(&g->zig_target);
193206}
194207
195208static void construct_linker_job_elf(LinkJob *lj) {