mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-30 19:30:06 +00:00
Merge pull request #4206 from laytan/improve-linking-shared-libraries
Improve linking shared libraries
This commit is contained in:
@@ -257,16 +257,16 @@ jobs:
|
|||||||
run: sudo apt-get install -y qemu-user qemu-user-static gcc-12-riscv64-linux-gnu libc6-riscv64-cross
|
run: sudo apt-get install -y qemu-user qemu-user-static gcc-12-riscv64-linux-gnu libc6-riscv64-cross
|
||||||
|
|
||||||
- name: Odin run
|
- name: Odin run
|
||||||
run: ./odin run examples/demo -vet -strict-style -disallow-do -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static"
|
run: ./odin run examples/demo -vet -strict-style -disallow-do -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" -no-rpath
|
||||||
|
|
||||||
- name: Odin run -debug
|
- name: Odin run -debug
|
||||||
run: ./odin run examples/demo -debug -vet -strict-style -disallow-do -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static"
|
run: ./odin run examples/demo -debug -vet -strict-style -disallow-do -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" -no-rpath
|
||||||
|
|
||||||
- name: Normal Core library tests
|
- name: Normal Core library tests
|
||||||
run: ./odin test tests/core/normal.odin -file -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static"
|
run: ./odin test tests/core/normal.odin -file -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" -no-rpath
|
||||||
|
|
||||||
- name: Optimized Core library tests
|
- name: Optimized Core library tests
|
||||||
run: ./odin test tests/core/speed.odin -o:speed -file -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static"
|
run: ./odin test tests/core/speed.odin -o:speed -file -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" -no-rpath
|
||||||
|
|
||||||
- name: Internals tests
|
- name: Internals tests
|
||||||
run: ./odin test tests/internal -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static"
|
run: ./odin test tests/internal -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" -no-rpath
|
||||||
|
|||||||
@@ -411,6 +411,7 @@ struct BuildContext {
|
|||||||
bool no_dynamic_literals;
|
bool no_dynamic_literals;
|
||||||
bool no_output_files;
|
bool no_output_files;
|
||||||
bool no_crt;
|
bool no_crt;
|
||||||
|
bool no_rpath;
|
||||||
bool no_entry_point;
|
bool no_entry_point;
|
||||||
bool no_thread_local;
|
bool no_thread_local;
|
||||||
bool use_lld;
|
bool use_lld;
|
||||||
|
|||||||
+11
-7
@@ -548,14 +548,8 @@ gb_internal i32 linker_stage(LinkerData *gen) {
|
|||||||
// available at runtime wherever the executable is run, so we make require those to be
|
// available at runtime wherever the executable is run, so we make require those to be
|
||||||
// local to the executable (unless the system collection is used, in which case we search
|
// local to the executable (unless the system collection is used, in which case we search
|
||||||
// the system library paths for the library file).
|
// the system library paths for the library file).
|
||||||
if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o"))) {
|
if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o")) || string_ends_with(lib, str_lit(".so")) || string_contains_string(lib, str_lit(".so."))) {
|
||||||
// static libs and object files, absolute full path relative to the file in which the lib was imported from
|
|
||||||
lib_str = gb_string_append_fmt(lib_str, " -l:\"%.*s\" ", LIT(lib));
|
lib_str = gb_string_append_fmt(lib_str, " -l:\"%.*s\" ", LIT(lib));
|
||||||
} else if (string_ends_with(lib, str_lit(".so")) || string_contains_string(lib, str_lit(".so."))) {
|
|
||||||
// dynamic lib, relative path to executable
|
|
||||||
// NOTE(vassvik): it is the user's responsibility to make sure the shared library files are visible
|
|
||||||
// at runtime to the executable
|
|
||||||
lib_str = gb_string_append_fmt(lib_str, " -l:\"%s/%.*s\" ", cwd, LIT(lib));
|
|
||||||
} else {
|
} else {
|
||||||
// dynamic or static system lib, just link regularly searching system library paths
|
// dynamic or static system lib, just link regularly searching system library paths
|
||||||
lib_str = gb_string_append_fmt(lib_str, " -l%.*s ", LIT(lib));
|
lib_str = gb_string_append_fmt(lib_str, " -l%.*s ", LIT(lib));
|
||||||
@@ -643,6 +637,16 @@ gb_internal i32 linker_stage(LinkerData *gen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!build_context.no_rpath) {
|
||||||
|
// Set the rpath to the $ORIGIN/@loader_path (the path of the executable),
|
||||||
|
// so that dynamic libraries are looked for at that path.
|
||||||
|
if (build_context.metrics.os == TargetOs_darwin) {
|
||||||
|
link_settings = gb_string_appendc(link_settings, "-Wl,-rpath,@loader_path ");
|
||||||
|
} else {
|
||||||
|
link_settings = gb_string_appendc(link_settings, "-Wl,-rpath,\\$ORIGIN ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!build_context.no_crt) {
|
if (!build_context.no_crt) {
|
||||||
platform_lib_str = gb_string_appendc(platform_lib_str, "-lm ");
|
platform_lib_str = gb_string_appendc(platform_lib_str, "-lm ");
|
||||||
if (build_context.metrics.os == TargetOs_darwin) {
|
if (build_context.metrics.os == TargetOs_darwin) {
|
||||||
|
|||||||
@@ -325,6 +325,7 @@ enum BuildFlagKind {
|
|||||||
BuildFlag_NoTypeAssert,
|
BuildFlag_NoTypeAssert,
|
||||||
BuildFlag_NoDynamicLiterals,
|
BuildFlag_NoDynamicLiterals,
|
||||||
BuildFlag_NoCRT,
|
BuildFlag_NoCRT,
|
||||||
|
BuildFlag_NoRPath,
|
||||||
BuildFlag_NoEntryPoint,
|
BuildFlag_NoEntryPoint,
|
||||||
BuildFlag_UseLLD,
|
BuildFlag_UseLLD,
|
||||||
BuildFlag_UseSeparateModules,
|
BuildFlag_UseSeparateModules,
|
||||||
@@ -533,6 +534,7 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
|||||||
add_flag(&build_flags, BuildFlag_NoThreadLocal, str_lit("no-thread-local"), BuildFlagParam_None, Command__does_check);
|
add_flag(&build_flags, BuildFlag_NoThreadLocal, str_lit("no-thread-local"), BuildFlagParam_None, Command__does_check);
|
||||||
add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None, Command__does_check);
|
add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None, Command__does_check);
|
||||||
add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None, Command__does_build);
|
add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None, Command__does_build);
|
||||||
|
add_flag(&build_flags, BuildFlag_NoRPath, str_lit("no-rpath"), BuildFlagParam_None, Command__does_build);
|
||||||
add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check &~ Command_test);
|
add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check &~ Command_test);
|
||||||
add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None, Command__does_build);
|
add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None, Command__does_build);
|
||||||
add_flag(&build_flags, BuildFlag_UseSeparateModules, str_lit("use-separate-modules"), BuildFlagParam_None, Command__does_build);
|
add_flag(&build_flags, BuildFlag_UseSeparateModules, str_lit("use-separate-modules"), BuildFlagParam_None, Command__does_build);
|
||||||
@@ -1183,6 +1185,9 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
|||||||
case BuildFlag_NoCRT:
|
case BuildFlag_NoCRT:
|
||||||
build_context.no_crt = true;
|
build_context.no_crt = true;
|
||||||
break;
|
break;
|
||||||
|
case BuildFlag_NoRPath:
|
||||||
|
build_context.no_rpath = true;
|
||||||
|
break;
|
||||||
case BuildFlag_NoEntryPoint:
|
case BuildFlag_NoEntryPoint:
|
||||||
build_context.no_entry_point = true;
|
build_context.no_entry_point = true;
|
||||||
break;
|
break;
|
||||||
@@ -2315,6 +2320,10 @@ gb_internal void print_show_help(String const arg0, String const &command) {
|
|||||||
print_usage_line(2, "Disables automatic linking with the C Run Time.");
|
print_usage_line(2, "Disables automatic linking with the C Run Time.");
|
||||||
print_usage_line(0, "");
|
print_usage_line(0, "");
|
||||||
|
|
||||||
|
print_usage_line(1, "-no-rpath");
|
||||||
|
print_usage_line(2, "Disables automatic addition of an rpath linked to the executable directory.");
|
||||||
|
print_usage_line(0, "");
|
||||||
|
|
||||||
print_usage_line(1, "-no-thread-local");
|
print_usage_line(1, "-no-thread-local");
|
||||||
print_usage_line(2, "Ignores @thread_local attribute, effectively treating the program as if it is single-threaded.");
|
print_usage_line(2, "Ignores @thread_local attribute, effectively treating the program as if it is single-threaded.");
|
||||||
print_usage_line(0, "");
|
print_usage_line(0, "");
|
||||||
|
|||||||
@@ -5932,20 +5932,6 @@ gb_internal bool determine_path_from_string(BlockingMutex *file_mutex, Ast *node
|
|||||||
do_error(node, "Unknown library collection: '%.*s'", LIT(collection_name));
|
do_error(node, "Unknown library collection: '%.*s'", LIT(collection_name));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
#if !defined(GB_SYSTEM_WINDOWS)
|
|
||||||
// @NOTE(vassvik): foreign imports of shared libraries that are not in the system collection on
|
|
||||||
// linux/mac have to be local to the executable for consistency with shared libraries.
|
|
||||||
// Unix does not have a concept of "import library" for shared/dynamic libraries,
|
|
||||||
// so we need to pass the relative path to the linker, and add the current
|
|
||||||
// working directory of the exe to the library search paths.
|
|
||||||
// Static libraries can be linked directly with the full pathname
|
|
||||||
//
|
|
||||||
if (node->kind == Ast_ForeignImportDecl && (string_ends_with(file_str, str_lit(".so")) || string_contains_string(file_str, str_lit(".so.")))) {
|
|
||||||
*path = file_str;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_package_name_reserved(file_str)) {
|
if (is_package_name_reserved(file_str)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user