authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-02 17:29:22-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-02 17:29:22-04:00
log5314641e117f3b3d9cef2db527af532ddf18ccfc
tree736b147b2016cf79979a5bf21923d3fa8c3ee4ed
parentc1778bd41f1fd340662920909fdd9992ac55133e
signaturelock-open Commit is signed but in an unrecognized format.

zig cc: support more linker args


4 files changed, 124 insertions(+), 7 deletions(-)

src/all_types.hpp+11
...@@ -2015,6 +2015,12 @@ enum WantCSanitize {...@@ -2015,6 +2015,12 @@ enum WantCSanitize {
2015 WantCSanitizeEnabled,2015 WantCSanitizeEnabled,
2016};2016};
20172017
2018enum OptionalBool {
2019 OptionalBoolNull,
2020 OptionalBoolFalse,
2021 OptionalBoolTrue,
2022};
2023
2018struct CFile {2024struct CFile {
2019 ZigList<const char *> args;2025 ZigList<const char *> args;
2020 const char *source_path;2026 const char *source_path;
...@@ -2260,6 +2266,8 @@ struct CodeGen {...@@ -2260,6 +2266,8 @@ struct CodeGen {
2260 TargetSubsystem subsystem; // careful using this directly; see detect_subsystem2266 TargetSubsystem subsystem; // careful using this directly; see detect_subsystem
2261 ValgrindSupport valgrind_support;2267 ValgrindSupport valgrind_support;
2262 CodeModel code_model;2268 CodeModel code_model;
2269 OptionalBool linker_gc_sections;
2270 OptionalBool linker_allow_shlib_undefined;
2263 bool strip_debug_symbols;2271 bool strip_debug_symbols;
2264 bool is_test_build;2272 bool is_test_build;
2265 bool is_single_threaded;2273 bool is_single_threaded;
...@@ -2280,6 +2288,8 @@ struct CodeGen {...@@ -2280,6 +2288,8 @@ struct CodeGen {
2280 bool emit_asm;2288 bool emit_asm;
2281 bool emit_llvm_ir;2289 bool emit_llvm_ir;
2282 bool test_is_evented;2290 bool test_is_evented;
2291 bool linker_z_nodelete;
2292 bool linker_z_defs;
22832293
2284 Buf *root_out_name;2294 Buf *root_out_name;
2285 Buf *test_filter;2295 Buf *test_filter;
...@@ -2288,6 +2298,7 @@ struct CodeGen {...@@ -2288,6 +2298,7 @@ struct CodeGen {
2288 Buf *zig_std_dir;2298 Buf *zig_std_dir;
2289 Buf *version_script_path;2299 Buf *version_script_path;
2290 Buf *override_soname;2300 Buf *override_soname;
2301 Buf *linker_optimization;
22912302
2292 const char **llvm_argv;2303 const char **llvm_argv;
2293 size_t llvm_argv_len;2304 size_t llvm_argv_len;
src/codegen.cpp+5
...@@ -10558,6 +10558,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -10558,6 +10558,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
10558 }10558 }
10559 cache_buf_opt(ch, g->version_script_path);10559 cache_buf_opt(ch, g->version_script_path);
10560 cache_buf_opt(ch, g->override_soname);10560 cache_buf_opt(ch, g->override_soname);
10561 cache_buf_opt(ch, g->linker_optimization);
10562 cache_int(ch, g->linker_gc_sections);
10563 cache_int(ch, g->linker_allow_shlib_undefined);
10564 cache_bool(ch, g->linker_z_nodelete);
10565 cache_bool(ch, g->linker_z_defs);
1056110566
10562 // gen_c_objects appends objects to g->link_objects which we want to include in the hash10567 // gen_c_objects appends objects to g->link_objects which we want to include in the hash
10563 gen_c_objects(g);10568 gen_c_objects(g);
src/link.cpp+73-7
...@@ -1769,8 +1769,17 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1769,8 +1769,17 @@ static void construct_linker_job_elf(LinkJob *lj) {
1769 lj->args.append(g->linker_script);1769 lj->args.append(g->linker_script);
1770 }1770 }
17711771
1772 if (g->out_type != OutTypeObj) {1772 switch (g->linker_gc_sections) {
1773 lj->args.append("--gc-sections");1773 case OptionalBoolNull:
1774 if (g->out_type != OutTypeObj) {
1775 lj->args.append("--gc-sections");
1776 }
1777 break;
1778 case OptionalBoolTrue:
1779 lj->args.append("--gc-sections");
1780 break;
1781 case OptionalBoolFalse:
1782 break;
1774 }1783 }
17751784
1776 if (g->link_eh_frame_hdr) {1785 if (g->link_eh_frame_hdr) {
...@@ -1781,6 +1790,19 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1781,6 +1790,19 @@ static void construct_linker_job_elf(LinkJob *lj) {
1781 lj->args.append("--export-dynamic");1790 lj->args.append("--export-dynamic");
1782 }1791 }
17831792
1793 if (g->linker_optimization != nullptr) {
1794 lj->args.append(buf_ptr(g->linker_optimization));
1795 }
1796
1797 if (g->linker_z_nodelete) {
1798 lj->args.append("-z");
1799 lj->args.append("nodelete");
1800 }
1801 if (g->linker_z_defs) {
1802 lj->args.append("-z");
1803 lj->args.append("defs");
1804 }
1805
1784 lj->args.append("-m");1806 lj->args.append("-m");
1785 lj->args.append(getLDMOption(g->zig_target));1807 lj->args.append(getLDMOption(g->zig_target));
17861808
...@@ -1971,8 +1993,17 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1971,8 +1993,17 @@ static void construct_linker_job_elf(LinkJob *lj) {
1971 }1993 }
1972 }1994 }
19731995
1974 if (!g->zig_target->is_native_os) {1996 switch (g->linker_allow_shlib_undefined) {
1975 lj->args.append("--allow-shlib-undefined");1997 case OptionalBoolNull:
1998 if (!g->zig_target->is_native_os) {
1999 lj->args.append("--allow-shlib-undefined");
2000 }
2001 break;
2002 case OptionalBoolFalse:
2003 break;
2004 case OptionalBoolTrue:
2005 lj->args.append("--allow-shlib-undefined");
2006 break;
1976 }2007 }
1977}2008}
19782009
...@@ -2536,10 +2567,34 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -2536,10 +2567,34 @@ static void construct_linker_job_macho(LinkJob *lj) {
2536 //lj->args.append("-error-limit=0");2567 //lj->args.append("-error-limit=0");
2537 lj->args.append("-demangle");2568 lj->args.append("-demangle");
25382569
2570 switch (g->linker_gc_sections) {
2571 case OptionalBoolNull:
2572 // TODO why do we not follow the same logic of elf here?
2573 break;
2574 case OptionalBoolTrue:
2575 lj->args.append("--gc-sections");
2576 break;
2577 case OptionalBoolFalse:
2578 break;
2579 }
2580
2539 if (g->linker_rdynamic) {2581 if (g->linker_rdynamic) {
2540 lj->args.append("-export_dynamic");2582 lj->args.append("-export_dynamic");
2541 }2583 }
25422584
2585 if (g->linker_optimization != nullptr) {
2586 lj->args.append(buf_ptr(g->linker_optimization));
2587 }
2588
2589 if (g->linker_z_nodelete) {
2590 lj->args.append("-z");
2591 lj->args.append("nodelete");
2592 }
2593 if (g->linker_z_defs) {
2594 lj->args.append("-z");
2595 lj->args.append("defs");
2596 }
2597
2543 bool is_lib = g->out_type == OutTypeLib;2598 bool is_lib = g->out_type == OutTypeLib;
2544 bool is_dyn_lib = g->is_dynamic && is_lib;2599 bool is_dyn_lib = g->is_dynamic && is_lib;
2545 if (is_lib && !g->is_dynamic) {2600 if (is_lib && !g->is_dynamic) {
...@@ -2654,9 +2709,20 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -2654,9 +2709,20 @@ static void construct_linker_job_macho(LinkJob *lj) {
2654 // and change between versions.2709 // and change between versions.
2655 // so we always link against libSystem2710 // so we always link against libSystem
2656 lj->args.append("-lSystem");2711 lj->args.append("-lSystem");
2657 } else {2712 }
2658 lj->args.append("-undefined");2713 switch (g->linker_allow_shlib_undefined) {
2659 lj->args.append("dynamic_lookup");2714 case OptionalBoolNull:
2715 if (!g->zig_target->is_native_os) {
2716 lj->args.append("-undefined");
2717 lj->args.append("dynamic_lookup");
2718 }
2719 break;
2720 case OptionalBoolFalse:
2721 break;
2722 case OptionalBoolTrue:
2723 lj->args.append("-undefined");
2724 lj->args.append("dynamic_lookup");
2725 break;
2660 }2726 }
26612727
2662 for (size_t i = 0; i < g->framework_dirs.length; i += 1) {2728 for (size_t i = 0; i < g->framework_dirs.length; i += 1) {
src/main.cpp+35
...@@ -459,6 +459,11 @@ static int main0(int argc, char **argv) {...@@ -459,6 +459,11 @@ static int main0(int argc, char **argv) {
459 bool ensure_libc_on_non_freestanding = false;459 bool ensure_libc_on_non_freestanding = false;
460 bool ensure_libcpp_on_non_freestanding = false;460 bool ensure_libcpp_on_non_freestanding = false;
461 bool disable_c_depfile = false;461 bool disable_c_depfile = false;
462 Buf *linker_optimization = nullptr;
463 OptionalBool linker_gc_sections = OptionalBoolNull;
464 OptionalBool linker_allow_shlib_undefined = OptionalBoolNull;
465 bool linker_z_nodelete = false;
466 bool linker_z_defs = false;
462467
463 ZigList<const char *> llvm_argv = {0};468 ZigList<const char *> llvm_argv = {0};
464 llvm_argv.append("zig (LLVM option parsing)");469 llvm_argv.append("zig (LLVM option parsing)");
...@@ -822,6 +827,30 @@ static int main0(int argc, char **argv) {...@@ -822,6 +827,30 @@ static int main0(int argc, char **argv) {
822 return EXIT_FAILURE;827 return EXIT_FAILURE;
823 }828 }
824 version_script = linker_args.at(i);829 version_script = linker_args.at(i);
830 } else if (buf_starts_with_str(arg, "-O")) {
831 linker_optimization = arg;
832 } else if (buf_eql_str(arg, "--gc-sections")) {
833 linker_gc_sections = OptionalBoolTrue;
834 } else if (buf_eql_str(arg, "--no-gc-sections")) {
835 linker_gc_sections = OptionalBoolFalse;
836 } else if (buf_eql_str(arg, "--allow-shlib-undefined")) {
837 linker_allow_shlib_undefined = OptionalBoolTrue;
838 } else if (buf_eql_str(arg, "--no-allow-shlib-undefined")) {
839 linker_allow_shlib_undefined = OptionalBoolFalse;
840 } else if (buf_eql_str(arg, "-z")) {
841 i += 1;
842 if (i >= linker_args.length) {
843 fprintf(stderr, "expected linker arg after '%s'\n", buf_ptr(arg));
844 return EXIT_FAILURE;
845 }
846 Buf *z_arg = linker_args.at(i);
847 if (buf_eql_str(z_arg, "nodelete")) {
848 linker_z_nodelete = true;
849 } else if (buf_eql_str(z_arg, "defs")) {
850 linker_z_defs = true;
851 } else {
852 fprintf(stderr, "warning: unsupported linker arg: -z %s\n", buf_ptr(z_arg));
853 }
825 } else {854 } else {
826 fprintf(stderr, "warning: unsupported linker arg: %s\n", buf_ptr(arg));855 fprintf(stderr, "warning: unsupported linker arg: %s\n", buf_ptr(arg));
827 }856 }
...@@ -1542,6 +1571,12 @@ static int main0(int argc, char **argv) {...@@ -1542,6 +1571,12 @@ static int main0(int argc, char **argv) {
1542 g->code_model = code_model;1571 g->code_model = code_model;
1543 g->disable_c_depfile = disable_c_depfile;1572 g->disable_c_depfile = disable_c_depfile;
15441573
1574 g->linker_optimization = linker_optimization;
1575 g->linker_gc_sections = linker_gc_sections;
1576 g->linker_allow_shlib_undefined = linker_allow_shlib_undefined;
1577 g->linker_z_nodelete = linker_z_nodelete;
1578 g->linker_z_defs = linker_z_defs;
1579
1545 if (override_soname) {1580 if (override_soname) {
1546 g->override_soname = buf_create_from_str(override_soname);1581 g->override_soname = buf_create_from_str(override_soname);
1547 }1582 }