From 9e0b69312b949f6f0e1e1851db3ecb79be25cfa1 Mon Sep 17 00:00:00 2001 From: vassvik Date: Fri, 10 Nov 2017 21:31:13 +0100 Subject: [PATCH] Fixed foreign import for linux. Modified .gitignore to ignore temp files and files in shared/. Added a Makefile for linux --- .gitignore | 10 ++++++++++ Makefile | 24 ++++++++++++++++++++++++ build.sh | 10 +++++++--- src/main.cpp | 40 ++++++++++++++++++++++++++++++++-------- src/parser.cpp | 15 +++++++++++++++ 5 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 Makefile diff --git a/.gitignore b/.gitignore index 71daef3f6..38b611044 100644 --- a/.gitignore +++ b/.gitignore @@ -257,7 +257,17 @@ paket-files/ builds/ bin/ *.exe +*.obj +*.pdb # - Linux/MacOS odin odin.dSYM + + +# shared collection +shared/ + +# temp files +* .ll +*.bc diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..c4e1fab92 --- /dev/null +++ b/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 + + + diff --git a/build.sh b/build.sh index 5a4476b89..3858da548 100755 --- a/build.sh +++ b/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 diff --git a/src/main.cpp b/src/main.cpp index 154fa91bc..adb690dad 100644 --- a/src/main.cpp +++ b/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); } diff --git a/src/parser.cpp b/src/parser.cpp index f81bb1a39..1c90bf274 100644 --- a/src/parser.cpp +++ b/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;