| author | |
| committer | |
| log | d10bbd28e9576d000f04ac6d06c2a8493ffc72ef |
| tree | 9cee12ed88ec066c81567e021e2bb764c0eb2d32 |
| parent | 7bc0145b802002c38a409dd9fe0b297c8af82391 |
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}") |
| 17 | set(ZIG_LIBC_LIB_DIR "" CACHE STRING "Default native target libc directory where crt1.o can be found") | 17 | set(ZIG_LIBC_LIB_DIR "" CACHE STRING "Default native target libc directory where crt1.o can be found") |
| 18 | set(ZIG_LIBC_STATIC_LIB_DIR "" CACHE STRING "Default native target libc directory where crtbeginT.o can be found") | 18 | set(ZIG_LIBC_STATIC_LIB_DIR "" CACHE STRING "Default native target libc directory where crtbeginT.o can be found") |
| 19 | set(ZIG_LIBC_INCLUDE_DIR "/usr/include" CACHE STRING "Default native target libc include directory") | 19 | set(ZIG_LIBC_INCLUDE_DIR "/usr/include" CACHE STRING "Default native target libc include directory") |
| 20 | set(ZIG_LD_PATH "ld" CACHE STRING "Path to ld for the native target") | ||
| 21 | set(ZIG_AR_PATH "ar" CACHE STRING "Path to ar for the native target") | ||
| 22 | set(ZIG_DYNAMIC_LINKER "" CACHE STRING "Override dynamic linker for native target") | 20 | set(ZIG_DYNAMIC_LINKER "" CACHE STRING "Override dynamic linker for native target") |
| 23 | 21 | ||
| 24 | option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF) | 22 | option(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}) |
| 32 | find_package(clang) | 30 | find_package(clang) |
| 33 | include_directories(${CLANG_INCLUDE_DIRS}) | 31 | include_directories(${CLANG_INCLUDE_DIRS}) |
| 34 | 32 | ||
| 33 | find_package(lld) | ||
| 34 | include_directories(${LLD_INCLUDE_DIRS}) | ||
| 35 | |||
| 35 | include_directories( | 36 | include_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 | ) |
| 193 | target_link_libraries(zig LINK_PUBLIC | 194 | target_link_libraries(zig LINK_PUBLIC |
| 194 | ${CLANG_LIBRARIES} | 195 | ${CLANG_LIBRARIES} |
| 196 | ${LLD_LIBRARIES} | ||
| 195 | ${LLVM_LIBRARIES} | 197 | ${LLVM_LIBRARIES} |
| 196 | ) | 198 | ) |
| 197 | install(TARGETS zig DESTINATION bin) | 199 | install(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/include | 11 | /usr/lib/llvm-4/include |
| 12 | /mingw64/include) | 12 | /mingw64/include) |
| 13 | 13 | ||
| 14 | macro(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 | PATHS | 17 | 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 | |||
| 9 | find_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() | ||
| 23 | endmacro(FIND_AND_ADD_LLD_LIB) | ||
| 24 | |||
| 25 | FIND_AND_ADD_LLD_LIB(lldDriver) | ||
| 26 | FIND_AND_ADD_LLD_LIB(lldELF) | ||
| 27 | FIND_AND_ADD_LLD_LIB(lldCOFF) | ||
| 28 | FIND_AND_ADD_LLD_LIB(lldMachO) | ||
| 29 | FIND_AND_ADD_LLD_LIB(lldReaderWriter) | ||
| 30 | FIND_AND_ADD_LLD_LIB(lldCore) | ||
| 31 | FIND_AND_ADD_LLD_LIB(lldYAML) | ||
| 32 | FIND_AND_ADD_LLD_LIB(lldConfig) | ||
| 33 | |||
| 34 | include(FindPackageHandleStandardArgs) | ||
| 35 | find_package_handle_standard_args(LLD DEFAULT_MSG LLD_LIBRARIES LLD_INCLUDE_DIRS) | ||
| 36 | |||
| 37 | mark_as_advanced(LLD_INCLUDE_DIRS LLD_LIBRARIES) | ||
| 38 | |||
example/hello_world/hello_libc.zig+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | const c = @cImport(@cInclude("stdio.h")); | 1 | const c = @cImport(@cInclude("stdio.h")); |
| 2 | 2 | ||
| 3 | export fn main(argc: c_int, argv: &&u8) -> c_int { | 3 | export 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 libs | 1268 | ZigList<Buf *> link_libs; // non-libc link libs |
| 1269 | // add -framework [name] args to linker | 1269 | // 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 | |||
| 1271 | 1274 | ||
| 1272 | // reminder: hash tables must be initialized before use | 1275 | // 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 stuff | 94 | // 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); |
| 107 | 103 | ||
| 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 | } |
| 182 | 178 | ||
| 183 | void codegen_set_linker_path(CodeGen *g, Buf *linker_path) { | ||
| 184 | g->linker_path = linker_path; | ||
| 185 | } | ||
| 186 | |||
| 187 | void codegen_set_ar_path(CodeGen *g, Buf *ar_path) { | ||
| 188 | g->ar_path = ar_path; | ||
| 189 | } | ||
| 190 | |||
| 191 | void codegen_add_lib_dir(CodeGen *g, const char *dir) { | 179 | void codegen_add_lib_dir(CodeGen *g, const char *dir) { |
| 192 | g->lib_dirs.append(dir); | 180 | g->lib_dirs.append(dir); |
| 193 | } | 181 | } |
| 194 | 182 | ||
| 183 | void codegen_add_rpath(CodeGen *g, const char *name) { | ||
| 184 | g->rpath_list.append(buf_create_from_str(name)); | ||
| 185 | } | ||
| 186 | |||
| 195 | void codegen_add_link_lib(CodeGen *g, const char *lib) { | 187 | void 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); |
| 32 | void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir); | 32 | void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir); |
| 33 | void codegen_set_zig_std_dir(CodeGen *codegen, Buf *zig_std_dir); | 33 | void codegen_set_zig_std_dir(CodeGen *codegen, Buf *zig_std_dir); |
| 34 | void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker); | 34 | void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker); |
| 35 | void codegen_set_linker_path(CodeGen *g, Buf *linker_path); | ||
| 36 | void codegen_set_ar_path(CodeGen *g, Buf *ar_path); | ||
| 37 | void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole); | 35 | void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole); |
| 38 | void codegen_set_windows_unicode(CodeGen *g, bool municode); | 36 | void codegen_set_windows_unicode(CodeGen *g, bool municode); |
| 39 | void codegen_add_lib_dir(CodeGen *codegen, const char *dir); | 37 | void codegen_add_lib_dir(CodeGen *codegen, const char *dir); |
| 40 | void codegen_add_link_lib(CodeGen *codegen, const char *lib); | 38 | void codegen_add_link_lib(CodeGen *codegen, const char *lib); |
| 41 | void codegen_add_framework(CodeGen *codegen, const char *name); | 39 | void codegen_add_framework(CodeGen *codegen, const char *name); |
| 40 | void codegen_add_rpath(CodeGen *codegen, const char *name); | ||
| 42 | void codegen_set_mlinker_version(CodeGen *g, Buf *darwin_linker_version); | 41 | void codegen_set_mlinker_version(CodeGen *g, Buf *darwin_linker_version); |
| 43 | void codegen_set_rdynamic(CodeGen *g, bool rdynamic); | 42 | void codegen_set_rdynamic(CodeGen *g, bool rdynamic); |
| 44 | void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min); | 43 | void 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@" |
| 25 | 23 |
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 | } |
| 105 | 105 | ||
| 106 | |||
| 106 | static const char *getLDMOption(const ZigTarget *t) { | 107 | static 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 | } |
| 149 | 150 | ||
| 150 | static void construct_linker_job_linux(LinkJob *lj) { | 151 | static void construct_linker_job_elf(LinkJob *lj) { |
| 151 | CodeGen *g = lj->codegen; | 152 | CodeGen *g = lj->codegen; |
| 152 | 153 | ||
| 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 | } |
| 204 | 205 | ||
| 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 | } |
| 295 | 302 | ||
| 296 | static void construct_linker_job_mingw(LinkJob *lj) { | 303 | static void construct_linker_job_coff(LinkJob *lj) { |
| 297 | CodeGen *g = lj->codegen; | 304 | CodeGen *g = lj->codegen; |
| 298 | 305 | ||
| 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 | } |
| 548 | 555 | ||
| 549 | static void construct_linker_job_darwin(LinkJob *lj) { | 556 | static void construct_linker_job_macho(LinkJob *lj) { |
| 550 | CodeGen *g = lj->codegen; | 557 | CodeGen *g = lj->codegen; |
| 551 | 558 | ||
| 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 | } |
| 687 | 694 | ||
| 688 | static void construct_linker_job(LinkJob *lj) { | 695 | static void construct_linker_job(LinkJob *lj) { |
| 689 | switch (lj->codegen->zig_target.os) { | 696 | switch (lj->codegen->zig_target.oformat) { |
| 690 | case ZigLLVM_UnknownOS: // freestanding | 697 | case ZigLLVM_UnknownObjectFormat: |
| 691 | // TODO we want to solve this problem with LLD, but for now let's | 698 | 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 | } | ||
| 764 | 699 | ||
| 765 | static 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 | } |
| 770 | 708 | ||
| ... | @@ -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 | } |
| 839 | 777 | ||
| 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); | ||
| 842 | 779 | ||
| 843 | construct_linker_job(&lj); | 780 | construct_linker_job(&lj); |
| 844 | 781 | ||
| 845 | 782 | ||
| 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 | } |
| 853 | 790 | ||
| 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 | } | ||
| 862 | 792 | ||
| 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 | } |
| 880 | 797 | ||
| 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}; | ||
| 145 | 146 | ||
| 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); |
| 382 | 380 | ||
| ... | @@ -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 | } | ||
| 392 | 393 | ||
| 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> |
| 44 | 44 | ||
| 45 | #include <lld/Driver/Driver.h> | ||
| 46 | |||
| 45 | using namespace llvm; | 47 | using namespace llvm; |
| 46 | 48 | ||
| 47 | void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) { | 49 | void 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 | } |
| 792 | 794 | ||
| 795 | bool 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 | */ |
| 353 | struct Buf; | 353 | struct Buf; |
| 354 | |||
| 355 | bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag); | ||
| 356 | |||
| 354 | void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *sub_arch_type, | 357 | void 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); |