| author | |
| committer | |
| log | 6b93495792678bd00a6205967bb2704a9a35e9c7 |
| tree | 9dd12653140fd7943c7d09dce22b0367a0caa73c |
| parent | 5a3c02137e6a15d3b8c1fb3595d55003ea44139a |
| signature | Commit is signed but in an unrecognized format. |
* introduce --disable-pic option which can generally be allowed to be
the default. compiler_rt.a and builtin.a get this option when you
build a static executable.
* compiler_rt and builtin libraries are not built for build-lib
--static
* posix_spawn instead of fork/execv
* disable the error limit on LLD. Fixes the blank lines printed5 files changed, 44 insertions(+), 28 deletions(-)
src/all_types.hpp+1| ... | @@ -1763,6 +1763,7 @@ struct CodeGen { | ... | @@ -1763,6 +1763,7 @@ struct CodeGen { |
| 1763 | bool linker_rdynamic; | 1763 | bool linker_rdynamic; |
| 1764 | bool no_rosegment_workaround; | 1764 | bool no_rosegment_workaround; |
| 1765 | bool each_lib_rpath; | 1765 | bool each_lib_rpath; |
| 1766 | bool disable_pic; | ||
| 1766 | 1767 | ||
| 1767 | Buf *mmacosx_version_min; | 1768 | Buf *mmacosx_version_min; |
| 1768 | Buf *mios_version_min; | 1769 | Buf *mios_version_min; |
src/codegen.cpp+5-1| ... | @@ -7228,7 +7228,10 @@ static void init(CodeGen *g) { | ... | @@ -7228,7 +7228,10 @@ static void init(CodeGen *g) { |
| 7228 | bool is_optimized = g->build_mode != BuildModeDebug; | 7228 | bool is_optimized = g->build_mode != BuildModeDebug; |
| 7229 | LLVMCodeGenOptLevel opt_level = is_optimized ? LLVMCodeGenLevelAggressive : LLVMCodeGenLevelNone; | 7229 | LLVMCodeGenOptLevel opt_level = is_optimized ? LLVMCodeGenLevelAggressive : LLVMCodeGenLevelNone; |
| 7230 | 7230 | ||
| 7231 | LLVMRelocMode reloc_mode = g->is_static ? LLVMRelocStatic : LLVMRelocPIC; | 7231 | if (g->out_type == OutTypeExe && g->is_static) { |
| 7232 | g->disable_pic = true; | ||
| 7233 | } | ||
| 7234 | LLVMRelocMode reloc_mode = g->disable_pic ? LLVMRelocStatic : LLVMRelocPIC; | ||
| 7232 | 7235 | ||
| 7233 | const char *target_specific_cpu_args; | 7236 | const char *target_specific_cpu_args; |
| 7234 | const char *target_specific_features; | 7237 | const char *target_specific_features; |
| ... | @@ -8047,6 +8050,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { | ... | @@ -8047,6 +8050,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 8047 | cache_bool(ch, g->linker_rdynamic); | 8050 | cache_bool(ch, g->linker_rdynamic); |
| 8048 | cache_bool(ch, g->no_rosegment_workaround); | 8051 | cache_bool(ch, g->no_rosegment_workaround); |
| 8049 | cache_bool(ch, g->each_lib_rpath); | 8052 | cache_bool(ch, g->each_lib_rpath); |
| 8053 | cache_bool(ch, g->disable_pic); | ||
| 8050 | cache_buf_opt(ch, g->mmacosx_version_min); | 8054 | cache_buf_opt(ch, g->mmacosx_version_min); |
| 8051 | cache_buf_opt(ch, g->mios_version_min); | 8055 | cache_buf_opt(ch, g->mios_version_min); |
| 8052 | cache_usize(ch, g->version_major); | 8056 | cache_usize(ch, g->version_major); |
src/link.cpp+10-9| ... | @@ -44,6 +44,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path) | ... | @@ -44,6 +44,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path) |
| 44 | 44 | ||
| 45 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); | 45 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); |
| 46 | codegen_set_is_static(child_gen, true); | 46 | codegen_set_is_static(child_gen, true); |
| 47 | child_gen->disable_pic = parent_gen->disable_pic; | ||
| 47 | 48 | ||
| 48 | codegen_set_out_name(child_gen, buf_create_from_str(aname)); | 49 | codegen_set_out_name(child_gen, buf_create_from_str(aname)); |
| 49 | 50 | ||
| ... | @@ -209,10 +210,9 @@ static void construct_linker_job_elf(LinkJob *lj) { | ... | @@ -209,10 +210,9 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 209 | lj->args.append(getLDMOption(&g->zig_target)); | 210 | lj->args.append(getLDMOption(&g->zig_target)); |
| 210 | 211 | ||
| 211 | bool is_lib = g->out_type == OutTypeLib; | 212 | bool is_lib = g->out_type == OutTypeLib; |
| 212 | bool is_static = g->is_static || (!is_lib && g->link_libs_list.length == 0); | 213 | bool shared = !g->is_static && is_lib; |
| 213 | bool shared = !is_static && is_lib; | ||
| 214 | Buf *soname = nullptr; | 214 | Buf *soname = nullptr; |
| 215 | if (is_static) { | 215 | if (g->is_static) { |
| 216 | if (g->zig_target.arch.arch == ZigLLVM_arm || g->zig_target.arch.arch == ZigLLVM_armeb || | 216 | if (g->zig_target.arch.arch == ZigLLVM_arm || g->zig_target.arch.arch == ZigLLVM_armeb || |
| 217 | g->zig_target.arch.arch == ZigLLVM_thumb || g->zig_target.arch.arch == ZigLLVM_thumbeb) | 217 | g->zig_target.arch.arch == ZigLLVM_thumb || g->zig_target.arch.arch == ZigLLVM_thumbeb) |
| 218 | { | 218 | { |
| ... | @@ -236,7 +236,7 @@ static void construct_linker_job_elf(LinkJob *lj) { | ... | @@ -236,7 +236,7 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 236 | if (lj->link_in_crt) { | 236 | if (lj->link_in_crt) { |
| 237 | const char *crt1o; | 237 | const char *crt1o; |
| 238 | const char *crtbegino; | 238 | const char *crtbegino; |
| 239 | if (is_static) { | 239 | if (g->is_static) { |
| 240 | crt1o = "crt1.o"; | 240 | crt1o = "crt1.o"; |
| 241 | crtbegino = "crtbeginT.o"; | 241 | crtbegino = "crtbeginT.o"; |
| 242 | } else { | 242 | } else { |
| ... | @@ -287,7 +287,7 @@ static void construct_linker_job_elf(LinkJob *lj) { | ... | @@ -287,7 +287,7 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 287 | lj->args.append(buf_ptr(g->libc_static_lib_dir)); | 287 | lj->args.append(buf_ptr(g->libc_static_lib_dir)); |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | if (!is_static) { | 290 | if (!g->is_static) { |
| 291 | if (g->dynamic_linker != nullptr) { | 291 | if (g->dynamic_linker != nullptr) { |
| 292 | assert(buf_len(g->dynamic_linker) != 0); | 292 | assert(buf_len(g->dynamic_linker) != 0); |
| 293 | lj->args.append("-dynamic-linker"); | 293 | lj->args.append("-dynamic-linker"); |
| ... | @@ -309,7 +309,7 @@ static void construct_linker_job_elf(LinkJob *lj) { | ... | @@ -309,7 +309,7 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 309 | lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); | 309 | lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); |
| 310 | } | 310 | } |
| 311 | 311 | ||
| 312 | if (g->out_type == OutTypeExe || g->out_type == OutTypeLib) { | 312 | if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && !g->is_static)) { |
| 313 | if (g->libc_link_lib == nullptr) { | 313 | if (g->libc_link_lib == nullptr) { |
| 314 | Buf *builtin_a_path = build_a(g, "builtin"); | 314 | Buf *builtin_a_path = build_a(g, "builtin"); |
| 315 | lj->args.append(buf_ptr(builtin_a_path)); | 315 | lj->args.append(buf_ptr(builtin_a_path)); |
| ... | @@ -339,7 +339,7 @@ static void construct_linker_job_elf(LinkJob *lj) { | ... | @@ -339,7 +339,7 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 339 | 339 | ||
| 340 | // libc dep | 340 | // libc dep |
| 341 | if (g->libc_link_lib != nullptr) { | 341 | if (g->libc_link_lib != nullptr) { |
| 342 | if (is_static) { | 342 | if (g->is_static) { |
| 343 | lj->args.append("--start-group"); | 343 | lj->args.append("--start-group"); |
| 344 | lj->args.append("-lgcc"); | 344 | lj->args.append("-lgcc"); |
| 345 | lj->args.append("-lgcc_eh"); | 345 | lj->args.append("-lgcc_eh"); |
| ... | @@ -540,7 +540,7 @@ static void construct_linker_job_coff(LinkJob *lj) { | ... | @@ -540,7 +540,7 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 540 | lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); | 540 | lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); |
| 541 | } | 541 | } |
| 542 | 542 | ||
| 543 | if (g->out_type == OutTypeExe || g->out_type == OutTypeLib) { | 543 | if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && !g->is_static)) { |
| 544 | if (g->libc_link_lib == nullptr) { | 544 | if (g->libc_link_lib == nullptr) { |
| 545 | Buf *builtin_a_path = build_a(g, "builtin"); | 545 | Buf *builtin_a_path = build_a(g, "builtin"); |
| 546 | lj->args.append(buf_ptr(builtin_a_path)); | 546 | lj->args.append(buf_ptr(builtin_a_path)); |
| ... | @@ -872,7 +872,7 @@ static void construct_linker_job_macho(LinkJob *lj) { | ... | @@ -872,7 +872,7 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 872 | } | 872 | } |
| 873 | 873 | ||
| 874 | // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce | 874 | // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce |
| 875 | if (g->out_type == OutTypeExe || g->out_type == OutTypeLib) { | 875 | if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && !g->is_static)) { |
| 876 | Buf *compiler_rt_o_path = build_compiler_rt(g); | 876 | Buf *compiler_rt_o_path = build_compiler_rt(g); |
| 877 | lj->args.append(buf_ptr(compiler_rt_o_path)); | 877 | lj->args.append(buf_ptr(compiler_rt_o_path)); |
| 878 | } | 878 | } |
| ... | @@ -969,6 +969,7 @@ void codegen_link(CodeGen *g) { | ... | @@ -969,6 +969,7 @@ void codegen_link(CodeGen *g) { |
| 969 | 969 | ||
| 970 | lj.link_in_crt = (g->libc_link_lib != nullptr && g->out_type == OutTypeExe); | 970 | lj.link_in_crt = (g->libc_link_lib != nullptr && g->out_type == OutTypeExe); |
| 971 | 971 | ||
| 972 | lj.args.append("-error-limit=0"); | ||
| 972 | construct_linker_job(&lj); | 973 | construct_linker_job(&lj); |
| 973 | 974 | ||
| 974 | 975 |
src/main.cpp+12| ... | @@ -47,6 +47,7 @@ static int print_full_usage(const char *arg0) { | ... | @@ -47,6 +47,7 @@ static int print_full_usage(const char *arg0) { |
| 47 | " --cache-dir [path] override the cache directory\n" | 47 | " --cache-dir [path] override the cache directory\n" |
| 48 | " --cache [auto|off|on] build in global cache, print out paths to stdout\n" | 48 | " --cache [auto|off|on] build in global cache, print out paths to stdout\n" |
| 49 | " --color [auto|off|on] enable or disable colored error messages\n" | 49 | " --color [auto|off|on] enable or disable colored error messages\n" |
| 50 | " --disable-pic disable Position Independent Code for libraries\n" | ||
| 50 | " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n" | 51 | " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n" |
| 51 | " -ftime-report print timing diagnostics\n" | 52 | " -ftime-report print timing diagnostics\n" |
| 52 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" | 53 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" |
| ... | @@ -386,6 +387,7 @@ int main(int argc, char **argv) { | ... | @@ -386,6 +387,7 @@ int main(int argc, char **argv) { |
| 386 | size_t ver_minor = 0; | 387 | size_t ver_minor = 0; |
| 387 | size_t ver_patch = 0; | 388 | size_t ver_patch = 0; |
| 388 | bool timing_info = false; | 389 | bool timing_info = false; |
| 390 | bool disable_pic = false; | ||
| 389 | const char *cache_dir = nullptr; | 391 | const char *cache_dir = nullptr; |
| 390 | CliPkg *cur_pkg = allocate<CliPkg>(1); | 392 | CliPkg *cur_pkg = allocate<CliPkg>(1); |
| 391 | BuildMode build_mode = BuildModeDebug; | 393 | BuildMode build_mode = BuildModeDebug; |
| ... | @@ -556,6 +558,8 @@ int main(int argc, char **argv) { | ... | @@ -556,6 +558,8 @@ int main(int argc, char **argv) { |
| 556 | each_lib_rpath = true; | 558 | each_lib_rpath = true; |
| 557 | } else if (strcmp(arg, "-ftime-report") == 0) { | 559 | } else if (strcmp(arg, "-ftime-report") == 0) { |
| 558 | timing_info = true; | 560 | timing_info = true; |
| 561 | } else if (strcmp(arg, "--disable-pic") == 0) { | ||
| 562 | disable_pic = true; | ||
| 559 | } else if (strcmp(arg, "--test-cmd-bin") == 0) { | 563 | } else if (strcmp(arg, "--test-cmd-bin") == 0) { |
| 560 | test_exec_args.append(nullptr); | 564 | test_exec_args.append(nullptr); |
| 561 | } else if (arg[1] == 'L' && arg[2] != 0) { | 565 | } else if (arg[1] == 'L' && arg[2] != 0) { |
| ... | @@ -849,6 +853,14 @@ int main(int argc, char **argv) { | ... | @@ -849,6 +853,14 @@ int main(int argc, char **argv) { |
| 849 | buf_out_name = buf_create_from_str("run"); | 853 | buf_out_name = buf_create_from_str("run"); |
| 850 | } | 854 | } |
| 851 | CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir()); | 855 | CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir()); |
| 856 | if (disable_pic) { | ||
| 857 | if (out_type != OutTypeLib || !is_static) { | ||
| 858 | fprintf(stderr, "--disable-pic only applies to static libraries"); | ||
| 859 | return EXIT_FAILURE; | ||
| 860 | } | ||
| 861 | g->disable_pic = true; | ||
| 862 | } | ||
| 863 | |||
| 852 | g->enable_time_report = timing_info; | 864 | g->enable_time_report = timing_info; |
| 853 | buf_init_from_str(&g->cache_dir, cache_dir ? cache_dir : default_zig_cache_name); | 865 | buf_init_from_str(&g->cache_dir, cache_dir ? cache_dir : default_zig_cache_name); |
| 854 | codegen_set_out_name(g, buf_out_name); | 866 | codegen_set_out_name(g, buf_out_name); |
src/os.cpp+16-18| ... | @@ -46,6 +46,7 @@ typedef SSIZE_T ssize_t; | ... | @@ -46,6 +46,7 @@ typedef SSIZE_T ssize_t; |
| 46 | #include <sys/wait.h> | 46 | #include <sys/wait.h> |
| 47 | #include <fcntl.h> | 47 | #include <fcntl.h> |
| 48 | #include <limits.h> | 48 | #include <limits.h> |
| 49 | #include <spawn.h> | ||
| 49 | 50 | ||
| 50 | #endif | 51 | #endif |
| 51 | 52 | ||
| ... | @@ -88,25 +89,22 @@ static void populate_termination(Termination *term, int status) { | ... | @@ -88,25 +89,22 @@ static void populate_termination(Termination *term, int status) { |
| 88 | } | 89 | } |
| 89 | 90 | ||
| 90 | static void os_spawn_process_posix(const char *exe, ZigList<const char *> &args, Termination *term) { | 91 | static void os_spawn_process_posix(const char *exe, ZigList<const char *> &args, Termination *term) { |
| 91 | pid_t pid = fork(); | 92 | const char **argv = allocate<const char *>(args.length + 2); |
| 92 | if (pid == -1) | 93 | argv[0] = exe; |
| 93 | zig_panic("fork failed: %s", strerror(errno)); | 94 | argv[args.length + 1] = nullptr; |
| 94 | if (pid == 0) { | 95 | for (size_t i = 0; i < args.length; i += 1) { |
| 95 | // child | 96 | argv[i + 1] = args.at(i); |
| 96 | const char **argv = allocate<const char *>(args.length + 2); | ||
| 97 | argv[0] = exe; | ||
| 98 | argv[args.length + 1] = nullptr; | ||
| 99 | for (size_t i = 0; i < args.length; i += 1) { | ||
| 100 | argv[i + 1] = args.at(i); | ||
| 101 | } | ||
| 102 | execvp(exe, const_cast<char * const *>(argv)); | ||
| 103 | zig_panic("execvp failed: %s", strerror(errno)); | ||
| 104 | } else { | ||
| 105 | // parent | ||
| 106 | int status; | ||
| 107 | waitpid(pid, &status, 0); | ||
| 108 | populate_termination(term, status); | ||
| 109 | } | 97 | } |
| 98 | |||
| 99 | pid_t pid; | ||
| 100 | int rc = posix_spawn(&pid, exe, nullptr, nullptr, const_cast<char *const*>(argv), environ); | ||
| 101 | if (rc != 0) { | ||
| 102 | zig_panic("posix_spawn failed: %s", strerror(rc)); | ||
| 103 | } | ||
| 104 | |||
| 105 | int status; | ||
| 106 | waitpid(pid, &status, 0); | ||
| 107 | populate_termination(term, status); | ||
| 110 | } | 108 | } |
| 111 | #endif | 109 | #endif |
| 112 | 110 |