| 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 | 17 | set(ZIG_LIBC_LIB_DIR "" CACHE STRING "Default native target libc directory where crt1.o can be found") |
| 18 | 18 | set(ZIG_LIBC_STATIC_LIB_DIR "" CACHE STRING "Default native target libc directory where crtbeginT.o can be found") |
| 19 | 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 | 20 | set(ZIG_DYNAMIC_LINKER "" CACHE STRING "Override dynamic linker for native target") |
| 23 | 21 | |
| 24 | 22 | option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF) |
| ... | ... | @@ -32,6 +30,9 @@ link_directories(${LLVM_LIBDIRS}) |
| 32 | 30 | find_package(clang) |
| 33 | 31 | include_directories(${CLANG_INCLUDE_DIRS}) |
| 34 | 32 | |
| 33 | find_package(lld) | |
| 34 | include_directories(${LLD_INCLUDE_DIRS}) | |
| 35 | ||
| 35 | 36 | include_directories( |
| 36 | 37 | ${CMAKE_SOURCE_DIR} |
| 37 | 38 | ${CMAKE_BINARY_DIR} |
| ... | ... | @@ -192,6 +193,7 @@ set_target_properties(zig PROPERTIES |
| 192 | 193 | ) |
| 193 | 194 | target_link_libraries(zig LINK_PUBLIC |
| 194 | 195 | ${CLANG_LIBRARIES} |
| 196 | ${LLD_LIBRARIES} | |
| 195 | 197 | ${LLVM_LIBRARIES} |
| 196 | 198 | ) |
| 197 | 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 | 11 | /usr/lib/llvm-4/include |
| 12 | 12 | /mingw64/include) |
| 13 | 13 | |
| 14 | macro(FIND_AND_ADD_CLANG_LIB _libname_) | |
| 14 | macro(FIND_AND_ADD_CLANG_LIB _libname_) | |
| 15 | 15 | string(TOUPPER ${_libname_} _prettylibname_) |
| 16 | 16 | find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_} |
| 17 | 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 | 1 | const c = @cImport(@cInclude("stdio.h")); |
| 2 | 2 | |
| 3 | 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 | 5 | return 0; |
| 6 | 6 | } |
src/all_types.hpp+3-1| ... | ... | @@ -1268,6 +1268,9 @@ struct CodeGen { |
| 1268 | 1268 | ZigList<Buf *> link_libs; // non-libc link libs |
| 1269 | 1269 | // add -framework [name] args to linker |
| 1270 | 1270 | ZigList<Buf *> darwin_frameworks; |
| 1271 | // add -rpath [name] args to linker | |
| 1272 | ZigList<Buf *> rpath_list; | |
| 1273 | ||
| 1271 | 1274 | |
| 1272 | 1275 | // reminder: hash tables must be initialized before use |
| 1273 | 1276 | HashMap<Buf *, ImportTableEntry *, buf_hash, buf_eql_buf> import_table; |
| ... | ... | @@ -1342,7 +1345,6 @@ struct CodeGen { |
| 1342 | 1345 | Buf *libc_include_dir; |
| 1343 | 1346 | Buf *zig_std_dir; |
| 1344 | 1347 | Buf *dynamic_linker; |
| 1345 | Buf *linker_path; | |
| 1346 | 1348 | Buf *ar_path; |
| 1347 | 1349 | Buf triple_str; |
| 1348 | 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 | 89 | g->libc_lib_dir = buf_create_from_str(""); |
| 90 | 90 | g->libc_static_lib_dir = buf_create_from_str(""); |
| 91 | 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 | 92 | g->darwin_linker_version = buf_create_from_str(""); |
| 95 | 93 | } else { |
| 96 | 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 | 99 | g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR); |
| 102 | 100 | g->libc_static_lib_dir = buf_create_from_str(ZIG_LIBC_STATIC_LIB_DIR); |
| 103 | 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 | 102 | g->darwin_linker_version = buf_create_from_str(ZIG_HOST_LINK_VERSION); |
| 107 | 103 | |
| 108 | 104 | if (g->zig_target.os == ZigLLVM_Darwin || |
| ... | ... | @@ -180,18 +176,14 @@ void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker) { |
| 180 | 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 | 179 | void codegen_add_lib_dir(CodeGen *g, const char *dir) { |
| 192 | 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 | 187 | void codegen_add_link_lib(CodeGen *g, const char *lib) { |
| 196 | 188 | if (strcmp(lib, "c") == 0) { |
| 197 | 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 | 32 | void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir); |
| 33 | 33 | void codegen_set_zig_std_dir(CodeGen *codegen, Buf *zig_std_dir); |
| 34 | 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 | 35 | void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole); |
| 38 | 36 | void codegen_set_windows_unicode(CodeGen *g, bool municode); |
| 39 | 37 | void codegen_add_lib_dir(CodeGen *codegen, const char *dir); |
| 40 | 38 | void codegen_add_link_lib(CodeGen *codegen, const char *lib); |
| 41 | 39 | void codegen_add_framework(CodeGen *codegen, const char *name); |
| 40 | void codegen_add_rpath(CodeGen *codegen, const char *name); | |
| 42 | 41 | void codegen_set_mlinker_version(CodeGen *g, Buf *darwin_linker_version); |
| 43 | 42 | void codegen_set_rdynamic(CodeGen *g, bool rdynamic); |
| 44 | 43 | void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min); |
src/config.h.in-2| ... | ... | @@ -18,8 +18,6 @@ |
| 18 | 18 | #define ZIG_LIBC_INCLUDE_DIR "@ZIG_LIBC_INCLUDE_DIR@" |
| 19 | 19 | #define ZIG_LIBC_LIB_DIR "@ZIG_LIBC_LIB_DIR@" |
| 20 | 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 | 21 | #define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@" |
| 24 | 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 | 103 | } |
| 104 | 104 | } |
| 105 | 105 | |
| 106 | ||
| 106 | 107 | static const char *getLDMOption(const ZigTarget *t) { |
| 107 | 108 | switch (t->arch.arch) { |
| 108 | 109 | case ZigLLVM_x86: |
| ... | ... | @@ -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 | 152 | CodeGen *g = lj->codegen; |
| 152 | 153 | |
| 153 | 154 | if (lj->link_in_crt) { |
| ... | ... | @@ -202,6 +203,12 @@ static void construct_linker_job_linux(LinkJob *lj) { |
| 202 | 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 | 212 | for (size_t i = 0; i < g->lib_dirs.length; i += 1) { |
| 206 | 213 | const char *lib_dir = g->lib_dirs.at(i); |
| 207 | 214 | lj->args.append("-L"); |
| ... | ... | @@ -293,7 +300,7 @@ static bool is_target_cyg_mingw(const ZigTarget *target) { |
| 293 | 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 | 304 | CodeGen *g = lj->codegen; |
| 298 | 305 | |
| 299 | 306 | if (lj->link_in_crt) { |
| ... | ... | @@ -546,7 +553,7 @@ static bool darwin_version_lt(DarwinPlatform *platform, int major, int minor) { |
| 546 | 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 | 557 | CodeGen *g = lj->codegen; |
| 551 | 558 | |
| 552 | 559 | int ver_major; |
| ... | ... | @@ -686,85 +693,16 @@ static void construct_linker_job_darwin(LinkJob *lj) { |
| 686 | 693 | } |
| 687 | 694 | |
| 688 | 695 | static void construct_linker_job(LinkJob *lj) { |
| 689 | switch (lj->codegen->zig_target.os) { | |
| 690 | case ZigLLVM_UnknownOS: // freestanding | |
| 691 | // TODO we want to solve this problem with LLD, but for now let's | |
| 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 | } | |
| 696 | switch (lj->codegen->zig_target.oformat) { | |
| 697 | case ZigLLVM_UnknownObjectFormat: | |
| 698 | zig_unreachable(); | |
| 764 | 699 | |
| 765 | static void ensure_we_have_linker_path(CodeGen *g) { | |
| 766 | if (!g->linker_path || buf_len(g->linker_path) == 0) { | |
| 767 | zig_panic("zig does not know the path to the linker"); | |
| 700 | case ZigLLVM_COFF: | |
| 701 | return construct_linker_job_coff(lj); | |
| 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 | 776 | } |
| 839 | 777 | |
| 840 | 778 | lj.link_in_crt = (g->link_libc && g->out_type == OutTypeExe); |
| 841 | ensure_we_have_linker_path(g); | |
| 842 | 779 | |
| 843 | 780 | construct_linker_job(&lj); |
| 844 | 781 | |
| 845 | 782 | |
| 846 | 783 | if (g->verbose) { |
| 847 | fprintf(stderr, "%s", buf_ptr(g->linker_path)); | |
| 784 | fprintf(stderr, "link"); | |
| 848 | 785 | for (size_t i = 0; i < lj.args.length; i += 1) { |
| 849 | 786 | fprintf(stderr, " %s", lj.args.at(i)); |
| 850 | 787 | } |
| 851 | 788 | fprintf(stderr, "\n"); |
| 852 | 789 | } |
| 853 | 790 | |
| 854 | Buf ld_stderr = 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 | } | |
| 791 | Buf diag = BUF_INIT; | |
| 862 | 792 | |
| 863 | if (term.how != TerminationIdClean || term.code != 0) { | |
| 864 | if (term.how == TerminationIdClean) { | |
| 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)); | |
| 793 | if (!ZigLLDLink(g->zig_target.oformat, lj.args.items, lj.args.length, &diag)) { | |
| 794 | fprintf(stderr, "%s\n", buf_ptr(&diag)); | |
| 876 | 795 | exit(1); |
| 877 | } else if (buf_len(&ld_stderr)) { | |
| 878 | fprintf(stderr, "%s\n", buf_ptr(&ld_stderr)); | |
| 879 | 796 | } |
| 880 | 797 | |
| 881 | 798 | if (g->out_type == OutTypeLib || |
src/main.cpp+12-11| ... | ... | @@ -43,6 +43,7 @@ static int usage(const char *arg0) { |
| 43 | 43 | " -isystem [dir] add additional search path for other .h files\n" |
| 44 | 44 | " -dirafter [dir] same as -isystem but do it last\n" |
| 45 | 45 | " --library-path [dir] add a directory to the library search path\n" |
| 46 | " -L[dir] alias for --library-path\n" | |
| 46 | 47 | " --library [lib] link against lib\n" |
| 47 | 48 | " --target-arch [name] specify target architecture\n" |
| 48 | 49 | " --target-os [name] specify target operating system\n" |
| ... | ... | @@ -57,6 +58,7 @@ static int usage(const char *arg0) { |
| 57 | 58 | " -framework [name] (darwin only) link against framework\n" |
| 58 | 59 | " --check-unused perform semantic analysis on unused declarations\n" |
| 59 | 60 | " --linker-script [path] use a custom linker script\n" |
| 61 | " -rpath [path] add a directory to the runtime library search path\n" | |
| 60 | 62 | , arg0); |
| 61 | 63 | return EXIT_FAILURE; |
| 62 | 64 | } |
| ... | ... | @@ -123,8 +125,6 @@ int main(int argc, char **argv) { |
| 123 | 125 | const char *libc_include_dir = nullptr; |
| 124 | 126 | const char *zig_std_dir = nullptr; |
| 125 | 127 | const char *dynamic_linker = nullptr; |
| 126 | const char *linker_path = nullptr; | |
| 127 | const char *ar_path = nullptr; | |
| 128 | 128 | ZigList<const char *> clang_argv = {0}; |
| 129 | 129 | ZigList<const char *> lib_dirs = {0}; |
| 130 | 130 | ZigList<const char *> link_libs = {0}; |
| ... | ... | @@ -142,6 +142,7 @@ int main(int argc, char **argv) { |
| 142 | 142 | const char *mios_version_min = nullptr; |
| 143 | 143 | bool check_unused = false; |
| 144 | 144 | const char *linker_script = nullptr; |
| 145 | ZigList<const char *> rpath_list = {0}; | |
| 145 | 146 | |
| 146 | 147 | for (int i = 1; i < argc; i += 1) { |
| 147 | 148 | char *arg = argv[i]; |
| ... | ... | @@ -165,6 +166,9 @@ int main(int argc, char **argv) { |
| 165 | 166 | rdynamic = true; |
| 166 | 167 | } else if (strcmp(arg, "--check-unused") == 0) { |
| 167 | 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 | 172 | } else if (i + 1 >= argc) { |
| 169 | 173 | return usage(arg0); |
| 170 | 174 | } else { |
| ... | ... | @@ -205,17 +209,13 @@ int main(int argc, char **argv) { |
| 205 | 209 | zig_std_dir = argv[i]; |
| 206 | 210 | } else if (strcmp(arg, "--dynamic-linker") == 0) { |
| 207 | 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 | 212 | } else if (strcmp(arg, "-isystem") == 0) { |
| 213 | 213 | clang_argv.append("-isystem"); |
| 214 | 214 | clang_argv.append(argv[i]); |
| 215 | 215 | } else if (strcmp(arg, "-dirafter") == 0) { |
| 216 | 216 | clang_argv.append("-dirafter"); |
| 217 | 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 | 219 | lib_dirs.append(argv[i]); |
| 220 | 220 | } else if (strcmp(arg, "--library") == 0) { |
| 221 | 221 | link_libs.append(argv[i]); |
| ... | ... | @@ -235,6 +235,8 @@ int main(int argc, char **argv) { |
| 235 | 235 | frameworks.append(argv[i]); |
| 236 | 236 | } else if (strcmp(arg, "--linker-script") == 0) { |
| 237 | 237 | linker_script = argv[i]; |
| 238 | } else if (strcmp(arg, "-rpath") == 0) { | |
| 239 | rpath_list.append(argv[i]); | |
| 238 | 240 | } else { |
| 239 | 241 | fprintf(stderr, "Invalid argument: %s\n", arg); |
| 240 | 242 | return usage(arg0); |
| ... | ... | @@ -373,10 +375,6 @@ int main(int argc, char **argv) { |
| 373 | 375 | codegen_set_zig_std_dir(g, buf_create_from_str(zig_std_dir)); |
| 374 | 376 | if (dynamic_linker) |
| 375 | 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 | 378 | codegen_set_verbose(g, verbose); |
| 381 | 379 | codegen_set_errmsg_color(g, color); |
| 382 | 380 | |
| ... | ... | @@ -389,6 +387,9 @@ int main(int argc, char **argv) { |
| 389 | 387 | for (size_t i = 0; i < frameworks.length; i += 1) { |
| 390 | 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 | 394 | codegen_set_windows_subsystem(g, mwindows, mconsole); |
| 394 | 395 | codegen_set_windows_unicode(g, municode); |
src/zig_llvm.cpp+35| ... | ... | @@ -42,6 +42,8 @@ |
| 42 | 42 | #include <llvm/Transforms/IPO/PassManagerBuilder.h> |
| 43 | 43 | #include <llvm/Transforms/Scalar.h> |
| 44 | 44 | |
| 45 | #include <lld/Driver/Driver.h> | |
| 46 | ||
| 45 | 47 | using namespace llvm; |
| 46 | 48 | |
| 47 | 49 | void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) { |
| ... | ... | @@ -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 | 351 | * This stuff is not LLVM API but it depends on the LLVM C++ API so we put it here. |
| 352 | 352 | */ |
| 353 | 353 | struct Buf; |
| 354 | ||
| 355 | bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag); | |
| 356 | ||
| 354 | 357 | void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *sub_arch_type, |
| 355 | 358 | ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type, |
| 356 | 359 | ZigLLVM_ObjectFormatType *oformat); |