use lld instead of system linker
parent
7bc0145b80
commit
d10bbd28e9
|
@ -17,8 +17,6 @@ message("Configuring zig version ${ZIG_VERSION}")
|
|||
set(ZIG_LIBC_LIB_DIR "" CACHE STRING "Default native target libc directory where crt1.o can be found")
|
||||
set(ZIG_LIBC_STATIC_LIB_DIR "" CACHE STRING "Default native target libc directory where crtbeginT.o can be found")
|
||||
set(ZIG_LIBC_INCLUDE_DIR "/usr/include" CACHE STRING "Default native target libc include directory")
|
||||
set(ZIG_LD_PATH "ld" CACHE STRING "Path to ld for the native target")
|
||||
set(ZIG_AR_PATH "ar" CACHE STRING "Path to ar for the native target")
|
||||
set(ZIG_DYNAMIC_LINKER "" CACHE STRING "Override dynamic linker for native target")
|
||||
|
||||
option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF)
|
||||
|
@ -32,6 +30,9 @@ link_directories(${LLVM_LIBDIRS})
|
|||
find_package(clang)
|
||||
include_directories(${CLANG_INCLUDE_DIRS})
|
||||
|
||||
find_package(lld)
|
||||
include_directories(${LLD_INCLUDE_DIRS})
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
|
@ -192,6 +193,7 @@ set_target_properties(zig PROPERTIES
|
|||
)
|
||||
target_link_libraries(zig LINK_PUBLIC
|
||||
${CLANG_LIBRARIES}
|
||||
${LLD_LIBRARIES}
|
||||
${LLVM_LIBRARIES}
|
||||
)
|
||||
install(TARGETS zig DESTINATION bin)
|
||||
|
|
|
@ -11,7 +11,7 @@ find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h
|
|||
/usr/lib/llvm-4/include
|
||||
/mingw64/include)
|
||||
|
||||
macro(FIND_AND_ADD_CLANG_LIB _libname_)
|
||||
macro(FIND_AND_ADD_CLANG_LIB _libname_)
|
||||
string(TOUPPER ${_libname_} _prettylibname_)
|
||||
find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_}
|
||||
PATHS
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
# Copyright (c) 2017 Andrew Kelley
|
||||
# This file is MIT licensed.
|
||||
# See http://opensource.org/licenses/MIT
|
||||
|
||||
# LLD_FOUND
|
||||
# LLD_INCLUDE_DIRS
|
||||
# LLD_LIBRARIES
|
||||
|
||||
find_path(LLD_INCLUDE_DIRS NAMES lld/Driver/Driver.h
|
||||
PATHS
|
||||
/usr/lib/llvm-4/include
|
||||
/mingw64/include)
|
||||
|
||||
macro(FIND_AND_ADD_LLD_LIB _libname_)
|
||||
string(TOUPPER ${_libname_} _prettylibname_)
|
||||
find_library(LLD_${_prettylibname_}_LIB NAMES ${_libname_}
|
||||
PATHS
|
||||
/usr/lib/llvm-4/lib
|
||||
/mingw64/lib)
|
||||
if(LLD_${_prettylibname_}_LIB)
|
||||
set(LLD_LIBRARIES ${LLD_LIBRARIES} ${LLD_${_prettylibname_}_LIB})
|
||||
endif()
|
||||
endmacro(FIND_AND_ADD_LLD_LIB)
|
||||
|
||||
FIND_AND_ADD_LLD_LIB(lldDriver)
|
||||
FIND_AND_ADD_LLD_LIB(lldELF)
|
||||
FIND_AND_ADD_LLD_LIB(lldCOFF)
|
||||
FIND_AND_ADD_LLD_LIB(lldMachO)
|
||||
FIND_AND_ADD_LLD_LIB(lldReaderWriter)
|
||||
FIND_AND_ADD_LLD_LIB(lldCore)
|
||||
FIND_AND_ADD_LLD_LIB(lldYAML)
|
||||
FIND_AND_ADD_LLD_LIB(lldConfig)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(LLD DEFAULT_MSG LLD_LIBRARIES LLD_INCLUDE_DIRS)
|
||||
|
||||
mark_as_advanced(LLD_INCLUDE_DIRS LLD_LIBRARIES)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
const c = @cImport(@cInclude("stdio.h"));
|
||||
|
||||
export fn main(argc: c_int, argv: &&u8) -> c_int {
|
||||
c.printf(c"Hello, world!\n");
|
||||
_ = c.printf(c"Hello, world!\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1268,6 +1268,9 @@ struct CodeGen {
|
|||
ZigList<Buf *> link_libs; // non-libc link libs
|
||||
// add -framework [name] args to linker
|
||||
ZigList<Buf *> darwin_frameworks;
|
||||
// add -rpath [name] args to linker
|
||||
ZigList<Buf *> rpath_list;
|
||||
|
||||
|
||||
// reminder: hash tables must be initialized before use
|
||||
HashMap<Buf *, ImportTableEntry *, buf_hash, buf_eql_buf> import_table;
|
||||
|
@ -1342,7 +1345,6 @@ struct CodeGen {
|
|||
Buf *libc_include_dir;
|
||||
Buf *zig_std_dir;
|
||||
Buf *dynamic_linker;
|
||||
Buf *linker_path;
|
||||
Buf *ar_path;
|
||||
Buf triple_str;
|
||||
bool is_release_build;
|
||||
|
|
|
@ -89,8 +89,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
|
|||
g->libc_lib_dir = buf_create_from_str("");
|
||||
g->libc_static_lib_dir = buf_create_from_str("");
|
||||
g->libc_include_dir = buf_create_from_str("");
|
||||
g->linker_path = buf_create_from_str("");
|
||||
g->ar_path = buf_create_from_str("");
|
||||
g->darwin_linker_version = buf_create_from_str("");
|
||||
} else {
|
||||
// native compilation, we can rely on the configuration stuff
|
||||
|
@ -101,8 +99,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
|
|||
g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR);
|
||||
g->libc_static_lib_dir = buf_create_from_str(ZIG_LIBC_STATIC_LIB_DIR);
|
||||
g->libc_include_dir = buf_create_from_str(ZIG_LIBC_INCLUDE_DIR);
|
||||
g->linker_path = buf_create_from_str(ZIG_LD_PATH);
|
||||
g->ar_path = buf_create_from_str(ZIG_AR_PATH);
|
||||
g->darwin_linker_version = buf_create_from_str(ZIG_HOST_LINK_VERSION);
|
||||
|
||||
if (g->zig_target.os == ZigLLVM_Darwin ||
|
||||
|
@ -180,18 +176,14 @@ void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker) {
|
|||
g->dynamic_linker = dynamic_linker;
|
||||
}
|
||||
|
||||
void codegen_set_linker_path(CodeGen *g, Buf *linker_path) {
|
||||
g->linker_path = linker_path;
|
||||
}
|
||||
|
||||
void codegen_set_ar_path(CodeGen *g, Buf *ar_path) {
|
||||
g->ar_path = ar_path;
|
||||
}
|
||||
|
||||
void codegen_add_lib_dir(CodeGen *g, const char *dir) {
|
||||
g->lib_dirs.append(dir);
|
||||
}
|
||||
|
||||
void codegen_add_rpath(CodeGen *g, const char *name) {
|
||||
g->rpath_list.append(buf_create_from_str(name));
|
||||
}
|
||||
|
||||
void codegen_add_link_lib(CodeGen *g, const char *lib) {
|
||||
if (strcmp(lib, "c") == 0) {
|
||||
g->link_libc = true;
|
||||
|
|
|
@ -32,13 +32,12 @@ void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir);
|
|||
void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir);
|
||||
void codegen_set_zig_std_dir(CodeGen *codegen, Buf *zig_std_dir);
|
||||
void codegen_set_dynamic_linker(CodeGen *g, Buf *dynamic_linker);
|
||||
void codegen_set_linker_path(CodeGen *g, Buf *linker_path);
|
||||
void codegen_set_ar_path(CodeGen *g, Buf *ar_path);
|
||||
void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole);
|
||||
void codegen_set_windows_unicode(CodeGen *g, bool municode);
|
||||
void codegen_add_lib_dir(CodeGen *codegen, const char *dir);
|
||||
void codegen_add_link_lib(CodeGen *codegen, const char *lib);
|
||||
void codegen_add_framework(CodeGen *codegen, const char *name);
|
||||
void codegen_add_rpath(CodeGen *codegen, const char *name);
|
||||
void codegen_set_mlinker_version(CodeGen *g, Buf *darwin_linker_version);
|
||||
void codegen_set_rdynamic(CodeGen *g, bool rdynamic);
|
||||
void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min);
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
#define ZIG_LIBC_INCLUDE_DIR "@ZIG_LIBC_INCLUDE_DIR@"
|
||||
#define ZIG_LIBC_LIB_DIR "@ZIG_LIBC_LIB_DIR@"
|
||||
#define ZIG_LIBC_STATIC_LIB_DIR "@ZIG_LIBC_STATIC_LIB_DIR@"
|
||||
#define ZIG_LD_PATH "@ZIG_LD_PATH@"
|
||||
#define ZIG_AR_PATH "@ZIG_AR_PATH@"
|
||||
#define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@"
|
||||
#define ZIG_HOST_LINK_VERSION "@ZIG_HOST_LINK_VERSION@"
|
||||
|
||||
|
|
129
src/link.cpp
129
src/link.cpp
|
@ -103,6 +103,7 @@ static const char *get_darwin_arch_string(const ZigTarget *t) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *getLDMOption(const ZigTarget *t) {
|
||||
switch (t->arch.arch) {
|
||||
case ZigLLVM_x86:
|
||||
|
@ -147,7 +148,7 @@ static const char *getLDMOption(const ZigTarget *t) {
|
|||
}
|
||||
}
|
||||
|
||||
static void construct_linker_job_linux(LinkJob *lj) {
|
||||
static void construct_linker_job_elf(LinkJob *lj) {
|
||||
CodeGen *g = lj->codegen;
|
||||
|
||||
if (lj->link_in_crt) {
|
||||
|
@ -202,6 +203,12 @@ static void construct_linker_job_linux(LinkJob *lj) {
|
|||
lj->args.append(get_libc_static_file(g, crtbegino));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < g->rpath_list.length; i += 1) {
|
||||
Buf *rpath = g->rpath_list.at(i);
|
||||
lj->args.append("-rpath");
|
||||
lj->args.append(buf_ptr(rpath));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
|
||||
const char *lib_dir = g->lib_dirs.at(i);
|
||||
lj->args.append("-L");
|
||||
|
@ -293,7 +300,7 @@ static bool is_target_cyg_mingw(const ZigTarget *target) {
|
|||
(target->os == ZigLLVM_Win32 && target->env_type == ZigLLVM_GNU);
|
||||
}
|
||||
|
||||
static void construct_linker_job_mingw(LinkJob *lj) {
|
||||
static void construct_linker_job_coff(LinkJob *lj) {
|
||||
CodeGen *g = lj->codegen;
|
||||
|
||||
if (lj->link_in_crt) {
|
||||
|
@ -546,7 +553,7 @@ static bool darwin_version_lt(DarwinPlatform *platform, int major, int minor) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static void construct_linker_job_darwin(LinkJob *lj) {
|
||||
static void construct_linker_job_macho(LinkJob *lj) {
|
||||
CodeGen *g = lj->codegen;
|
||||
|
||||
int ver_major;
|
||||
|
@ -686,85 +693,16 @@ static void construct_linker_job_darwin(LinkJob *lj) {
|
|||
}
|
||||
|
||||
static void construct_linker_job(LinkJob *lj) {
|
||||
switch (lj->codegen->zig_target.os) {
|
||||
case ZigLLVM_UnknownOS: // freestanding
|
||||
// TODO we want to solve this problem with LLD, but for now let's
|
||||
// assume gnu binutils
|
||||
// http://lists.llvm.org/pipermail/llvm-dev/2017-February/109835.html
|
||||
return construct_linker_job_linux(lj);
|
||||
case ZigLLVM_Linux:
|
||||
if (lj->codegen->zig_target.arch.arch == ZigLLVM_hexagon) {
|
||||
zig_panic("TODO construct hexagon_TC linker job");
|
||||
} else {
|
||||
return construct_linker_job_linux(lj);
|
||||
}
|
||||
case ZigLLVM_CloudABI:
|
||||
zig_panic("TODO construct CloudABI linker job");
|
||||
case ZigLLVM_Darwin:
|
||||
case ZigLLVM_MacOSX:
|
||||
case ZigLLVM_IOS:
|
||||
return construct_linker_job_darwin(lj);
|
||||
case ZigLLVM_DragonFly:
|
||||
zig_panic("TODO construct DragonFly linker job");
|
||||
case ZigLLVM_OpenBSD:
|
||||
zig_panic("TODO construct OpenBSD linker job");
|
||||
case ZigLLVM_Bitrig:
|
||||
zig_panic("TODO construct Bitrig linker job");
|
||||
case ZigLLVM_NetBSD:
|
||||
zig_panic("TODO construct NetBSD linker job");
|
||||
case ZigLLVM_FreeBSD:
|
||||
zig_panic("TODO construct FreeBSD linker job");
|
||||
case ZigLLVM_Minix:
|
||||
zig_panic("TODO construct Minix linker job");
|
||||
case ZigLLVM_NaCl:
|
||||
zig_panic("TODO construct NaCl_TC linker job");
|
||||
case ZigLLVM_Solaris:
|
||||
zig_panic("TODO construct Solaris linker job");
|
||||
case ZigLLVM_Win32:
|
||||
switch (lj->codegen->zig_target.env_type) {
|
||||
default:
|
||||
if (lj->codegen->zig_target.oformat == ZigLLVM_ELF) {
|
||||
zig_panic("TODO construct Generic_ELF linker job");
|
||||
} else if (lj->codegen->zig_target.oformat == ZigLLVM_MachO) {
|
||||
zig_panic("TODO construct MachO linker job");
|
||||
} else {
|
||||
zig_panic("TODO construct Generic_GCC linker job");
|
||||
}
|
||||
case ZigLLVM_GNU:
|
||||
return construct_linker_job_mingw(lj);
|
||||
case ZigLLVM_Itanium:
|
||||
zig_panic("TODO construct CrossWindowsToolChain linker job");
|
||||
case ZigLLVM_MSVC:
|
||||
case ZigLLVM_UnknownEnvironment:
|
||||
zig_panic("TODO construct MSVC linker job");
|
||||
}
|
||||
case ZigLLVM_CUDA:
|
||||
zig_panic("TODO construct Cuda linker job");
|
||||
default:
|
||||
// Of these targets, Hexagon is the only one that might have
|
||||
// an OS of Linux, in which case it got handled above already.
|
||||
if (lj->codegen->zig_target.arch.arch == ZigLLVM_tce) {
|
||||
zig_panic("TODO construct TCE linker job");
|
||||
} else if (lj->codegen->zig_target.arch.arch == ZigLLVM_hexagon) {
|
||||
zig_panic("TODO construct Hexagon_TC linker job");
|
||||
} else if (lj->codegen->zig_target.arch.arch == ZigLLVM_xcore) {
|
||||
zig_panic("TODO construct XCore linker job");
|
||||
} else if (lj->codegen->zig_target.arch.arch == ZigLLVM_shave) {
|
||||
zig_panic("TODO construct SHAVE linker job");
|
||||
} else if (lj->codegen->zig_target.oformat == ZigLLVM_ELF) {
|
||||
zig_panic("TODO construct Generic_ELF linker job");
|
||||
} else if (lj->codegen->zig_target.oformat == ZigLLVM_MachO) {
|
||||
zig_panic("TODO construct MachO linker job");
|
||||
} else {
|
||||
zig_panic("TODO construct Generic_GCC linker job");
|
||||
}
|
||||
switch (lj->codegen->zig_target.oformat) {
|
||||
case ZigLLVM_UnknownObjectFormat:
|
||||
zig_unreachable();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void ensure_we_have_linker_path(CodeGen *g) {
|
||||
if (!g->linker_path || buf_len(g->linker_path) == 0) {
|
||||
zig_panic("zig does not know the path to the linker");
|
||||
case ZigLLVM_COFF:
|
||||
return construct_linker_job_coff(lj);
|
||||
case ZigLLVM_ELF:
|
||||
return construct_linker_job_elf(lj);
|
||||
case ZigLLVM_MachO:
|
||||
return construct_linker_job_macho(lj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -838,44 +776,23 @@ void codegen_link(CodeGen *g, const char *out_file) {
|
|||
}
|
||||
|
||||
lj.link_in_crt = (g->link_libc && g->out_type == OutTypeExe);
|
||||
ensure_we_have_linker_path(g);
|
||||
|
||||
construct_linker_job(&lj);
|
||||
|
||||
|
||||
if (g->verbose) {
|
||||
fprintf(stderr, "%s", buf_ptr(g->linker_path));
|
||||
fprintf(stderr, "link");
|
||||
for (size_t i = 0; i < lj.args.length; i += 1) {
|
||||
fprintf(stderr, " %s", lj.args.at(i));
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
Buf ld_stderr = BUF_INIT;
|
||||
Buf ld_stdout = BUF_INIT;
|
||||
Termination term;
|
||||
int err = os_exec_process(buf_ptr(g->linker_path), lj.args, &term, &ld_stderr, &ld_stdout);
|
||||
if (err) {
|
||||
fprintf(stderr, "linker not found: '%s'\n", buf_ptr(g->linker_path));
|
||||
exit(1);
|
||||
}
|
||||
Buf diag = BUF_INIT;
|
||||
|
||||
if (term.how != TerminationIdClean || term.code != 0) {
|
||||
if (term.how == TerminationIdClean) {
|
||||
fprintf(stderr, "linker failed with return code %d\n", term.code);
|
||||
} else if (term.how == TerminationIdSignaled) {
|
||||
fprintf(stderr, "linker failed with signal %d\n", term.code);
|
||||
} else {
|
||||
fprintf(stderr, "linker failed\n");
|
||||
}
|
||||
fprintf(stderr, "%s ", buf_ptr(g->linker_path));
|
||||
for (size_t i = 0; i < lj.args.length; i += 1) {
|
||||
fprintf(stderr, "%s ", lj.args.at(i));
|
||||
}
|
||||
fprintf(stderr, "\n%s\n", buf_ptr(&ld_stderr));
|
||||
if (!ZigLLDLink(g->zig_target.oformat, lj.args.items, lj.args.length, &diag)) {
|
||||
fprintf(stderr, "%s\n", buf_ptr(&diag));
|
||||
exit(1);
|
||||
} else if (buf_len(&ld_stderr)) {
|
||||
fprintf(stderr, "%s\n", buf_ptr(&ld_stderr));
|
||||
}
|
||||
|
||||
if (g->out_type == OutTypeLib ||
|
||||
|
|
23
src/main.cpp
23
src/main.cpp
|
@ -43,6 +43,7 @@ static int usage(const char *arg0) {
|
|||
" -isystem [dir] add additional search path for other .h files\n"
|
||||
" -dirafter [dir] same as -isystem but do it last\n"
|
||||
" --library-path [dir] add a directory to the library search path\n"
|
||||
" -L[dir] alias for --library-path\n"
|
||||
" --library [lib] link against lib\n"
|
||||
" --target-arch [name] specify target architecture\n"
|
||||
" --target-os [name] specify target operating system\n"
|
||||
|
@ -57,6 +58,7 @@ static int usage(const char *arg0) {
|
|||
" -framework [name] (darwin only) link against framework\n"
|
||||
" --check-unused perform semantic analysis on unused declarations\n"
|
||||
" --linker-script [path] use a custom linker script\n"
|
||||
" -rpath [path] add a directory to the runtime library search path\n"
|
||||
, arg0);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
@ -123,8 +125,6 @@ int main(int argc, char **argv) {
|
|||
const char *libc_include_dir = nullptr;
|
||||
const char *zig_std_dir = nullptr;
|
||||
const char *dynamic_linker = nullptr;
|
||||
const char *linker_path = nullptr;
|
||||
const char *ar_path = nullptr;
|
||||
ZigList<const char *> clang_argv = {0};
|
||||
ZigList<const char *> lib_dirs = {0};
|
||||
ZigList<const char *> link_libs = {0};
|
||||
|
@ -142,6 +142,7 @@ int main(int argc, char **argv) {
|
|||
const char *mios_version_min = nullptr;
|
||||
bool check_unused = false;
|
||||
const char *linker_script = nullptr;
|
||||
ZigList<const char *> rpath_list = {0};
|
||||
|
||||
for (int i = 1; i < argc; i += 1) {
|
||||
char *arg = argv[i];
|
||||
|
@ -165,6 +166,9 @@ int main(int argc, char **argv) {
|
|||
rdynamic = true;
|
||||
} else if (strcmp(arg, "--check-unused") == 0) {
|
||||
check_unused = true;
|
||||
} else if (arg[1] == 'L' && arg[2] != 0) {
|
||||
// alias for --library-path
|
||||
lib_dirs.append(&arg[2]);
|
||||
} else if (i + 1 >= argc) {
|
||||
return usage(arg0);
|
||||
} else {
|
||||
|
@ -205,17 +209,13 @@ int main(int argc, char **argv) {
|
|||
zig_std_dir = argv[i];
|
||||
} else if (strcmp(arg, "--dynamic-linker") == 0) {
|
||||
dynamic_linker = argv[i];
|
||||
} else if (strcmp(arg, "--ld-path") == 0) {
|
||||
linker_path = argv[i];
|
||||
} else if (strcmp(arg, "--ar-path") == 0) {
|
||||
ar_path = argv[i];
|
||||
} else if (strcmp(arg, "-isystem") == 0) {
|
||||
clang_argv.append("-isystem");
|
||||
clang_argv.append(argv[i]);
|
||||
} else if (strcmp(arg, "-dirafter") == 0) {
|
||||
clang_argv.append("-dirafter");
|
||||
clang_argv.append(argv[i]);
|
||||
} else if (strcmp(arg, "--library-path") == 0) {
|
||||
} else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) {
|
||||
lib_dirs.append(argv[i]);
|
||||
} else if (strcmp(arg, "--library") == 0) {
|
||||
link_libs.append(argv[i]);
|
||||
|
@ -235,6 +235,8 @@ int main(int argc, char **argv) {
|
|||
frameworks.append(argv[i]);
|
||||
} else if (strcmp(arg, "--linker-script") == 0) {
|
||||
linker_script = argv[i];
|
||||
} else if (strcmp(arg, "-rpath") == 0) {
|
||||
rpath_list.append(argv[i]);
|
||||
} else {
|
||||
fprintf(stderr, "Invalid argument: %s\n", arg);
|
||||
return usage(arg0);
|
||||
|
@ -373,10 +375,6 @@ int main(int argc, char **argv) {
|
|||
codegen_set_zig_std_dir(g, buf_create_from_str(zig_std_dir));
|
||||
if (dynamic_linker)
|
||||
codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker));
|
||||
if (linker_path)
|
||||
codegen_set_linker_path(g, buf_create_from_str(linker_path));
|
||||
if (ar_path)
|
||||
codegen_set_ar_path(g, buf_create_from_str(ar_path));
|
||||
codegen_set_verbose(g, verbose);
|
||||
codegen_set_errmsg_color(g, color);
|
||||
|
||||
|
@ -389,6 +387,9 @@ int main(int argc, char **argv) {
|
|||
for (size_t i = 0; i < frameworks.length; i += 1) {
|
||||
codegen_add_framework(g, frameworks.at(i));
|
||||
}
|
||||
for (size_t i = 0; i < rpath_list.length; i += 1) {
|
||||
codegen_add_rpath(g, rpath_list.at(i));
|
||||
}
|
||||
|
||||
codegen_set_windows_subsystem(g, mwindows, mconsole);
|
||||
codegen_set_windows_unicode(g, municode);
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
|
||||
#include <llvm/Transforms/Scalar.h>
|
||||
|
||||
#include <lld/Driver/Driver.h>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) {
|
||||
|
@ -790,3 +792,36 @@ Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine_ref) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag_buf) {
|
||||
ArrayRef<const char *> array_ref_args(args, arg_count);
|
||||
|
||||
buf_resize(diag_buf, 0);
|
||||
class MyOStream: public raw_ostream {
|
||||
public:
|
||||
MyOStream(Buf *_diag_buf) : raw_ostream(true), diag_buf(_diag_buf) {
|
||||
|
||||
}
|
||||
void write_impl(const char *ptr, size_t len) override {
|
||||
buf_append_mem(diag_buf, ptr, len);
|
||||
}
|
||||
uint64_t current_pos() const override {
|
||||
return buf_len(diag_buf);
|
||||
}
|
||||
Buf *diag_buf;
|
||||
} diag(diag_buf);
|
||||
|
||||
switch (oformat) {
|
||||
case ZigLLVM_UnknownObjectFormat:
|
||||
zig_unreachable();
|
||||
|
||||
case ZigLLVM_COFF:
|
||||
return lld::coff::link(array_ref_args);
|
||||
|
||||
case ZigLLVM_ELF:
|
||||
return lld::elf::link(array_ref_args, false, diag);
|
||||
|
||||
case ZigLLVM_MachO:
|
||||
return lld::mach_o::link(array_ref_args, diag);
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
|
|
@ -351,6 +351,9 @@ const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type);
|
|||
* This stuff is not LLVM API but it depends on the LLVM C++ API so we put it here.
|
||||
*/
|
||||
struct Buf;
|
||||
|
||||
bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag);
|
||||
|
||||
void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *sub_arch_type,
|
||||
ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type,
|
||||
ZigLLVM_ObjectFormatType *oformat);
|
||||
|
|
Loading…
Reference in New Issue