authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-10-09 12:18:09-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-10-09 13:16:50-04:00
log6b93495792678bd00a6205967bb2704a9a35e9c7
tree9dd12653140fd7943c7d09dce22b0367a0caa73c
parent5a3c02137e6a15d3b8c1fb3595d55003ea44139a
signature Commit is signed but in an unrecognized format.

more efficient builtin library code generation

* 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 printed

5 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;
17661767
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;
72307230
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;
72327235
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)
4444
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;
4748
48 codegen_set_out_name(child_gen, buf_create_from_str(aname));49 codegen_set_out_name(child_gen, buf_create_from_str(aname));
4950
...@@ -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));
210211
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 }
289289
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 }
311311
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) {
339339
340 // libc dep340 // 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 }
542542
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 }
873873
874 // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce874 // 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) {
969969
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);
971971
972 lj.args.append("-error-limit=0");
972 construct_linker_job(&lj);973 construct_linker_job(&lj);
973974
974975
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>
4950
50#endif51#endif
5152
...@@ -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}
8990
90static void os_spawn_process_posix(const char *exe, ZigList<const char *> &args, Termination *term) {91static 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 // child96 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#endif109#endif
112110