| author | |
| committer | |
| log | 55a0016221e459c49b9f04a4b57ba84be27bba72 |
| tree | 8c7b7eb1e0e6bf6b34d41110d990f5dca6c4f6f4 |
| parent | 0d10ab0680c8cd0c75bf6f6cc7d4a153ac742db8 |
| signature | Commit is signed but in an unrecognized format. |
9 files changed, 90 insertions(+), 66 deletions(-)
src/all_types.hpp+1| ... | ... | @@ -1851,6 +1851,7 @@ struct CodeGen { |
| 1851 | 1851 | ZigPackage *root_package; |
| 1852 | 1852 | Buf *zig_lib_dir; |
| 1853 | 1853 | Buf *zig_std_dir; |
| 1854 | Buf *dynamic_linker_path; | |
| 1854 | 1855 | |
| 1855 | 1856 | const char **llvm_argv; |
| 1856 | 1857 | size_t llvm_argv_len; |
src/codegen.cpp+51-1| ... | ... | @@ -257,6 +257,10 @@ void codegen_set_out_name(CodeGen *g, Buf *out_name) { |
| 257 | 257 | g->root_out_name = out_name; |
| 258 | 258 | } |
| 259 | 259 | |
| 260 | void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker_path) { | |
| 261 | g->dynamic_linker_path = dynamic_linker_path; | |
| 262 | } | |
| 263 | ||
| 260 | 264 | void codegen_add_lib_dir(CodeGen *g, const char *dir) { |
| 261 | 265 | g->lib_dirs.append(dir); |
| 262 | 266 | } |
| ... | ... | @@ -7908,6 +7912,51 @@ static void init(CodeGen *g) { |
| 7908 | 7912 | } |
| 7909 | 7913 | } |
| 7910 | 7914 | |
| 7915 | static 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 | ||
| 7911 | 7960 | static void detect_libc(CodeGen *g) { |
| 7912 | 7961 | Error err; |
| 7913 | 7962 | |
| ... | ... | @@ -9029,8 +9078,8 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 9029 | 9078 | cache_buf(ch, &g->libc->crt_dir); |
| 9030 | 9079 | cache_buf(ch, &g->libc->msvc_lib_dir); |
| 9031 | 9080 | cache_buf(ch, &g->libc->kernel32_lib_dir); |
| 9032 | cache_buf(ch, &g->libc->dynamic_linker_path); | |
| 9033 | 9081 | } |
| 9082 | cache_buf(ch, g->dynamic_linker_path); | |
| 9034 | 9083 | |
| 9035 | 9084 | gen_c_objects(g); |
| 9036 | 9085 | |
| ... | ... | @@ -9132,6 +9181,7 @@ void codegen_build_and_link(CodeGen *g) { |
| 9132 | 9181 | assert(g->out_type != OutTypeUnknown); |
| 9133 | 9182 | |
| 9134 | 9183 | detect_libc(g); |
| 9184 | detect_dynamic_linker(g); | |
| 9135 | 9185 | |
| 9136 | 9186 | Buf *artifact_dir = buf_alloc(); |
| 9137 | 9187 | Buf digest = BUF_INIT; |
src/codegen.hpp+1| ... | ... | @@ -29,6 +29,7 @@ void codegen_set_is_static(CodeGen *codegen, bool is_static); |
| 29 | 29 | void codegen_set_strip(CodeGen *codegen, bool strip); |
| 30 | 30 | void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color); |
| 31 | 31 | void codegen_set_out_name(CodeGen *codegen, Buf *out_name); |
| 32 | void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker); | |
| 32 | 33 | void codegen_add_lib_dir(CodeGen *codegen, const char *dir); |
| 33 | 34 | void codegen_add_forbidden_lib(CodeGen *codegen, Buf *lib); |
| 34 | 35 | LinkLib *codegen_add_link_lib(CodeGen *codegen, Buf *lib); |
src/compiler.cpp+15-1| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | #include "cache_hash.hpp" |
| 2 | #include "os.hpp" | |
| 2 | 3 | |
| 3 | 4 | #include <stdio.h> |
| 4 | 5 | |
| ... | ... | @@ -8,8 +9,9 @@ static Buf saved_stage1_path = BUF_INIT; |
| 8 | 9 | static Buf saved_lib_dir = BUF_INIT; |
| 9 | 10 | static Buf saved_special_dir = BUF_INIT; |
| 10 | 11 | static Buf saved_std_dir = BUF_INIT; |
| 12 | static Buf saved_dynamic_linker_path = BUF_INIT; | |
| 11 | 13 | |
| 12 | Buf *get_stage1_cache_path() { | |
| 14 | Buf *get_stage1_cache_path(void) { | |
| 13 | 15 | if (saved_stage1_path.list.length != 0) { |
| 14 | 16 | return &saved_stage1_path; |
| 15 | 17 | } |
| ... | ... | @@ -57,6 +59,13 @@ Error get_compiler_id(Buf **result) { |
| 57 | 59 | Buf *lib_path = lib_paths.at(i); |
| 58 | 60 | if ((err = cache_add_file(ch, lib_path))) |
| 59 | 61 | 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 | |
| 60 | 69 | } |
| 61 | 70 | if ((err = cache_final(ch, &saved_compiler_id))) |
| 62 | 71 | return err; |
| ... | ... | @@ -67,6 +76,11 @@ Error get_compiler_id(Buf **result) { |
| 67 | 76 | return ErrorNone; |
| 68 | 77 | } |
| 69 | 78 | |
| 79 | Buf *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 | } | |
| 70 | 84 | |
| 71 | 85 | static bool test_zig_install_prefix(Buf *test_path, Buf *out_zig_lib_dir) { |
| 72 | 86 | Buf lib_buf = BUF_INIT; |
src/compiler.hpp+5-4| ... | ... | @@ -11,11 +11,12 @@ |
| 11 | 11 | #include "buffer.hpp" |
| 12 | 12 | #include "error.hpp" |
| 13 | 13 | |
| 14 | Buf *get_stage1_cache_path(); | |
| 14 | Buf *get_stage1_cache_path(void); | |
| 15 | 15 | Error get_compiler_id(Buf **result); |
| 16 | Buf *get_self_dynamic_linker_path(void); | |
| 16 | 17 | |
| 17 | Buf *get_zig_lib_dir(); | |
| 18 | Buf *get_zig_special_dir(); | |
| 19 | Buf *get_zig_std_dir(); | |
| 18 | Buf *get_zig_lib_dir(void); | |
| 19 | Buf *get_zig_special_dir(void); | |
| 20 | Buf *get_zig_std_dir(void); | |
| 20 | 21 | |
| 21 | 22 | #endif |
src/libc_installation.cpp+4-49| ... | ... | @@ -16,7 +16,6 @@ static const char *zig_libc_keys[] = { |
| 16 | 16 | "crt_dir", |
| 17 | 17 | "msvc_lib_dir", |
| 18 | 18 | "kernel32_lib_dir", |
| 19 | "dynamic_linker_path", | |
| 20 | 19 | }; |
| 21 | 20 | |
| 22 | 21 | static const size_t zig_libc_keys_len = array_length(zig_libc_keys); |
| ... | ... | @@ -37,7 +36,6 @@ static void zig_libc_init_empty(ZigLibCInstallation *libc) { |
| 37 | 36 | buf_init_from_str(&libc->crt_dir, ""); |
| 38 | 37 | buf_init_from_str(&libc->msvc_lib_dir, ""); |
| 39 | 38 | buf_init_from_str(&libc->kernel32_lib_dir, ""); |
| 40 | buf_init_from_str(&libc->dynamic_linker_path, ""); | |
| 41 | 39 | } |
| 42 | 40 | |
| 43 | 41 | Error 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 |
| 78 | 76 | match = match || zig_libc_match_key(name, value, found_keys, 2, &libc->crt_dir); |
| 79 | 77 | match = match || zig_libc_match_key(name, value, found_keys, 3, &libc->msvc_lib_dir); |
| 80 | 78 | 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); | |
| 82 | 79 | } |
| 83 | 80 | |
| 84 | 81 | 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 |
| 131 | 128 | } |
| 132 | 129 | } |
| 133 | 130 | |
| 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 | ||
| 143 | 131 | return ErrorNone; |
| 144 | 132 | } |
| 145 | 133 | |
| ... | ... | @@ -301,8 +289,8 @@ static Error zig_libc_find_native_include_dir_posix(ZigLibCInstallation *self, b |
| 301 | 289 | } |
| 302 | 290 | return ErrorFileNotFound; |
| 303 | 291 | } |
| 304 | #if !defined(ZIG_OS_DARWIN) && !defined(ZIG_OS_FREEBSD) && !defined(ZIG_OS_NETBSD) | |
| 305 | static Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose) { | |
| 292 | #if defined(ZIG_OS_LINUX) | |
| 293 | Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose) { | |
| 306 | 294 | const char *cc_exe = getenv("CC"); |
| 307 | 295 | cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe; |
| 308 | 296 | ZigList<const char *> args = {}; |
| ... | ... | @@ -340,32 +328,6 @@ static Error zig_libc_find_native_crt_dir_posix(ZigLibCInstallation *self, bool |
| 340 | 328 | return zig_libc_cc_print_file_name("crt1.o", &self->crt_dir, true, verbose); |
| 341 | 329 | } |
| 342 | 330 | #endif |
| 343 | ||
| 344 | static 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 | } | |
| 369 | 331 | #endif |
| 370 | 332 | |
| 371 | 333 | void zig_libc_render(ZigLibCInstallation *self, FILE *file) { |
| ... | ... | @@ -391,17 +353,12 @@ void zig_libc_render(ZigLibCInstallation *self, FILE *file) { |
| 391 | 353 | "# Only needed when targeting Windows.\n" |
| 392 | 354 | "kernel32_lib_dir=%s\n" |
| 393 | 355 | "\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" | |
| 398 | 356 | , |
| 399 | 357 | buf_ptr(&self->include_dir), |
| 400 | 358 | buf_ptr(&self->sys_include_dir), |
| 401 | 359 | buf_ptr(&self->crt_dir), |
| 402 | 360 | 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) | |
| 405 | 362 | ); |
| 406 | 363 | } |
| 407 | 364 | |
| ... | ... | @@ -438,12 +395,10 @@ Error zig_libc_find_native(ZigLibCInstallation *self, bool verbose) { |
| 438 | 395 | return err; |
| 439 | 396 | #if defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) |
| 440 | 397 | buf_init_from_str(&self->crt_dir, "/usr/lib"); |
| 441 | #elif !defined(ZIG_OS_DARWIN) | |
| 398 | #elif defined(ZIG_OS_LINUX) | |
| 442 | 399 | if ((err = zig_libc_find_native_crt_dir_posix(self, verbose))) |
| 443 | 400 | return err; |
| 444 | 401 | #endif |
| 445 | if ((err = zig_libc_find_native_dynamic_linker_posix(self, verbose))) | |
| 446 | return err; | |
| 447 | 402 | return ErrorNone; |
| 448 | 403 | #endif |
| 449 | 404 | } |
src/libc_installation.hpp+4-1| ... | ... | @@ -21,7 +21,6 @@ struct ZigLibCInstallation { |
| 21 | 21 | Buf crt_dir; |
| 22 | 22 | Buf msvc_lib_dir; |
| 23 | 23 | Buf kernel32_lib_dir; |
| 24 | Buf dynamic_linker_path; | |
| 25 | 24 | }; |
| 26 | 25 | |
| 27 | 26 | Error ATTRIBUTE_MUST_USE zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, |
| ... | ... | @@ -30,4 +29,8 @@ void zig_libc_render(ZigLibCInstallation *self, FILE *file); |
| 30 | 29 | |
| 31 | 30 | Error ATTRIBUTE_MUST_USE zig_libc_find_native(ZigLibCInstallation *self, bool verbose); |
| 32 | 31 | |
| 32 | #if defined(ZIG_OS_LINUX) | |
| 33 | Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose); | |
| 34 | #endif | |
| 35 | ||
| 33 | 36 | #endif |
src/link.cpp+3-9| ... | ... | @@ -517,14 +517,9 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 517 | 517 | } |
| 518 | 518 | |
| 519 | 519 | 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)); | |
| 528 | 523 | } |
| 529 | 524 | |
| 530 | 525 | } |
| ... | ... | @@ -545,7 +540,6 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 545 | 540 | lj->args.append(buf_ptr(builtin_a_path)); |
| 546 | 541 | } |
| 547 | 542 | |
| 548 | // sometimes libgcc is missing stuff, so we still build compiler_rt and rely on weak linkage | |
| 549 | 543 | Buf *compiler_rt_o_path = build_compiler_rt(g); |
| 550 | 544 | lj->args.append(buf_ptr(compiler_rt_o_path)); |
| 551 | 545 | } |
src/main.cpp+6-1| ... | ... | @@ -166,7 +166,7 @@ static int print_target_list(FILE *f) { |
| 166 | 166 | SubArchList sub_arch_list = target_subarch_list(arch); |
| 167 | 167 | size_t sub_count = target_subarch_count(sub_arch_list); |
| 168 | 168 | 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); | |
| 170 | 170 | for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) { |
| 171 | 171 | ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i); |
| 172 | 172 | const char *sub_name = target_subarch_name(sub); |
| ... | ... | @@ -406,6 +406,7 @@ int main(int argc, char **argv) { |
| 406 | 406 | bool verbose_cc = false; |
| 407 | 407 | ErrColor color = ErrColorAuto; |
| 408 | 408 | CacheOpt enable_cache = CacheOptAuto; |
| 409 | const char *dynamic_linker = nullptr; | |
| 409 | 410 | const char *libc_txt = nullptr; |
| 410 | 411 | ZigList<const char *> clang_argv = {0}; |
| 411 | 412 | ZigList<const char *> llvm_argv = {0}; |
| ... | ... | @@ -715,6 +716,8 @@ int main(int argc, char **argv) { |
| 715 | 716 | } |
| 716 | 717 | } else if (strcmp(arg, "--name") == 0) { |
| 717 | 718 | out_name = argv[i]; |
| 719 | } else if (strcmp(arg, "--dynamic-linker") == 0) { | |
| 720 | dynamic_linker = argv[i]; | |
| 718 | 721 | } else if (strcmp(arg, "--libc") == 0) { |
| 719 | 722 | libc_txt = argv[i]; |
| 720 | 723 | } else if (strcmp(arg, "-isystem") == 0) { |
| ... | ... | @@ -1027,6 +1030,8 @@ int main(int argc, char **argv) { |
| 1027 | 1030 | codegen_set_llvm_argv(g, llvm_argv.items, llvm_argv.length); |
| 1028 | 1031 | codegen_set_strip(g, strip); |
| 1029 | 1032 | codegen_set_is_static(g, is_static); |
| 1033 | if (dynamic_linker != nullptr) | |
| 1034 | codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker)); | |
| 1030 | 1035 | g->verbose_tokenize = verbose_tokenize; |
| 1031 | 1036 | g->verbose_ast = verbose_ast; |
| 1032 | 1037 | g->verbose_link = verbose_link; |