Browse Source

Merge pull request #775 from Tetralux/fix-type-table-unix

Fix -build-mode:shared type table on Unix
gingerBill 4 năm trước cách đây
mục cha
commit
7a7fddd1df
1 tập tin đã thay đổi với 45 bổ sung37 xóa
  1. 45 37
      src/main.cpp

+ 45 - 37
src/main.cpp

@@ -342,9 +342,9 @@ i32 linker_stage(lbGenerator *gen) {
 					lib_name = remove_extension_from_path(lib_name);
 					lib_str = gb_string_append_fmt(lib_str, " -framework %.*s ", LIT(lib_name));
 				} else if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o")) || string_ends_with(lib, str_lit(".dylib"))) {
-          				// For:
-          				// object 
-          				// dynamic lib
+					// For:
+					// object
+					// dynamic lib
 					// static libs, absolute full path relative to the file in which the lib was imported from
 					lib_str = gb_string_append_fmt(lib_str, " %.*s ", LIT(lib));
 				} else {
@@ -382,20 +382,33 @@ i32 linker_stage(lbGenerator *gen) {
 		// Unlike the Win32 linker code, the output_ext includes the dot, because
 		// typically executable files on *NIX systems don't have extensions.
 		String output_ext = {};
-		char const *link_settings = "";
+		gbString link_settings = gb_string_make_reserve(heap_allocator(), 32);
 		char const *linker;
 		if (build_context.build_mode == BuildMode_DynamicLibrary) {
+			// NOTE(tetra, 2020-11-06): __$startup_runtime must be called at DLL load time.
+			// Clang, for some reason, won't let us pass the '-init' flag that lets us do this,
+			// so use ld instead.
+			// :UseLDForShared
+			linker = "ld";
+			link_settings = gb_string_appendc(link_settings, "-init '__$startup_runtime' ");
 			// Shared libraries are .dylib on MacOS and .so on Linux.
 			#if defined(GB_SYSTEM_OSX)
 				output_ext = STR_LIT(".dylib");
-				link_settings = "-dylib -dynamic";
+				link_settings = gb_string_appendc(link_settings, "-dylib -dynamic ");
 			#else
 				output_ext = STR_LIT(".so");
-				link_settings = "-shared";
+				link_settings = gb_string_appendc(link_settings, "-shared ");
 			#endif
 		} else {
-			// TODO: Do I need anything here?
-			link_settings = "";
+			#if defined(GB_SYSTEM_OSX)
+				linker = "ld";
+			#else
+				// TODO(zangent): Figure out how to make ld work on Linux.
+				//   It probably has to do with including the entire CRT, but
+				//   that's quite a complicated issue to solve while remaining distro-agnostic.
+				//   Clang can figure out linker flags for us, and that's good enough _for now_.
+				linker = "clang -Wno-unused-command-line-argument";
+			#endif
 		}
 
 		if (build_context.out_filepath.len > 0) {
@@ -406,16 +419,6 @@ i32 linker_stage(lbGenerator *gen) {
 			}
 		}
 
-		#if defined(GB_SYSTEM_OSX)
-			linker = "ld";
-		#else
-			// TODO(zangent): Figure out how to make ld work on Linux.
-			//   It probably has to do with including the entire CRT, but
-			//   that's quite a complicated issue to solve while remaining distro-agnostic.
-			//   Clang can figure out linker flags for us, and that's good enough _for now_.
-			linker = "clang -Wno-unused-command-line-argument";
-		#endif
-
 		exit_code = system_exec_command_line_app("ld-link",
 			"%s %s -o \"%.*s%.*s\" %s "
 			" %s "
@@ -443,7 +446,7 @@ i32 linker_stage(lbGenerator *gen) {
 		if (exit_code != 0) {
 			return exit_code;
 		}
-    
+
 	#if defined(GB_SYSTEM_OSX)
 		if (build_context.ODIN_DEBUG) {
 			// NOTE: macOS links DWARF symbols dynamically. Dsymutil will map the stubs in the exe
@@ -2136,11 +2139,11 @@ int main(int arg_count, char const **arg_ptr) {
 						String lib_name = lib;
 						lib_name = remove_extension_from_path(lib_name);
 						lib_str = gb_string_append_fmt(lib_str, " -framework %.*s ", LIT(lib_name));
-						
+
 				} else if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o")) || string_ends_with(lib, str_lit(".dylib"))) {
-          				// For:
-          				// object 
-          				// dynamic lib
+					// For:
+					// object
+					// dynamic lib
 					// static libs, absolute full path relative to the file in which the lib was imported from
 					lib_str = gb_string_append_fmt(lib_str, " %.*s ", LIT(lib));
 				} else {
@@ -2171,22 +2174,36 @@ int main(int arg_count, char const **arg_ptr) {
 			// Unlike the Win32 linker code, the output_ext includes the dot, because
 			// typically executable files on *NIX systems don't have extensions.
 			String output_ext = {};
-			char const *link_settings = "";
+			gbString link_settings = gb_string_make_reserve(heap_allocator(), 32);
 			char const *linker;
 			if (build_context.build_mode == BuildMode_DynamicLibrary) {
+				// NOTE(tetra, 2020-11-06): __$startup_runtime must be called at DLL load time.
+				// Clang, for some reason, won't let us pass the '-init' flag that lets us do this,
+				// so use ld instead.
+				// :UseLDForShared
+				linker = "ld";
+				link_settings = gb_string_appendc(link_settings, "-init '__$startup_runtime' ");
 				// Shared libraries are .dylib on MacOS and .so on Linux.
 				#if defined(GB_SYSTEM_OSX)
 					output_ext = STR_LIT(".dylib");
-					link_settings = "-dylib -dynamic";
+					link_settings = gb_string_appendc(link_settings, "-dylib -dynamic ");
 				#else
 					output_ext = STR_LIT(".so");
-					link_settings = "-shared";
+					link_settings = gb_string_appendc(link_settings, "-shared ");
 				#endif
 			} else {
-				// TODO: Do I need anything here?
-				link_settings = "";
+				#if defined(GB_SYSTEM_OSX)
+					linker = "ld";
+				#else
+					// TODO(zangent): Figure out how to make ld work on Linux.
+					//   It probably has to do with including the entire CRT, but
+					//   that's quite a complicated issue to solve while remaining distro-agnostic.
+					//   Clang can figure out linker flags for us, and that's good enough _for now_.
+					linker = "clang -Wno-unused-command-line-argument";
+				#endif
 			}
 
+
 			if (build_context.out_filepath.len > 0) {
 				//NOTE(thebirk): We have a custom -out arguments, so we should use the extension from that
 				isize pos = string_extension_position(build_context.out_filepath);
@@ -2195,15 +2212,6 @@ int main(int arg_count, char const **arg_ptr) {
 				}
 			}
 
-			#if defined(GB_SYSTEM_OSX)
-				linker = "ld";
-			#else
-				// TODO(zangent): Figure out how to make ld work on Linux.
-				//   It probably has to do with including the entire CRT, but
-				//   that's quite a complicated issue to solve while remaining distro-agnostic.
-				//   Clang can figure out linker flags for us, and that's good enough _for now_.
-				linker = "clang -Wno-unused-command-line-argument";
-			#endif
 
 			exit_code = system_exec_command_line_app("ld-link",
 				"%s \"%.*s.o\" -o \"%.*s%.*s\" %s "