authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-03-13 11:54:56-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-03-13 11:54:56-04:00
logd10bbd28e9576d000f04ac6d06c2a8493ffc72ef
tree9cee12ed88ec066c81567e021e2bb764c0eb2d32
parent7bc0145b802002c38a409dd9fe0b297c8af82391

use lld instead of system linker


12 files changed, 125 insertions(+), 138 deletions(-)

CMakeLists.txt+4-2
...@@ -17,8 +17,6 @@ message("Configuring zig version ${ZIG_VERSION}")...@@ -17,8 +17,6 @@ message("Configuring zig version ${ZIG_VERSION}")
17set(ZIG_LIBC_LIB_DIR "" CACHE STRING "Default native target libc directory where crt1.o can be found")17set(ZIG_LIBC_LIB_DIR "" CACHE STRING "Default native target libc directory where crt1.o can be found")
18set(ZIG_LIBC_STATIC_LIB_DIR "" CACHE STRING "Default native target libc directory where crtbeginT.o can be found")18set(ZIG_LIBC_STATIC_LIB_DIR "" CACHE STRING "Default native target libc directory where crtbeginT.o can be found")
19set(ZIG_LIBC_INCLUDE_DIR "/usr/include" CACHE STRING "Default native target libc include directory")19set(ZIG_LIBC_INCLUDE_DIR "/usr/include" CACHE STRING "Default native target libc include directory")
20set(ZIG_LD_PATH "ld" CACHE STRING "Path to ld for the native target")
21set(ZIG_AR_PATH "ar" CACHE STRING "Path to ar for the native target")
22set(ZIG_DYNAMIC_LINKER "" CACHE STRING "Override dynamic linker for native target")20set(ZIG_DYNAMIC_LINKER "" CACHE STRING "Override dynamic linker for native target")
2321
24option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF)22option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF)
...@@ -32,6 +30,9 @@ link_directories(${LLVM_LIBDIRS})...@@ -32,6 +30,9 @@ link_directories(${LLVM_LIBDIRS})
32find_package(clang)30find_package(clang)
33include_directories(${CLANG_INCLUDE_DIRS})31include_directories(${CLANG_INCLUDE_DIRS})
3432
33find_package(lld)
34include_directories(${LLD_INCLUDE_DIRS})
35
35include_directories(36include_directories(
36 ${CMAKE_SOURCE_DIR}37 ${CMAKE_SOURCE_DIR}
37 ${CMAKE_BINARY_DIR}38 ${CMAKE_BINARY_DIR}
...@@ -192,6 +193,7 @@ set_target_properties(zig PROPERTIES...@@ -192,6 +193,7 @@ set_target_properties(zig PROPERTIES
192)193)
193target_link_libraries(zig LINK_PUBLIC194target_link_libraries(zig LINK_PUBLIC
194 ${CLANG_LIBRARIES}195 ${CLANG_LIBRARIES}
196 ${LLD_LIBRARIES}
195 ${LLVM_LIBRARIES}197 ${LLVM_LIBRARIES}
196)198)
197install(TARGETS zig DESTINATION bin)199install(TARGETS zig DESTINATION bin)
cmake/Findclang.cmake+1-1
...@@ -11,7 +11,7 @@ find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h...@@ -11,7 +11,7 @@ find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h
11 /usr/lib/llvm-4/include11 /usr/lib/llvm-4/include
12 /mingw64/include)12 /mingw64/include)
1313
14macro(FIND_AND_ADD_CLANG_LIB _libname_)14 macro(FIND_AND_ADD_CLANG_LIB _libname_)
15 string(TOUPPER ${_libname_} _prettylibname_)15 string(TOUPPER ${_libname_} _prettylibname_)
16 find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_}16 find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_}
17 PATHS17 PATHS
cmake/Findlld.cmake created+38
...@@ -0,0 +1,38 @@
1# Copyright (c) 2017 Andrew Kelley
2# This file is MIT licensed.
3# See http://opensource.org/licenses/MIT
4
5# LLD_FOUND
6# LLD_INCLUDE_DIRS
7# LLD_LIBRARIES
8
9find_path(LLD_INCLUDE_DIRS NAMES lld/Driver/Driver.h
10 PATHS
11 /usr/lib/llvm-4/include
12 /mingw64/include)
13
14 macro(FIND_AND_ADD_LLD_LIB _libname_)
15 string(TOUPPER ${_libname_} _prettylibname_)
16 find_library(LLD_${_prettylibname_}_LIB NAMES ${_libname_}
17 PATHS
18 /usr/lib/llvm-4/lib
19 /mingw64/lib)
20 if(LLD_${_prettylibname_}_LIB)
21 set(LLD_LIBRARIES ${LLD_LIBRARIES} ${LLD_${_prettylibname_}_LIB})
22 endif()
23endmacro(FIND_AND_ADD_LLD_LIB)
24
25FIND_AND_ADD_LLD_LIB(lldDriver)
26FIND_AND_ADD_LLD_LIB(lldELF)
27FIND_AND_ADD_LLD_LIB(lldCOFF)
28FIND_AND_ADD_LLD_LIB(lldMachO)
29FIND_AND_ADD_LLD_LIB(lldReaderWriter)
30FIND_AND_ADD_LLD_LIB(lldCore)
31FIND_AND_ADD_LLD_LIB(lldYAML)
32FIND_AND_ADD_LLD_LIB(lldConfig)
33
34include(FindPackageHandleStandardArgs)
35find_package_handle_standard_args(LLD DEFAULT_MSG LLD_LIBRARIES LLD_INCLUDE_DIRS)
36
37mark_as_advanced(LLD_INCLUDE_DIRS LLD_LIBRARIES)
38
example/hello_world/hello_libc.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const c = @cImport(@cInclude("stdio.h"));1const c = @cImport(@cInclude("stdio.h"));
22
3export fn main(argc: c_int, argv: &&u8) -> c_int {3export fn main(argc: c_int, argv: &&u8) -> c_int {
4 c.printf(c"Hello, world!\n");4 _ = c.printf(c"Hello, world!\n");
5 return 0;5 return 0;
6}6}
src/all_types.hpp+3-1
...@@ -1268,6 +1268,9 @@ struct CodeGen {...@@ -1268,6 +1268,9 @@ struct CodeGen {
1268 ZigList<Buf *> link_libs; // non-libc link libs1268 ZigList<Buf *> link_libs; // non-libc link libs
1269 // add -framework [name] args to linker1269 // add -framework [name] args to linker
1270 ZigList<Buf *> darwin_frameworks;1270 ZigList<Buf *> darwin_frameworks;
1271 // add -rpath [name] args to linker
1272 ZigList<Buf *> rpath_list;
1273
12711274
1272 // reminder: hash tables must be initialized before use1275 // reminder: hash tables must be initialized before use
1273 HashMap<Buf *, ImportTableEntry *, buf_hash, buf_eql_buf> import_table;1276 HashMap<Buf *, ImportTableEntry *, buf_hash, buf_eql_buf> import_table;
...@@ -1342,7 +1345,6 @@ struct CodeGen {...@@ -1342,7 +1345,6 @@ struct CodeGen {
1342 Buf *libc_include_dir;1345 Buf *libc_include_dir;
1343 Buf *zig_std_dir;1346 Buf *zig_std_dir;
1344 Buf *dynamic_linker;1347 Buf *dynamic_linker;
1345 Buf *linker_path;
1346 Buf *ar_path;1348 Buf *ar_path;
1347 Buf triple_str;1349 Buf triple_str;
1348 bool is_release_build;1350 bool is_release_build;
src/codegen.cpp+4-12
...@@ -89,8 +89,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {...@@ -89,8 +89,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
89 g->libc_lib_dir = buf_create_from_str("");89 g->libc_lib_dir = buf_create_from_str("");
90 g->libc_static_lib_dir = buf_create_from_str("");90 g->libc_static_lib_dir = buf_create_from_str("");
91 g->libc_include_dir = buf_create_from_str("");91 g->libc_include_dir = buf_create_from_str("");
92 g->linker_path = buf_create_from_str("");
93 g->ar_path = buf_create_from_str("");
94 g->darwin_linker_version = buf_create_from_str("");92 g->darwin_linker_version = buf_create_from_str("");
95 } else {93 } else {
96 // native compilation, we can rely on the configuration stuff94 // native compilation, we can rely on the configuration stuff
...@@ -101,8 +99,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {...@@ -101,8 +99,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
101 g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR);99 g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR);
102 g->libc_static_lib_dir = buf_create_from_str(ZIG_LIBC_STATIC_LIB_DIR);100 g->libc_static_lib_dir = buf_create_from_str(ZIG_LIBC_STATIC_LIB_DIR);
103 g->libc_include_dir = buf_create_from_str(ZIG_LIBC_INCLUDE_DIR);101 g->libc_include_dir = buf_create_from_str(ZIG_LIBC_INCLUDE_DIR);
104 g->linker_path = buf_create_from_str(ZIG_LD_PATH);
105 g->ar_path = buf_create_from_str(ZIG_AR_PATH);
106 g->darwin_linker_version = buf_create_from_str(ZIG_HOST_LINK_VERSION);102 g->darwin_linker_version = buf_create_from_str(ZIG_HOST_LINK_VERSION);
107103
108 if (g->zig_target.os == ZigLLVM_Darwin ||104 if (g->zig_target.os == ZigLLVM_Darwin ||
...@@ -180,18 +176,14 @@ void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker) {...@@ -180,18 +176,14 @@ void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker) {
180 g->dynamic_linker = dynamic_linker;176 g->dynamic_linker = dynamic_linker;
181}177}
182178
183void codegen_set_linker_path(CodeGen *g, Buf *linker_path) {
184 g->linker_path = linker_path;
185}
186
187void codegen_set_ar_path(CodeGen *g, Buf *ar_path) {
188 g->ar_path = ar_path;
189}
190
191void codegen_add_lib_dir(CodeGen *g, const char *dir) {179void codegen_add_lib_dir(CodeGen *g, const char *dir) {
192 g->lib_dirs.append(dir);180 g->lib_dirs.append(dir);
193}181}
194182
183void codegen_add_rpath(CodeGen *g, const char *name) {
184 g->rpath_list.append(buf_create_from_str(name));
185}
186
195void codegen_add_link_lib(CodeGen *g, const char *lib) {187void codegen_add_link_lib(CodeGen *g, const char *lib) {
196 if (strcmp(lib, "c") == 0) {188 if (strcmp(lib, "c") == 0) {
197 g->link_libc = true;189 g->link_libc = true;
src/codegen.hpp+1-2
...@@ -32,13 +32,12 @@ void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir);...@@ -32,13 +32,12 @@ void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir);
32void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir);32void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir);
33void codegen_set_zig_std_dir(CodeGen *codegen, Buf *zig_std_dir);33void codegen_set_zig_std_dir(CodeGen *codegen, Buf *zig_std_dir);
34void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker);34void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker);
35void codegen_set_linker_path(CodeGen *g, Buf *linker_path);
36void codegen_set_ar_path(CodeGen *g, Buf *ar_path);
37void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole);35void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole);
38void codegen_set_windows_unicode(CodeGen *g, bool municode);36void codegen_set_windows_unicode(CodeGen *g, bool municode);
39void codegen_add_lib_dir(CodeGen *codegen, const char *dir);37void codegen_add_lib_dir(CodeGen *codegen, const char *dir);
40void codegen_add_link_lib(CodeGen *codegen, const char *lib);38void codegen_add_link_lib(CodeGen *codegen, const char *lib);
41void codegen_add_framework(CodeGen *codegen, const char *name);39void codegen_add_framework(CodeGen *codegen, const char *name);
40void codegen_add_rpath(CodeGen *codegen, const char *name);
42void codegen_set_mlinker_version(CodeGen *g, Buf *darwin_linker_version);41void codegen_set_mlinker_version(CodeGen *g, Buf *darwin_linker_version);
43void codegen_set_rdynamic(CodeGen *g, bool rdynamic);42void codegen_set_rdynamic(CodeGen *g, bool rdynamic);
44void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min);43void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min);
src/config.h.in-2
...@@ -18,8 +18,6 @@...@@ -18,8 +18,6 @@
18#define ZIG_LIBC_INCLUDE_DIR "@ZIG_LIBC_INCLUDE_DIR@"18#define ZIG_LIBC_INCLUDE_DIR "@ZIG_LIBC_INCLUDE_DIR@"
19#define ZIG_LIBC_LIB_DIR "@ZIG_LIBC_LIB_DIR@"19#define ZIG_LIBC_LIB_DIR "@ZIG_LIBC_LIB_DIR@"
20#define ZIG_LIBC_STATIC_LIB_DIR "@ZIG_LIBC_STATIC_LIB_DIR@"20#define ZIG_LIBC_STATIC_LIB_DIR "@ZIG_LIBC_STATIC_LIB_DIR@"
21#define ZIG_LD_PATH "@ZIG_LD_PATH@"
22#define ZIG_AR_PATH "@ZIG_AR_PATH@"
23#define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@"21#define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@"
24#define ZIG_HOST_LINK_VERSION "@ZIG_HOST_LINK_VERSION@"22#define ZIG_HOST_LINK_VERSION "@ZIG_HOST_LINK_VERSION@"
2523
src/link.cpp+23-106
...@@ -103,6 +103,7 @@ static const char *get_darwin_arch_string(const ZigTarget *t) {...@@ -103,6 +103,7 @@ static const char *get_darwin_arch_string(const ZigTarget *t) {
103 }103 }
104}104}
105105
106
106static const char *getLDMOption(const ZigTarget *t) {107static const char *getLDMOption(const ZigTarget *t) {
107 switch (t->arch.arch) {108 switch (t->arch.arch) {
108 case ZigLLVM_x86:109 case ZigLLVM_x86:
...@@ -147,7 +148,7 @@ static const char *getLDMOption(const ZigTarget *t) {...@@ -147,7 +148,7 @@ static const char *getLDMOption(const ZigTarget *t) {
147 }148 }
148}149}
149150
150static void construct_linker_job_linux(LinkJob *lj) {151static void construct_linker_job_elf(LinkJob *lj) {
151 CodeGen *g = lj->codegen;152 CodeGen *g = lj->codegen;
152153
153 if (lj->link_in_crt) {154 if (lj->link_in_crt) {
...@@ -202,6 +203,12 @@ static void construct_linker_job_linux(LinkJob *lj) {...@@ -202,6 +203,12 @@ static void construct_linker_job_linux(LinkJob *lj) {
202 lj->args.append(get_libc_static_file(g, crtbegino));203 lj->args.append(get_libc_static_file(g, crtbegino));
203 }204 }
204205
206 for (size_t i = 0; i < g->rpath_list.length; i += 1) {
207 Buf *rpath = g->rpath_list.at(i);
208 lj->args.append("-rpath");
209 lj->args.append(buf_ptr(rpath));
210 }
211
205 for (size_t i = 0; i < g->lib_dirs.length; i += 1) {212 for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
206 const char *lib_dir = g->lib_dirs.at(i);213 const char *lib_dir = g->lib_dirs.at(i);
207 lj->args.append("-L");214 lj->args.append("-L");
...@@ -293,7 +300,7 @@ static bool is_target_cyg_mingw(const ZigTarget *target) {...@@ -293,7 +300,7 @@ static bool is_target_cyg_mingw(const ZigTarget *target) {
293 (target->os == ZigLLVM_Win32 && target->env_type == ZigLLVM_GNU);300 (target->os == ZigLLVM_Win32 && target->env_type == ZigLLVM_GNU);
294}301}
295302
296static void construct_linker_job_mingw(LinkJob *lj) {303static void construct_linker_job_coff(LinkJob *lj) {
297 CodeGen *g = lj->codegen;304 CodeGen *g = lj->codegen;
298305
299 if (lj->link_in_crt) {306 if (lj->link_in_crt) {
...@@ -546,7 +553,7 @@ static bool darwin_version_lt(DarwinPlatform *platform, int major, int minor) {...@@ -546,7 +553,7 @@ static bool darwin_version_lt(DarwinPlatform *platform, int major, int minor) {
546 return false;553 return false;
547}554}
548555
549static void construct_linker_job_darwin(LinkJob *lj) {556static void construct_linker_job_macho(LinkJob *lj) {
550 CodeGen *g = lj->codegen;557 CodeGen *g = lj->codegen;
551558
552 int ver_major;559 int ver_major;
...@@ -686,85 +693,16 @@ static void construct_linker_job_darwin(LinkJob *lj) {...@@ -686,85 +693,16 @@ static void construct_linker_job_darwin(LinkJob *lj) {
686}693}
687694
688static void construct_linker_job(LinkJob *lj) {695static void construct_linker_job(LinkJob *lj) {
689 switch (lj->codegen->zig_target.os) {696 switch (lj->codegen->zig_target.oformat) {
690 case ZigLLVM_UnknownOS: // freestanding697 case ZigLLVM_UnknownObjectFormat:
691 // TODO we want to solve this problem with LLD, but for now let's698 zig_unreachable();
692 // assume gnu binutils
693 // http://lists.llvm.org/pipermail/llvm-dev/2017-February/109835.html
694 return construct_linker_job_linux(lj);
695 case ZigLLVM_Linux:
696 if (lj->codegen->zig_target.arch.arch == ZigLLVM_hexagon) {
697 zig_panic("TODO construct hexagon_TC linker job");
698 } else {
699 return construct_linker_job_linux(lj);
700 }
701 case ZigLLVM_CloudABI:
702 zig_panic("TODO construct CloudABI linker job");
703 case ZigLLVM_Darwin:
704 case ZigLLVM_MacOSX:
705 case ZigLLVM_IOS:
706 return construct_linker_job_darwin(lj);
707 case ZigLLVM_DragonFly:
708 zig_panic("TODO construct DragonFly linker job");
709 case ZigLLVM_OpenBSD:
710 zig_panic("TODO construct OpenBSD linker job");
711 case ZigLLVM_Bitrig:
712 zig_panic("TODO construct Bitrig linker job");
713 case ZigLLVM_NetBSD:
714 zig_panic("TODO construct NetBSD linker job");
715 case ZigLLVM_FreeBSD:
716 zig_panic("TODO construct FreeBSD linker job");
717 case ZigLLVM_Minix:
718 zig_panic("TODO construct Minix linker job");
719 case ZigLLVM_NaCl:
720 zig_panic("TODO construct NaCl_TC linker job");
721 case ZigLLVM_Solaris:
722 zig_panic("TODO construct Solaris linker job");
723 case ZigLLVM_Win32:
724 switch (lj->codegen->zig_target.env_type) {
725 default:
726 if (lj->codegen->zig_target.oformat == ZigLLVM_ELF) {
727 zig_panic("TODO construct Generic_ELF linker job");
728 } else if (lj->codegen->zig_target.oformat == ZigLLVM_MachO) {
729 zig_panic("TODO construct MachO linker job");
730 } else {
731 zig_panic("TODO construct Generic_GCC linker job");
732 }
733 case ZigLLVM_GNU:
734 return construct_linker_job_mingw(lj);
735 case ZigLLVM_Itanium:
736 zig_panic("TODO construct CrossWindowsToolChain linker job");
737 case ZigLLVM_MSVC:
738 case ZigLLVM_UnknownEnvironment:
739 zig_panic("TODO construct MSVC linker job");
740 }
741 case ZigLLVM_CUDA:
742 zig_panic("TODO construct Cuda linker job");
743 default:
744 // Of these targets, Hexagon is the only one that might have
745 // an OS of Linux, in which case it got handled above already.
746 if (lj->codegen->zig_target.arch.arch == ZigLLVM_tce) {
747 zig_panic("TODO construct TCE linker job");
748 } else if (lj->codegen->zig_target.arch.arch == ZigLLVM_hexagon) {
749 zig_panic("TODO construct Hexagon_TC linker job");
750 } else if (lj->codegen->zig_target.arch.arch == ZigLLVM_xcore) {
751 zig_panic("TODO construct XCore linker job");
752 } else if (lj->codegen->zig_target.arch.arch == ZigLLVM_shave) {
753 zig_panic("TODO construct SHAVE linker job");
754 } else if (lj->codegen->zig_target.oformat == ZigLLVM_ELF) {
755 zig_panic("TODO construct Generic_ELF linker job");
756 } else if (lj->codegen->zig_target.oformat == ZigLLVM_MachO) {
757 zig_panic("TODO construct MachO linker job");
758 } else {
759 zig_panic("TODO construct Generic_GCC linker job");
760 }
761
762 }
763}
764699
765static void ensure_we_have_linker_path(CodeGen *g) {700 case ZigLLVM_COFF:
766 if (!g->linker_path || buf_len(g->linker_path) == 0) {701 return construct_linker_job_coff(lj);
767 zig_panic("zig does not know the path to the linker");702 case ZigLLVM_ELF:
703 return construct_linker_job_elf(lj);
704 case ZigLLVM_MachO:
705 return construct_linker_job_macho(lj);
768 }706 }
769}707}
770708
...@@ -838,44 +776,23 @@ void codegen_link(CodeGen *g, const char *out_file) {...@@ -838,44 +776,23 @@ void codegen_link(CodeGen *g, const char *out_file) {
838 }776 }
839777
840 lj.link_in_crt = (g->link_libc && g->out_type == OutTypeExe);778 lj.link_in_crt = (g->link_libc && g->out_type == OutTypeExe);
841 ensure_we_have_linker_path(g);
842779
843 construct_linker_job(&lj);780 construct_linker_job(&lj);
844781
845782
846 if (g->verbose) {783 if (g->verbose) {
847 fprintf(stderr, "%s", buf_ptr(g->linker_path));784 fprintf(stderr, "link");
848 for (size_t i = 0; i < lj.args.length; i += 1) {785 for (size_t i = 0; i < lj.args.length; i += 1) {
849 fprintf(stderr, " %s", lj.args.at(i));786 fprintf(stderr, " %s", lj.args.at(i));
850 }787 }
851 fprintf(stderr, "\n");788 fprintf(stderr, "\n");
852 }789 }
853790
854 Buf ld_stderr = BUF_INIT;791 Buf diag = BUF_INIT;
855 Buf ld_stdout = BUF_INIT;
856 Termination term;
857 int err = os_exec_process(buf_ptr(g->linker_path), lj.args, &term, &ld_stderr, &ld_stdout);
858 if (err) {
859 fprintf(stderr, "linker not found: '%s'\n", buf_ptr(g->linker_path));
860 exit(1);
861 }
862792
863 if (term.how != TerminationIdClean || term.code != 0) {793 if (!ZigLLDLink(g->zig_target.oformat, lj.args.items, lj.args.length, &diag)) {
864 if (term.how == TerminationIdClean) {794 fprintf(stderr, "%s\n", buf_ptr(&diag));
865 fprintf(stderr, "linker failed with return code %d\n", term.code);
866 } else if (term.how == TerminationIdSignaled) {
867 fprintf(stderr, "linker failed with signal %d\n", term.code);
868 } else {
869 fprintf(stderr, "linker failed\n");
870 }
871 fprintf(stderr, "%s ", buf_ptr(g->linker_path));
872 for (size_t i = 0; i < lj.args.length; i += 1) {
873 fprintf(stderr, "%s ", lj.args.at(i));
874 }
875 fprintf(stderr, "\n%s\n", buf_ptr(&ld_stderr));
876 exit(1);795 exit(1);
877 } else if (buf_len(&ld_stderr)) {
878 fprintf(stderr, "%s\n", buf_ptr(&ld_stderr));
879 }796 }
880797
881 if (g->out_type == OutTypeLib ||798 if (g->out_type == OutTypeLib ||
src/main.cpp+12-11
...@@ -43,6 +43,7 @@ static int usage(const char *arg0) {...@@ -43,6 +43,7 @@ static int usage(const char *arg0) {
43 " -isystem [dir] add additional search path for other .h files\n"43 " -isystem [dir] add additional search path for other .h files\n"
44 " -dirafter [dir] same as -isystem but do it last\n"44 " -dirafter [dir] same as -isystem but do it last\n"
45 " --library-path [dir] add a directory to the library search path\n"45 " --library-path [dir] add a directory to the library search path\n"
46 " -L[dir] alias for --library-path\n"
46 " --library [lib] link against lib\n"47 " --library [lib] link against lib\n"
47 " --target-arch [name] specify target architecture\n"48 " --target-arch [name] specify target architecture\n"
48 " --target-os [name] specify target operating system\n"49 " --target-os [name] specify target operating system\n"
...@@ -57,6 +58,7 @@ static int usage(const char *arg0) {...@@ -57,6 +58,7 @@ static int usage(const char *arg0) {
57 " -framework [name] (darwin only) link against framework\n"58 " -framework [name] (darwin only) link against framework\n"
58 " --check-unused perform semantic analysis on unused declarations\n"59 " --check-unused perform semantic analysis on unused declarations\n"
59 " --linker-script [path] use a custom linker script\n"60 " --linker-script [path] use a custom linker script\n"
61 " -rpath [path] add a directory to the runtime library search path\n"
60 , arg0);62 , arg0);
61 return EXIT_FAILURE;63 return EXIT_FAILURE;
62}64}
...@@ -123,8 +125,6 @@ int main(int argc, char **argv) {...@@ -123,8 +125,6 @@ int main(int argc, char **argv) {
123 const char *libc_include_dir = nullptr;125 const char *libc_include_dir = nullptr;
124 const char *zig_std_dir = nullptr;126 const char *zig_std_dir = nullptr;
125 const char *dynamic_linker = nullptr;127 const char *dynamic_linker = nullptr;
126 const char *linker_path = nullptr;
127 const char *ar_path = nullptr;
128 ZigList<const char *> clang_argv = {0};128 ZigList<const char *> clang_argv = {0};
129 ZigList<const char *> lib_dirs = {0};129 ZigList<const char *> lib_dirs = {0};
130 ZigList<const char *> link_libs = {0};130 ZigList<const char *> link_libs = {0};
...@@ -142,6 +142,7 @@ int main(int argc, char **argv) {...@@ -142,6 +142,7 @@ int main(int argc, char **argv) {
142 const char *mios_version_min = nullptr;142 const char *mios_version_min = nullptr;
143 bool check_unused = false;143 bool check_unused = false;
144 const char *linker_script = nullptr;144 const char *linker_script = nullptr;
145 ZigList<const char *> rpath_list = {0};
145146
146 for (int i = 1; i < argc; i += 1) {147 for (int i = 1; i < argc; i += 1) {
147 char *arg = argv[i];148 char *arg = argv[i];
...@@ -165,6 +166,9 @@ int main(int argc, char **argv) {...@@ -165,6 +166,9 @@ int main(int argc, char **argv) {
165 rdynamic = true;166 rdynamic = true;
166 } else if (strcmp(arg, "--check-unused") == 0) {167 } else if (strcmp(arg, "--check-unused") == 0) {
167 check_unused = true;168 check_unused = true;
169 } else if (arg[1] == 'L' && arg[2] != 0) {
170 // alias for --library-path
171 lib_dirs.append(&arg[2]);
168 } else if (i + 1 >= argc) {172 } else if (i + 1 >= argc) {
169 return usage(arg0);173 return usage(arg0);
170 } else {174 } else {
...@@ -205,17 +209,13 @@ int main(int argc, char **argv) {...@@ -205,17 +209,13 @@ int main(int argc, char **argv) {
205 zig_std_dir = argv[i];209 zig_std_dir = argv[i];
206 } else if (strcmp(arg, "--dynamic-linker") == 0) {210 } else if (strcmp(arg, "--dynamic-linker") == 0) {
207 dynamic_linker = argv[i];211 dynamic_linker = argv[i];
208 } else if (strcmp(arg, "--ld-path") == 0) {
209 linker_path = argv[i];
210 } else if (strcmp(arg, "--ar-path") == 0) {
211 ar_path = argv[i];
212 } else if (strcmp(arg, "-isystem") == 0) {212 } else if (strcmp(arg, "-isystem") == 0) {
213 clang_argv.append("-isystem");213 clang_argv.append("-isystem");
214 clang_argv.append(argv[i]);214 clang_argv.append(argv[i]);
215 } else if (strcmp(arg, "-dirafter") == 0) {215 } else if (strcmp(arg, "-dirafter") == 0) {
216 clang_argv.append("-dirafter");216 clang_argv.append("-dirafter");
217 clang_argv.append(argv[i]);217 clang_argv.append(argv[i]);
218 } else if (strcmp(arg, "--library-path") == 0) {218 } else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) {
219 lib_dirs.append(argv[i]);219 lib_dirs.append(argv[i]);
220 } else if (strcmp(arg, "--library") == 0) {220 } else if (strcmp(arg, "--library") == 0) {
221 link_libs.append(argv[i]);221 link_libs.append(argv[i]);
...@@ -235,6 +235,8 @@ int main(int argc, char **argv) {...@@ -235,6 +235,8 @@ int main(int argc, char **argv) {
235 frameworks.append(argv[i]);235 frameworks.append(argv[i]);
236 } else if (strcmp(arg, "--linker-script") == 0) {236 } else if (strcmp(arg, "--linker-script") == 0) {
237 linker_script = argv[i];237 linker_script = argv[i];
238 } else if (strcmp(arg, "-rpath") == 0) {
239 rpath_list.append(argv[i]);
238 } else {240 } else {
239 fprintf(stderr, "Invalid argument: %s\n", arg);241 fprintf(stderr, "Invalid argument: %s\n", arg);
240 return usage(arg0);242 return usage(arg0);
...@@ -373,10 +375,6 @@ int main(int argc, char **argv) {...@@ -373,10 +375,6 @@ int main(int argc, char **argv) {
373 codegen_set_zig_std_dir(g, buf_create_from_str(zig_std_dir));375 codegen_set_zig_std_dir(g, buf_create_from_str(zig_std_dir));
374 if (dynamic_linker)376 if (dynamic_linker)
375 codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker));377 codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker));
376 if (linker_path)
377 codegen_set_linker_path(g, buf_create_from_str(linker_path));
378 if (ar_path)
379 codegen_set_ar_path(g, buf_create_from_str(ar_path));
380 codegen_set_verbose(g, verbose);378 codegen_set_verbose(g, verbose);
381 codegen_set_errmsg_color(g, color);379 codegen_set_errmsg_color(g, color);
382380
...@@ -389,6 +387,9 @@ int main(int argc, char **argv) {...@@ -389,6 +387,9 @@ int main(int argc, char **argv) {
389 for (size_t i = 0; i < frameworks.length; i += 1) {387 for (size_t i = 0; i < frameworks.length; i += 1) {
390 codegen_add_framework(g, frameworks.at(i));388 codegen_add_framework(g, frameworks.at(i));
391 }389 }
390 for (size_t i = 0; i < rpath_list.length; i += 1) {
391 codegen_add_rpath(g, rpath_list.at(i));
392 }
392393
393 codegen_set_windows_subsystem(g, mwindows, mconsole);394 codegen_set_windows_subsystem(g, mwindows, mconsole);
394 codegen_set_windows_unicode(g, municode);395 codegen_set_windows_unicode(g, municode);
src/zig_llvm.cpp+35
...@@ -42,6 +42,8 @@...@@ -42,6 +42,8 @@
42#include <llvm/Transforms/IPO/PassManagerBuilder.h>42#include <llvm/Transforms/IPO/PassManagerBuilder.h>
43#include <llvm/Transforms/Scalar.h>43#include <llvm/Transforms/Scalar.h>
4444
45#include <lld/Driver/Driver.h>
46
45using namespace llvm;47using namespace llvm;
4648
47void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) {49void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) {
...@@ -790,3 +792,36 @@ Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine_ref) {...@@ -790,3 +792,36 @@ Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine_ref) {
790 }792 }
791}793}
792794
795bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag_buf) {
796 ArrayRef<const char *> array_ref_args(args, arg_count);
797
798 buf_resize(diag_buf, 0);
799 class MyOStream: public raw_ostream {
800 public:
801 MyOStream(Buf *_diag_buf) : raw_ostream(true), diag_buf(_diag_buf) {
802
803 }
804 void write_impl(const char *ptr, size_t len) override {
805 buf_append_mem(diag_buf, ptr, len);
806 }
807 uint64_t current_pos() const override {
808 return buf_len(diag_buf);
809 }
810 Buf *diag_buf;
811 } diag(diag_buf);
812
813 switch (oformat) {
814 case ZigLLVM_UnknownObjectFormat:
815 zig_unreachable();
816
817 case ZigLLVM_COFF:
818 return lld::coff::link(array_ref_args);
819
820 case ZigLLVM_ELF:
821 return lld::elf::link(array_ref_args, false, diag);
822
823 case ZigLLVM_MachO:
824 return lld::mach_o::link(array_ref_args, diag);
825 }
826 zig_unreachable();
827}
src/zig_llvm.hpp+3
...@@ -351,6 +351,9 @@ const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type);...@@ -351,6 +351,9 @@ const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type);
351 * This stuff is not LLVM API but it depends on the LLVM C++ API so we put it here.351 * This stuff is not LLVM API but it depends on the LLVM C++ API so we put it here.
352 */352 */
353struct Buf;353struct Buf;
354
355bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag);
356
354void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *sub_arch_type,357void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *sub_arch_type,
355 ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type,358 ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type,
356 ZigLLVM_ObjectFormatType *oformat);359 ZigLLVM_ObjectFormatType *oformat);