authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-03-05 15:54:08-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-03-05 16:00:28-05:00
log55a0016221e459c49b9f04a4b57ba84be27bba72
tree8c7b7eb1e0e6bf6b34d41110d990f5dca6c4f6f4
parent0d10ab0680c8cd0c75bf6f6cc7d4a153ac742db8
signature Commit is signed but in an unrecognized format.

dynamic linker path is independent from libc installation


9 files changed, 90 insertions(+), 66 deletions(-)

src/all_types.hpp+1
......@@ -1851,6 +1851,7 @@ struct CodeGen {
18511851 ZigPackage *root_package;
18521852 Buf *zig_lib_dir;
18531853 Buf *zig_std_dir;
1854 Buf *dynamic_linker_path;
18541855
18551856 const char **llvm_argv;
18561857 size_t llvm_argv_len;
src/codegen.cpp+51-1
......@@ -257,6 +257,10 @@ void codegen_set_out_name(CodeGen *g, Buf *out_name) {
257257 g->root_out_name = out_name;
258258}
259259
260void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker_path) {
261 g->dynamic_linker_path = dynamic_linker_path;
262}
263
260264void codegen_add_lib_dir(CodeGen *g, const char *dir) {
261265 g->lib_dirs.append(dir);
262266}
......@@ -7908,6 +7912,51 @@ static void init(CodeGen *g) {
79087912 }
79097913}
79107914
7915static void detect_dynamic_linker(CodeGen *g) {
7916 if (g->dynamic_linker_path != nullptr)
7917 return;
7918
7919 if (g->zig_target->is_native) {
7920 // target_dynamic_linker is usually correct. However on some systems, such as NixOS
7921 // it will be incorrect. See if we can do better by looking at what zig's own
7922 // dynamic linker path is.
7923 g->dynamic_linker_path = get_self_dynamic_linker_path();
7924 if (g->dynamic_linker_path != nullptr)
7925 return;
7926
7927 // If Zig is statically linked, such as via distributed binary static builds, the above
7928 // trick won't work. What are we left with? Try to run the system C compiler and get
7929 // it to tell us the dynamic linker path
7930#if defined(ZIG_OS_LINUX)
7931 {
7932 Error err;
7933 static const char *dyn_tests[] = {
7934#if defined(ZIG_ARCH_X86_64)
7935 "ld-linux-x86-64.so.2",
7936 "ld-musl-x86_64.so.1",
7937#endif
7938 };
7939 Buf *result = buf_alloc();
7940 for (size_t i = 0; i < array_length(dyn_tests); i += 1) {
7941 const char *lib_name = dyn_tests[i];
7942 if ((err = zig_libc_cc_print_file_name(lib_name, result, false, true))) {
7943 if (err != ErrorCCompilerCannotFindFile) {
7944 fprintf(stderr, "Unable to detect native dynamic linker: %s\n", err_str(err));
7945 exit(1);
7946 }
7947 continue;
7948 }
7949 g->dynamic_linker_path = result;
7950 return;
7951 }
7952 }
7953#endif
7954 }
7955
7956 // Otherwise go with the standard linker path.
7957 g->dynamic_linker_path = buf_create_from_str(target_dynamic_linker(g->zig_target));
7958}
7959
79117960static void detect_libc(CodeGen *g) {
79127961 Error err;
79137962
......@@ -9029,8 +9078,8 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
90299078 cache_buf(ch, &g->libc->crt_dir);
90309079 cache_buf(ch, &g->libc->msvc_lib_dir);
90319080 cache_buf(ch, &g->libc->kernel32_lib_dir);
9032 cache_buf(ch, &g->libc->dynamic_linker_path);
90339081 }
9082 cache_buf(ch, g->dynamic_linker_path);
90349083
90359084 gen_c_objects(g);
90369085
......@@ -9132,6 +9181,7 @@ void codegen_build_and_link(CodeGen *g) {
91329181 assert(g->out_type != OutTypeUnknown);
91339182
91349183 detect_libc(g);
9184 detect_dynamic_linker(g);
91359185
91369186 Buf *artifact_dir = buf_alloc();
91379187 Buf digest = BUF_INIT;
src/codegen.hpp+1
......@@ -29,6 +29,7 @@ void codegen_set_is_static(CodeGen *codegen, bool is_static);
2929void codegen_set_strip(CodeGen *codegen, bool strip);
3030void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);
3131void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
32void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker);
3233void codegen_add_lib_dir(CodeGen *codegen, const char *dir);
3334void codegen_add_forbidden_lib(CodeGen *codegen, Buf *lib);
3435LinkLib *codegen_add_link_lib(CodeGen *codegen, Buf *lib);
src/compiler.cpp+15-1
......@@ -1,4 +1,5 @@
11#include "cache_hash.hpp"
2#include "os.hpp"
23
34#include <stdio.h>
45
......@@ -8,8 +9,9 @@ static Buf saved_stage1_path = BUF_INIT;
89static Buf saved_lib_dir = BUF_INIT;
910static Buf saved_special_dir = BUF_INIT;
1011static Buf saved_std_dir = BUF_INIT;
12static Buf saved_dynamic_linker_path = BUF_INIT;
1113
12Buf *get_stage1_cache_path() {
14Buf *get_stage1_cache_path(void) {
1315 if (saved_stage1_path.list.length != 0) {
1416 return &saved_stage1_path;
1517 }
......@@ -57,6 +59,13 @@ Error get_compiler_id(Buf **result) {
5759 Buf *lib_path = lib_paths.at(i);
5860 if ((err = cache_add_file(ch, lib_path)))
5961 return err;
62#if defined(ZIG_OS_LINUX) && defined(ZIG_ARCH_X86_64)
63 if (buf_ends_with_str(lib_path, "ld-linux-x86-64.so.2")) {
64 buf_init_from_buf(&saved_dynamic_linker_path, lib_path);
65 } else if (buf_ends_with_str(lib_path, "ld-musl-x86-64.so.1")) {
66 buf_init_from_buf(&saved_dynamic_linker_path, lib_path);
67 }
68#endif
6069 }
6170 if ((err = cache_final(ch, &saved_compiler_id)))
6271 return err;
......@@ -67,6 +76,11 @@ Error get_compiler_id(Buf **result) {
6776 return ErrorNone;
6877}
6978
79Buf *get_self_dynamic_linker_path(void) {
80 Buf *dontcare;
81 (void)get_compiler_id(&dontcare); // for the side-effects of caching the dynamic linker path
82 return (saved_dynamic_linker_path.list.length == 0) ? nullptr : &saved_dynamic_linker_path;
83}
7084
7185static bool test_zig_install_prefix(Buf *test_path, Buf *out_zig_lib_dir) {
7286 Buf lib_buf = BUF_INIT;
src/compiler.hpp+5-4
......@@ -11,11 +11,12 @@
1111#include "buffer.hpp"
1212#include "error.hpp"
1313
14Buf *get_stage1_cache_path();
14Buf *get_stage1_cache_path(void);
1515Error get_compiler_id(Buf **result);
16Buf *get_self_dynamic_linker_path(void);
1617
17Buf *get_zig_lib_dir();
18Buf *get_zig_special_dir();
19Buf *get_zig_std_dir();
18Buf *get_zig_lib_dir(void);
19Buf *get_zig_special_dir(void);
20Buf *get_zig_std_dir(void);
2021
2122#endif
src/libc_installation.cpp+4-49
......@@ -16,7 +16,6 @@ static const char *zig_libc_keys[] = {
1616 "crt_dir",
1717 "msvc_lib_dir",
1818 "kernel32_lib_dir",
19 "dynamic_linker_path",
2019};
2120
2221static const size_t zig_libc_keys_len = array_length(zig_libc_keys);
......@@ -37,7 +36,6 @@ static void zig_libc_init_empty(ZigLibCInstallation *libc) {
3736 buf_init_from_str(&libc->crt_dir, "");
3837 buf_init_from_str(&libc->msvc_lib_dir, "");
3938 buf_init_from_str(&libc->kernel32_lib_dir, "");
40 buf_init_from_str(&libc->dynamic_linker_path, "");
4139}
4240
4341Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget *target, bool verbose) {
......@@ -78,7 +76,6 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget
7876 match = match || zig_libc_match_key(name, value, found_keys, 2, &libc->crt_dir);
7977 match = match || zig_libc_match_key(name, value, found_keys, 3, &libc->msvc_lib_dir);
8078 match = match || zig_libc_match_key(name, value, found_keys, 4, &libc->kernel32_lib_dir);
81 match = match || zig_libc_match_key(name, value, found_keys, 5, &libc->dynamic_linker_path);
8279 }
8380
8481 for (size_t i = 0; i < zig_libc_keys_len; i += 1) {
......@@ -131,15 +128,6 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget
131128 }
132129 }
133130
134 if (buf_len(&libc->dynamic_linker_path) == 0) {
135 if (!target_is_darwin(target) && target->os != OsWindows) {
136 if (verbose) {
137 fprintf(stderr, "dynamic_linker_path may not be empty for %s\n", target_os_name(target->os));
138 }
139 return ErrorSemanticAnalyzeFail;
140 }
141 }
142
143131 return ErrorNone;
144132}
145133
......@@ -301,8 +289,8 @@ static Error zig_libc_find_native_include_dir_posix(ZigLibCInstallation *self, b
301289 }
302290 return ErrorFileNotFound;
303291}
304#if !defined(ZIG_OS_DARWIN) && !defined(ZIG_OS_FREEBSD) && !defined(ZIG_OS_NETBSD)
305static Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose) {
292#if defined(ZIG_OS_LINUX)
293Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose) {
306294 const char *cc_exe = getenv("CC");
307295 cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe;
308296 ZigList<const char *> args = {};
......@@ -340,32 +328,6 @@ static Error zig_libc_find_native_crt_dir_posix(ZigLibCInstallation *self, bool
340328 return zig_libc_cc_print_file_name("crt1.o", &self->crt_dir, true, verbose);
341329}
342330#endif
343
344static Error zig_libc_find_native_dynamic_linker_posix(ZigLibCInstallation *self, bool verbose) {
345#if defined(ZIG_OS_LINUX)
346 Error err;
347 static const char *dyn_tests[] = {
348 "ld-linux-x86-64.so.2",
349 "ld-musl-x86_64.so.1",
350 };
351 for (size_t i = 0; i < array_length(dyn_tests); i += 1) {
352 const char *lib_name = dyn_tests[i];
353 if ((err = zig_libc_cc_print_file_name(lib_name, &self->dynamic_linker_path, false, true))) {
354 if (err != ErrorCCompilerCannotFindFile)
355 return err;
356 continue;
357 }
358 return ErrorNone;
359 }
360#endif
361 ZigTarget native_target;
362 get_native_target(&native_target);
363 const char *dynamic_linker_path = target_dynamic_linker(&native_target);
364 if (dynamic_linker_path != nullptr) {
365 buf_init_from_str(&self->dynamic_linker_path, dynamic_linker_path);
366 }
367 return ErrorNone;
368}
369331#endif
370332
371333void zig_libc_render(ZigLibCInstallation *self, FILE *file) {
......@@ -391,17 +353,12 @@ void zig_libc_render(ZigLibCInstallation *self, FILE *file) {
391353 "# Only needed when targeting Windows.\n"
392354 "kernel32_lib_dir=%s\n"
393355 "\n"
394 "# The full path to the dynamic linker, on the target system.\n"
395 "# Not needed when targeting MacOS or Windows.\n"
396 "dynamic_linker_path=%s\n"
397 "\n"
398356 ,
399357 buf_ptr(&self->include_dir),
400358 buf_ptr(&self->sys_include_dir),
401359 buf_ptr(&self->crt_dir),
402360 buf_ptr(&self->msvc_lib_dir),
403 buf_ptr(&self->kernel32_lib_dir),
404 buf_ptr(&self->dynamic_linker_path)
361 buf_ptr(&self->kernel32_lib_dir)
405362 );
406363}
407364
......@@ -438,12 +395,10 @@ Error zig_libc_find_native(ZigLibCInstallation *self, bool verbose) {
438395 return err;
439396#if defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD)
440397 buf_init_from_str(&self->crt_dir, "/usr/lib");
441#elif !defined(ZIG_OS_DARWIN)
398#elif defined(ZIG_OS_LINUX)
442399 if ((err = zig_libc_find_native_crt_dir_posix(self, verbose)))
443400 return err;
444401#endif
445 if ((err = zig_libc_find_native_dynamic_linker_posix(self, verbose)))
446 return err;
447402 return ErrorNone;
448403#endif
449404}
src/libc_installation.hpp+4-1
......@@ -21,7 +21,6 @@ struct ZigLibCInstallation {
2121 Buf crt_dir;
2222 Buf msvc_lib_dir;
2323 Buf kernel32_lib_dir;
24 Buf dynamic_linker_path;
2524};
2625
2726Error ATTRIBUTE_MUST_USE zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file,
......@@ -30,4 +29,8 @@ void zig_libc_render(ZigLibCInstallation *self, FILE *file);
3029
3130Error ATTRIBUTE_MUST_USE zig_libc_find_native(ZigLibCInstallation *self, bool verbose);
3231
32#if defined(ZIG_OS_LINUX)
33Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose);
34#endif
35
3336#endif
src/link.cpp+3-9
......@@ -517,14 +517,9 @@ static void construct_linker_job_elf(LinkJob *lj) {
517517 }
518518
519519 if (!g->is_static) {
520 if (g->libc != nullptr) {
521 assert(buf_len(&g->libc->dynamic_linker_path) != 0);
522 lj->args.append("-dynamic-linker");
523 lj->args.append(buf_ptr(&g->libc->dynamic_linker_path));
524 } else {
525 lj->args.append("-dynamic-linker");
526 lj->args.append(target_dynamic_linker(g->zig_target));
527 }
520 assert(g->dynamic_linker_path != nullptr);
521 lj->args.append("-dynamic-linker");
522 lj->args.append(buf_ptr(g->dynamic_linker_path));
528523 }
529524
530525 }
......@@ -545,7 +540,6 @@ static void construct_linker_job_elf(LinkJob *lj) {
545540 lj->args.append(buf_ptr(builtin_a_path));
546541 }
547542
548 // sometimes libgcc is missing stuff, so we still build compiler_rt and rely on weak linkage
549543 Buf *compiler_rt_o_path = build_compiler_rt(g);
550544 lj->args.append(buf_ptr(compiler_rt_o_path));
551545 }
src/main.cpp+6-1
......@@ -166,7 +166,7 @@ static int print_target_list(FILE *f) {
166166 SubArchList sub_arch_list = target_subarch_list(arch);
167167 size_t sub_count = target_subarch_count(sub_arch_list);
168168 const char *arch_native_str = (native.arch == arch) ? " (native)" : "";
169 fprintf(stderr, " %s%s\n", arch_name, arch_native_str);
169 fprintf(f, " %s%s\n", arch_name, arch_native_str);
170170 for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) {
171171 ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
172172 const char *sub_name = target_subarch_name(sub);
......@@ -406,6 +406,7 @@ int main(int argc, char **argv) {
406406 bool verbose_cc = false;
407407 ErrColor color = ErrColorAuto;
408408 CacheOpt enable_cache = CacheOptAuto;
409 const char *dynamic_linker = nullptr;
409410 const char *libc_txt = nullptr;
410411 ZigList<const char *> clang_argv = {0};
411412 ZigList<const char *> llvm_argv = {0};
......@@ -715,6 +716,8 @@ int main(int argc, char **argv) {
715716 }
716717 } else if (strcmp(arg, "--name") == 0) {
717718 out_name = argv[i];
719 } else if (strcmp(arg, "--dynamic-linker") == 0) {
720 dynamic_linker = argv[i];
718721 } else if (strcmp(arg, "--libc") == 0) {
719722 libc_txt = argv[i];
720723 } else if (strcmp(arg, "-isystem") == 0) {
......@@ -1027,6 +1030,8 @@ int main(int argc, char **argv) {
10271030 codegen_set_llvm_argv(g, llvm_argv.items, llvm_argv.length);
10281031 codegen_set_strip(g, strip);
10291032 codegen_set_is_static(g, is_static);
1033 if (dynamic_linker != nullptr)
1034 codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker));
10301035 g->verbose_tokenize = verbose_tokenize;
10311036 g->verbose_ast = verbose_ast;
10321037 g->verbose_link = verbose_link;