mirror of
https://github.com/ziglang/zig.git
synced 2025-01-23 18:31:44 +00:00
add --each-lib-rpath option and corresponding config option
This adds an rpath entry for each used dynamic library directory. This is necessary on some systems such as NixOS.
This commit is contained in:
parent
d10bbd28e9
commit
7efa2cd81c
@ -18,6 +18,7 @@ set(ZIG_LIBC_LIB_DIR "" CACHE STRING "Default native target libc directory where
|
||||
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_DYNAMIC_LINKER "" CACHE STRING "Override dynamic linker for native target")
|
||||
set(ZIG_EACH_LIB_RPATH off CACHE BOOL "Add each dynamic library to rpath for native target")
|
||||
|
||||
option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF)
|
||||
|
||||
|
@ -1413,6 +1413,7 @@ struct CodeGen {
|
||||
uint32_t test_fn_count;
|
||||
|
||||
bool check_unused;
|
||||
bool each_lib_rpath;
|
||||
|
||||
ZigList<AstNode *> error_decls;
|
||||
bool generate_error_name_table;
|
||||
|
@ -90,6 +90,7 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
|
||||
g->libc_static_lib_dir = buf_create_from_str("");
|
||||
g->libc_include_dir = buf_create_from_str("");
|
||||
g->darwin_linker_version = buf_create_from_str("");
|
||||
g->each_lib_rpath = false;
|
||||
} else {
|
||||
// native compilation, we can rely on the configuration stuff
|
||||
g->is_native_target = true;
|
||||
@ -100,6 +101,9 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
|
||||
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->darwin_linker_version = buf_create_from_str(ZIG_HOST_LINK_VERSION);
|
||||
#ifdef ZIG_EACH_LIB_RPATH
|
||||
g->each_lib_rpath = true;
|
||||
#endif
|
||||
|
||||
if (g->zig_target.os == ZigLLVM_Darwin ||
|
||||
g->zig_target.os == ZigLLVM_MacOSX ||
|
||||
@ -138,6 +142,10 @@ void codegen_set_check_unused(CodeGen *g, bool check_unused) {
|
||||
g->check_unused = check_unused;
|
||||
}
|
||||
|
||||
void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) {
|
||||
g->each_lib_rpath = each_lib_rpath;
|
||||
}
|
||||
|
||||
void codegen_set_errmsg_color(CodeGen *g, ErrColor err_color) {
|
||||
g->err_color = err_color;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
|
||||
void codegen_set_is_release(CodeGen *codegen, bool is_release);
|
||||
void codegen_set_is_test(CodeGen *codegen, bool is_test);
|
||||
void codegen_set_check_unused(CodeGen *codegen, bool check_unused);
|
||||
void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);
|
||||
|
||||
void codegen_set_is_static(CodeGen *codegen, bool is_static);
|
||||
void codegen_set_strip(CodeGen *codegen, bool strip);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@"
|
||||
#define ZIG_HOST_LINK_VERSION "@ZIG_HOST_LINK_VERSION@"
|
||||
|
||||
#cmakedefine ZIG_EACH_LIB_RPATH
|
||||
#cmakedefine ZIG_LLVM_OLD_CXX_ABI
|
||||
|
||||
// Only used for running tests before installing.
|
||||
|
32
src/link.cpp
32
src/link.cpp
@ -17,6 +17,7 @@ struct LinkJob {
|
||||
ZigList<const char *> args;
|
||||
bool link_in_crt;
|
||||
Buf out_file_o;
|
||||
HashMap<Buf *, bool, buf_hash, buf_eql_buf> rpath_table;
|
||||
};
|
||||
|
||||
static const char *get_libc_file(CodeGen *g, const char *file) {
|
||||
@ -148,6 +149,16 @@ static const char *getLDMOption(const ZigTarget *t) {
|
||||
}
|
||||
}
|
||||
|
||||
static void add_rpath(LinkJob *lj, Buf *rpath) {
|
||||
if (lj->rpath_table.maybe_get(rpath) != nullptr)
|
||||
return;
|
||||
|
||||
lj->args.append("-rpath");
|
||||
lj->args.append(buf_ptr(rpath));
|
||||
|
||||
lj->rpath_table.put(rpath, true);
|
||||
}
|
||||
|
||||
static void construct_linker_job_elf(LinkJob *lj) {
|
||||
CodeGen *g = lj->codegen;
|
||||
|
||||
@ -205,8 +216,24 @@ static void construct_linker_job_elf(LinkJob *lj) {
|
||||
|
||||
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));
|
||||
add_rpath(lj, rpath);
|
||||
}
|
||||
if (g->each_lib_rpath) {
|
||||
for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
|
||||
const char *lib_dir = g->lib_dirs.at(i);
|
||||
for (size_t i = 0; i < g->link_libs.length; i += 1) {
|
||||
Buf *link_lib = g->link_libs.at(i);
|
||||
bool does_exist;
|
||||
Buf *test_path = buf_sprintf("%s/lib%s.so", lib_dir, buf_ptr(link_lib));
|
||||
if (os_file_exists(test_path, &does_exist) != ErrorNone) {
|
||||
zig_panic("link: unable to check if file exists: %s", buf_ptr(test_path));
|
||||
}
|
||||
if (does_exist) {
|
||||
add_rpath(lj, buf_create_from_str(lib_dir));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
|
||||
@ -708,6 +735,7 @@ static void construct_linker_job(LinkJob *lj) {
|
||||
|
||||
void codegen_link(CodeGen *g, const char *out_file) {
|
||||
LinkJob lj = {0};
|
||||
lj.rpath_table.init(4);
|
||||
lj.codegen = g;
|
||||
if (out_file) {
|
||||
buf_init_from_str(&lj.out_file, out_file);
|
||||
|
@ -58,7 +58,8 @@ 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"
|
||||
" -rpath [path] add directory to the runtime library search path\n"
|
||||
" --each-lib-rpath add rpath for each used dynamic library\n"
|
||||
, arg0);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@ -143,6 +144,7 @@ int main(int argc, char **argv) {
|
||||
bool check_unused = false;
|
||||
const char *linker_script = nullptr;
|
||||
ZigList<const char *> rpath_list = {0};
|
||||
bool each_lib_rpath = false;
|
||||
|
||||
for (int i = 1; i < argc; i += 1) {
|
||||
char *arg = argv[i];
|
||||
@ -166,6 +168,8 @@ int main(int argc, char **argv) {
|
||||
rdynamic = true;
|
||||
} else if (strcmp(arg, "--check-unused") == 0) {
|
||||
check_unused = true;
|
||||
} else if (strcmp(arg, "--each-lib-rpath") == 0) {
|
||||
each_lib_rpath = true;
|
||||
} else if (arg[1] == 'L' && arg[2] != 0) {
|
||||
// alias for --library-path
|
||||
lib_dirs.append(&arg[2]);
|
||||
@ -351,6 +355,8 @@ int main(int argc, char **argv) {
|
||||
codegen_set_is_test(g, cmd == CmdTest);
|
||||
codegen_set_linker_script(g, linker_script);
|
||||
codegen_set_check_unused(g, check_unused);
|
||||
if (each_lib_rpath)
|
||||
codegen_set_each_lib_rpath(g, each_lib_rpath);
|
||||
|
||||
codegen_set_clang_argv(g, clang_argv.items, clang_argv.length);
|
||||
codegen_set_strip(g, strip);
|
||||
|
@ -218,6 +218,15 @@ int os_fetch_file(FILE *f, Buf *out_buf) {
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
int os_file_exists(Buf *full_path, bool *result) {
|
||||
#if defined(ZIG_OS_POSIX)
|
||||
*result = access(buf_ptr(full_path), F_OK) != -1;
|
||||
return 0;
|
||||
#else
|
||||
zig_panic("TODO implement os_file_exists for non-posix");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(ZIG_OS_POSIX)
|
||||
static int os_exec_process_posix(const char *exe, ZigList<const char *> &args,
|
||||
Termination *term, Buf *out_stderr, Buf *out_stdout)
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "list.hpp"
|
||||
#include "buffer.hpp"
|
||||
#include "error.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@ -40,7 +41,6 @@ bool os_path_is_absolute(Buf *path);
|
||||
|
||||
void os_write_file(Buf *full_path, Buf *contents);
|
||||
|
||||
|
||||
int os_fetch_file(FILE *file, Buf *out_contents);
|
||||
int os_fetch_file_path(Buf *full_path, Buf *out_contents);
|
||||
|
||||
@ -51,4 +51,6 @@ bool os_stderr_tty(void);
|
||||
int os_buf_to_tmp_file(Buf *contents, Buf *suffix, Buf *out_tmp_path);
|
||||
int os_delete_file(Buf *path);
|
||||
|
||||
int os_file_exists(Buf *full_path, bool *result);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user