| author | |
| committer | |
| log | 5314641e117f3b3d9cef2db527af532ddf18ccfc |
| tree | 736b147b2016cf79979a5bf21923d3fa8c3ee4ed |
| parent | c1778bd41f1fd340662920909fdd9992ac55133e |
| signature |
4 files changed, 124 insertions(+), 7 deletions(-)
src/all_types.hpp+11| ... | ... | @@ -2015,6 +2015,12 @@ enum WantCSanitize { |
| 2015 | 2015 | WantCSanitizeEnabled, |
| 2016 | 2016 | }; |
| 2017 | 2017 | |
| 2018 | enum OptionalBool { | |
| 2019 | OptionalBoolNull, | |
| 2020 | OptionalBoolFalse, | |
| 2021 | OptionalBoolTrue, | |
| 2022 | }; | |
| 2023 | ||
| 2018 | 2024 | struct CFile { |
| 2019 | 2025 | ZigList<const char *> args; |
| 2020 | 2026 | const char *source_path; |
| ... | ... | @@ -2260,6 +2266,8 @@ struct CodeGen { |
| 2260 | 2266 | TargetSubsystem subsystem; // careful using this directly; see detect_subsystem |
| 2261 | 2267 | ValgrindSupport valgrind_support; |
| 2262 | 2268 | CodeModel code_model; |
| 2269 | OptionalBool linker_gc_sections; | |
| 2270 | OptionalBool linker_allow_shlib_undefined; | |
| 2263 | 2271 | bool strip_debug_symbols; |
| 2264 | 2272 | bool is_test_build; |
| 2265 | 2273 | bool is_single_threaded; |
| ... | ... | @@ -2280,6 +2288,8 @@ struct CodeGen { |
| 2280 | 2288 | bool emit_asm; |
| 2281 | 2289 | bool emit_llvm_ir; |
| 2282 | 2290 | bool test_is_evented; |
| 2291 | bool linker_z_nodelete; | |
| 2292 | bool linker_z_defs; | |
| 2283 | 2293 | |
| 2284 | 2294 | Buf *root_out_name; |
| 2285 | 2295 | Buf *test_filter; |
| ... | ... | @@ -2288,6 +2298,7 @@ struct CodeGen { |
| 2288 | 2298 | Buf *zig_std_dir; |
| 2289 | 2299 | Buf *version_script_path; |
| 2290 | 2300 | Buf *override_soname; |
| 2301 | Buf *linker_optimization; | |
| 2291 | 2302 | |
| 2292 | 2303 | const char **llvm_argv; |
| 2293 | 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 | 10558 | } |
| 10559 | 10559 | cache_buf_opt(ch, g->version_script_path); |
| 10560 | 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); | |
| 10561 | 10566 | |
| 10562 | 10567 | // gen_c_objects appends objects to g->link_objects which we want to include in the hash |
| 10563 | 10568 | gen_c_objects(g); |
src/link.cpp+73-7| ... | ... | @@ -1769,8 +1769,17 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1769 | 1769 | lj->args.append(g->linker_script); |
| 1770 | 1770 | } |
| 1771 | 1771 | |
| 1772 | if (g->out_type != OutTypeObj) { | |
| 1773 | lj->args.append("--gc-sections"); | |
| 1772 | switch (g->linker_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 | } |
| 1775 | 1784 | |
| 1776 | 1785 | if (g->link_eh_frame_hdr) { |
| ... | ... | @@ -1781,6 +1790,19 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1781 | 1790 | lj->args.append("--export-dynamic"); |
| 1782 | 1791 | } |
| 1783 | 1792 | |
| 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 | 1806 | lj->args.append("-m"); |
| 1785 | 1807 | lj->args.append(getLDMOption(g->zig_target)); |
| 1786 | 1808 | |
| ... | ... | @@ -1971,8 +1993,17 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1971 | 1993 | } |
| 1972 | 1994 | } |
| 1973 | 1995 | |
| 1974 | if (!g->zig_target->is_native_os) { | |
| 1975 | lj->args.append("--allow-shlib-undefined"); | |
| 1996 | switch (g->linker_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 | } |
| 1978 | 2009 | |
| ... | ... | @@ -2536,10 +2567,34 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 2536 | 2567 | //lj->args.append("-error-limit=0"); |
| 2537 | 2568 | lj->args.append("-demangle"); |
| 2538 | 2569 | |
| 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 | 2581 | if (g->linker_rdynamic) { |
| 2540 | 2582 | lj->args.append("-export_dynamic"); |
| 2541 | 2583 | } |
| 2542 | 2584 | |
| 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 | 2598 | bool is_lib = g->out_type == OutTypeLib; |
| 2544 | 2599 | bool is_dyn_lib = g->is_dynamic && is_lib; |
| 2545 | 2600 | if (is_lib && !g->is_dynamic) { |
| ... | ... | @@ -2654,9 +2709,20 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 2654 | 2709 | // and change between versions. |
| 2655 | 2710 | // so we always link against libSystem |
| 2656 | 2711 | lj->args.append("-lSystem"); |
| 2657 | } else { | |
| 2658 | lj->args.append("-undefined"); | |
| 2659 | lj->args.append("dynamic_lookup"); | |
| 2712 | } | |
| 2713 | switch (g->linker_allow_shlib_undefined) { | |
| 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 | } |
| 2661 | 2727 | |
| 2662 | 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 | 459 | bool ensure_libc_on_non_freestanding = false; |
| 460 | 460 | bool ensure_libcpp_on_non_freestanding = false; |
| 461 | 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; | |
| 462 | 467 | |
| 463 | 468 | ZigList<const char *> llvm_argv = {0}; |
| 464 | 469 | llvm_argv.append("zig (LLVM option parsing)"); |
| ... | ... | @@ -822,6 +827,30 @@ static int main0(int argc, char **argv) { |
| 822 | 827 | return EXIT_FAILURE; |
| 823 | 828 | } |
| 824 | 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 | 854 | } else { |
| 826 | 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 | 1571 | g->code_model = code_model; |
| 1543 | 1572 | g->disable_c_depfile = disable_c_depfile; |
| 1544 | 1573 | |
| 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 | 1580 | if (override_soname) { |
| 1546 | 1581 | g->override_soname = buf_create_from_str(override_soname); |
| 1547 | 1582 | } |