From 6b36b756eb4b4c26b98d405310680ebe5679d111 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 15 May 2019 21:47:15 -0400 Subject: [PATCH] fix static builds of zig from requiring c compiler to be installed when linking libc. When zig links against libc, it requires a dynamic linker path. Usually this can be determined based on the architecture and operating system components of the target. However on some systems this is not correct; because of this zig checks its own dynamic linker. When zig is statically linked, this information is not available, and so it resorts to using cc -print-filename=foo to find the dynamic linker path. Before this commit, Zig incorrectly exited with an error if there was no c compiler installed. Now, Zig falls back to the dynamic linker determined based on the arch and os when no C compiler can be found. --- src/codegen.cpp | 2 +- src/error.cpp | 1 + src/libc_installation.cpp | 2 ++ src/link.cpp | 1 + src/os.cpp | 18 ++++++++++++++---- src/userland.h | 1 + 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 1d7d543a49..ecdee4e9e5 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8121,7 +8121,7 @@ static void detect_dynamic_linker(CodeGen *g) { for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) { const char *lib_name = possible_ld_names[i]; if ((err = zig_libc_cc_print_file_name(lib_name, result, false, true))) { - if (err != ErrorCCompilerCannotFindFile) { + if (err != ErrorCCompilerCannotFindFile && err != ErrorNoCCompilerInstalled) { fprintf(stderr, "Unable to detect native dynamic linker: %s\n", err_str(err)); exit(1); } diff --git a/src/error.cpp b/src/error.cpp index 69676f9cf5..20d429e8bf 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -54,6 +54,7 @@ const char *err_str(Error err) { case ErrorOperationAborted: return "operation aborted"; case ErrorBrokenPipe: return "broken pipe"; case ErrorNoSpaceLeft: return "no space left"; + case ErrorNoCCompilerInstalled: return "no C compiler installed"; } return "(invalid error)"; } diff --git a/src/libc_installation.cpp b/src/libc_installation.cpp index fc51fa427e..d1773b89e7 100644 --- a/src/libc_installation.cpp +++ b/src/libc_installation.cpp @@ -283,6 +283,8 @@ Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirnam Buf *out_stdout = buf_alloc(); Error err; if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) { + if (err == ErrorFileNotFound) + return ErrorNoCCompilerInstalled; if (verbose) { fprintf(stderr, "unable to determine libc library path: executing '%s': %s\n", cc_exe, err_str(err)); } diff --git a/src/link.cpp b/src/link.cpp index 7566838a36..538d663b03 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -34,6 +34,7 @@ static CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, Ou child_gen->verbose_cimport = parent_gen->verbose_cimport; child_gen->verbose_cc = parent_gen->verbose_cc; child_gen->llvm_argv = parent_gen->llvm_argv; + child_gen->dynamic_linker_path = parent_gen->dynamic_linker_path; codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); child_gen->want_pic = parent_gen->have_pic ? WantPICEnabled : WantPICDisabled; diff --git a/src/os.cpp b/src/os.cpp index 83c67d5818..8ab5007d80 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -791,6 +791,7 @@ static Error os_exec_process_posix(const char *exe, ZigList &args, int stdin_pipe[2]; int stdout_pipe[2]; int stderr_pipe[2]; + int err_pipe[2]; int err; if ((err = pipe(stdin_pipe))) @@ -799,6 +800,8 @@ static Error os_exec_process_posix(const char *exe, ZigList &args, zig_panic("pipe failed"); if ((err = pipe(stderr_pipe))) zig_panic("pipe failed"); + if ((err = pipe(err_pipe))) + zig_panic("pipe failed"); pid_t pid = fork(); if (pid == -1) @@ -821,11 +824,12 @@ static Error os_exec_process_posix(const char *exe, ZigList &args, argv[i + 1] = args.at(i); } execvp(exe, const_cast(argv)); + Error report_err = ErrorUnexpected; if (errno == ENOENT) { - return ErrorFileNotFound; - } else { - zig_panic("execvp failed: %s", strerror(errno)); + report_err = ErrorFileNotFound; } + write(err_pipe[1], &report_err, sizeof(Error)); + exit(1); } else { // parent close(stdin_pipe[0]); @@ -847,7 +851,13 @@ static Error os_exec_process_posix(const char *exe, ZigList &args, if (err1) return err1; if (err2) return err2; - return ErrorNone; + + Error child_err = ErrorNone; + write(err_pipe[1], &child_err, sizeof(Error)); + close(err_pipe[1]); + read(err_pipe[0], &child_err, sizeof(Error)); + close(err_pipe[0]); + return child_err; } } #endif diff --git a/src/userland.h b/src/userland.h index e48b80d0c2..d61081c0a0 100644 --- a/src/userland.h +++ b/src/userland.h @@ -56,6 +56,7 @@ enum Error { ErrorCacheUnavailable, ErrorPathTooLong, ErrorCCompilerCannotFindFile, + ErrorNoCCompilerInstalled, ErrorReadingDepFile, ErrorInvalidDepFile, ErrorMissingArchitecture,