Browse Source

Merge pull request #140 from vassvik/master

Fixed foreign import for linux. Modified .gitignore to ignore temp files and files in shared/. Added a Makefile for linux
gingerBill 7 years ago
parent
commit
1d2eb8055e
5 changed files with 88 additions and 11 deletions
  1. 10 0
      .gitignore
  2. 24 0
      Makefile
  3. 7 3
      build.sh
  4. 32 8
      src/main.cpp
  5. 15 0
      src/parser.cpp

+ 10 - 0
.gitignore

@@ -257,7 +257,17 @@ paket-files/
 builds/
 bin/
 *.exe
+*.obj
+*.pdb
 
 # - Linux/MacOS
 odin
 odin.dSYM
+
+
+# shared collection
+shared/
+
+# temp files
+* .ll
+*.bc

+ 24 - 0
Makefile

@@ -0,0 +1,24 @@
+DISABLED_WARNINGS=-Wno-switch -Wno-writable-strings -Wno-tautological-compare -Wno-macro-redefined #-Wno-pointer-sign -Wno-tautological-constant-out-of-range-compare  
+LDFLAGS=-pthread -ldl -lm -lstdc++
+CFLAGS=-std=c++11
+CC=clang
+
+OS=$(shell uname)
+
+ifeq ($(OS), DARWIN)
+	LDFLAGS=$(LDFLAGS) -liconv
+endif
+
+all: debug demo
+
+demo:
+	./odin run examples/demo.odin
+
+debug:
+	$(CC) src/main.cpp $(DISABLED_WARNINGS) $(CFLAGS) -g $(LDFLAGS) -o odin
+
+release:
+	$(CC) src/main.cpp $(DISABLED_WARNINGS) $(CFLAGS) -O3 -march=native $(LDFLAGS) -o odin
+	
+
+	

+ 7 - 3
build.sh

@@ -1,15 +1,19 @@
 #!/bin/bash
 
-release_mode=0
+release_mode=$1
 
-warnings_to_disable="-std=c++11 -g -Wno-switch -Wno-pointer-sign -Wno-tautological-constant-out-of-range-compare -Wno-tautological-compare -Wno-macro-redefined -Wno-writable-strings"
+warnings_to_disable="-std=c++11 -Wno-switch -Wno-pointer-sign -Wno-tautological-constant-out-of-range-compare -Wno-tautological-compare -Wno-macro-redefined -Wno-writable-strings"
 libraries="-pthread -ldl -lm -lstdc++"
 other_args=""
 compiler="clang"
 
 if [ "$release_mode" -eq "0" ]; then
-	other_args="${other_args} -g -fno-inline-functions"
+	other_args="${other_args} -g
 fi
+if [ "$release_mode" -eq "1" ]; then
+	other_args="${other_args} -O3 -march=native
+fi
+
 if [[ "$(uname)" == "Darwin" ]]; then
 
 	# Set compiler to clang on MacOS

+ 32 - 8
src/main.cpp

@@ -811,9 +811,15 @@ int main(int arg_count, char **arg_ptr) {
 			return exit_code;
 		}
 
-		timings_start_section(&timings, str_lit("ld-link"));
+		// NOTE(vassvik): get cwd, for used for local shared libs linking, since those have to be relative to the exe
+		char cwd[256];
+		getcwd(&cwd[0], 256);
+		//printf("%s\n", cwd);
+
+		// NOTE(vassvik): needs to add the root to the library search paths, so that the full filenames of the library
+		//                files can be passed with -l:
+		gbString lib_str = gb_string_make(heap_allocator(), "-L/");
 
-		gbString lib_str = gb_string_make(heap_allocator(), "");
 		defer (gb_string_free(lib_str));
 		char lib_str_buf[1024] = {0};
 		for_array(i, ir_gen.module.foreign_library_paths) {
@@ -825,15 +831,33 @@ int main(int arg_count, char **arg_ptr) {
 			#if defined(GB_SYSTEM_OSX)
 				isize len;
 				if(lib.len > 2 && lib[0] == '-' && lib[1] == 'f') {
-					len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
-					                        " -framework %.*s ", (int)(lib.len) - 2, lib.text + 2);
+					// framework thingie
+					len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf), " -framework %.*s ", (int)(lib.len) - 2, lib.text + 2);
+				} else if (string_has_extension(lib, str_lit("dylib"))) {
+					// dynamic lib, relative path to executable
+					len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf), " -l:%s/%.*s ", cwd, LIT(lib));
 				} else {
-					len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
-					                        " -l%.*s ", LIT(lib));
+					// dynamic or static system lib, just link regularly searching system library paths
+					len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf), " -l%.*s ", LIT(lib));
 				}
 			#else
-				isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
-				                        " -l%.*s ", LIT(lib));
+				// NOTE(vassvik): static libraries (.a files) in linux can be linked to directly using the full path, 
+				//                since those are statically linked to at link time. shared libraries (.so) has 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
+				//                the system library paths for the library file). 
+				if (string_has_extension(lib, str_lit("a"))) {
+					// static libs, absolute full path relative to the file in which the lib was imported from
+					isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf), " -l:%.*s ", LIT(lib));
+				} else if (string_has_extension(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 runtimeto the executable
+					isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf), " -l:%s/%.*s ", cwd, LIT(lib));
+				} else {
+					// dynamic or static system lib, just link regularly searching system library paths
+					isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf), " -l%.*s ", LIT(lib));
+				}
 			#endif
 			lib_str = gb_string_appendc(lib_str, lib_str_buf);
 		}

+ 15 - 0
src/parser.cpp

@@ -4880,7 +4880,22 @@ bool determine_path_from_string(Parser *p, AstNode *node, String base_dir, Strin
 			syntax_error(node, "Unknown library collection: `%.*s`", LIT(collection_name));
 			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 == AstNode_ForeignImportDecl && string_has_extension(file_str, str_lit("so"))) {
+			*path = file_str;
+			return true;
+		}
+#endif
 	}
+	
 	String fullpath = string_trim_whitespace(get_fullpath_relative(a, base_dir, file_str));
 	*path = fullpath;