Browse Source

set -rpath to \$ORIGIN and expect libraries next to executable just like Windows

Laytan 1 year ago
parent
commit
1a7c1d107a
2 changed files with 8 additions and 20 deletions
  1. 8 6
      src/linker.cpp
  2. 0 14
      src/parser.cpp

+ 8 - 6
src/linker.cpp

@@ -548,14 +548,12 @@ 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
 								// 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));
+
+								// NOTE(laytan): If .so, I think we can check for the existence of "$OUT_DIRECTORY/$lib" here and print an error telling the user to copy over the file, or we can even do the copy for them?
+
 							} 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 +641,10 @@ gb_internal i32 linker_stage(LinkerData *gen) {
 				}
 				}
 			}
 			}
 
 
+			// Set the rpath to the $ORIGIN (the path of the executable),
+			// so that dynamic libraries are looked for at that path.
+			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) {

+ 0 - 14
src/parser.cpp

@@ -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)) {