From 59aa05170d54edff75aed220bb1653fc369573d7 Mon Sep 17 00:00:00 2001 From: Patrick Cleavelin Date: Thu, 4 Jan 2024 13:54:10 -0600 Subject: respect -lld CLI arg --- src/linker.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/linker.cpp') diff --git a/src/linker.cpp b/src/linker.cpp index 4ab4b2cd1..7fec11ad3 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -516,7 +516,12 @@ gb_internal i32 linker_stage(LinkerData *gen) { link_command_line = gb_string_append_fmt(link_command_line, " %.*s ", LIT(build_context.extra_linker_flags)); link_command_line = gb_string_append_fmt(link_command_line, " %s ", link_settings); - result = system_exec_command_line_app("ld-link", link_command_line); + if (build_context.use_lld) { + link_command_line = gb_string_append_fmt(link_command_line, " -fuse-ld=lld"); + result = system_exec_command_line_app("lld-link", link_command_line); + } else { + result = system_exec_command_line_app("ld-link", link_command_line); + } if (result) { return result; -- cgit v1.2.3 From eab0e730a02146979e5ead1dd9dcc33a8f75ae4e Mon Sep 17 00:00:00 2001 From: Laytan Date: Thu, 8 Feb 2024 19:48:37 +0100 Subject: fix -no-crt on Linux --- src/linker.cpp | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'src/linker.cpp') diff --git a/src/linker.cpp b/src/linker.cpp index c0952d0e0..987fab7f7 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -482,37 +482,33 @@ gb_internal i32 linker_stage(LinkerData *gen) { gbString platform_lib_str = gb_string_make(heap_allocator(), ""); defer (gb_string_free(platform_lib_str)); if (build_context.metrics.os == TargetOs_darwin) { - platform_lib_str = gb_string_appendc(platform_lib_str, "-Wl,-syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib"); + platform_lib_str = gb_string_appendc(platform_lib_str, "-Wl,-syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib "); // Homebrew's default library path, checking if it exists to avoid linking warnings. if (gb_file_exists("/opt/homebrew/lib")) { - platform_lib_str = gb_string_appendc(platform_lib_str, " -L/opt/homebrew/lib"); + platform_lib_str = gb_string_appendc(platform_lib_str, "-L/opt/homebrew/lib "); } // MacPort's default library path, checking if it exists to avoid linking warnings. if (gb_file_exists("/opt/local/lib")) { - platform_lib_str = gb_string_appendc(platform_lib_str, " -L/opt/local/lib"); + platform_lib_str = gb_string_appendc(platform_lib_str, "-L/opt/local/lib "); } - #if defined(GB_SYSTEM_OSX) - if(!build_context.no_crt) { - platform_lib_str = gb_string_appendc(platform_lib_str, " -lm "); - if(gen->needs_system_library_linked == 1) { - platform_lib_str = gb_string_appendc(platform_lib_str, " -lSystem "); - } - } - #endif - } else { - platform_lib_str = gb_string_appendc(platform_lib_str, "-lc -lm"); - } - - if (build_context.metrics.os == TargetOs_darwin) { // This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit. if (build_context.minimum_os_version_string.len) { - link_settings = gb_string_append_fmt(link_settings, " -mmacosx-version-min=%.*s ", LIT(build_context.minimum_os_version_string)); + link_settings = gb_string_append_fmt(link_settings, "-mmacosx-version-min=%.*s ", LIT(build_context.minimum_os_version_string)); } // This points the linker to where the entry point is - link_settings = gb_string_appendc(link_settings, " -e _main "); + link_settings = gb_string_appendc(link_settings, "-e _main "); + } + + if (!build_context.no_crt) { + platform_lib_str = gb_string_appendc(platform_lib_str, "-lm "); + if (build_context.metrics.os == TargetOs_darwin) { + platform_lib_str = gb_string_appendc(platform_lib_str, "-lSystem "); + } else { + platform_lib_str = gb_string_appendc(platform_lib_str, "-lc "); + } } gbString link_command_line = gb_string_make(heap_allocator(), "clang -Wno-unused-command-line-argument "); -- cgit v1.2.3 From 88add0b6b12b6590fd69bb74182f1a7689ae9ff6 Mon Sep 17 00:00:00 2001 From: avanspector Date: Sun, 25 Feb 2024 02:24:52 +0100 Subject: Improve Haiku support --- src/build_settings.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/check_builtin.cpp | 1 + src/checker.cpp | 1 + src/linker.cpp | 4 +-- src/llvm_backend.cpp | 4 +-- src/tilde.cpp | 1 + 6 files changed, 73 insertions(+), 4 deletions(-) (limited to 'src/linker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 0bcb9f298..f395cb515 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -18,6 +18,7 @@ enum TargetOsKind : u16 { TargetOs_essence, TargetOs_freebsd, TargetOs_openbsd, + TargetOs_haiku, TargetOs_wasi, TargetOs_js, @@ -542,6 +543,13 @@ gb_global TargetMetrics target_openbsd_amd64 = { str_lit("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"), }; +gb_global TargetMetrics target_haiku_amd64 = { + TargetOs_haiku, + TargetArch_amd64, + 8, 8, 8, 16, + str_lit("x86_64-unknown-haiku"), +}; + gb_global TargetMetrics target_essence_amd64 = { TargetOs_essence, TargetArch_amd64, @@ -641,6 +649,7 @@ gb_global NamedTargetMetrics named_targets[] = { { str_lit("freebsd_amd64"), &target_freebsd_amd64 }, { str_lit("openbsd_amd64"), &target_openbsd_amd64 }, + { str_lit("haiku_amd64"), &target_haiku_amd64 }, { str_lit("freestanding_wasm32"), &target_freestanding_wasm32 }, { str_lit("wasi_wasm32"), &target_wasi_wasm32 }, @@ -872,6 +881,58 @@ gb_internal String internal_odin_root_dir(void) { return path; } +#elif defined(GB_SYSTEM_HAIKU) + +#include + +gb_internal String internal_odin_root_dir(void) { + String path = global_module_path; + isize len, i; + u8 *text; + + if (global_module_path_set) { + return global_module_path; + } + + auto path_buf = array_make(heap_allocator(), 300); + + len = 0; + for (;;) { + u32 sz = path_buf.count; + int res = find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, nullptr, &path_buf[0], sz); + if(res == B_OK) { + len = sz; + break; + } else { + array_resize(&path_buf, sz + 1); + } + } + + mutex_lock(&string_buffer_mutex); + defer (mutex_unlock(&string_buffer_mutex)); + + text = gb_alloc_array(permanent_allocator(), u8, len + 1); + gb_memmove(text, &path_buf[0], len); + + path = path_to_fullpath(heap_allocator(), make_string(text, len), nullptr); + + for (i = path.len-1; i >= 0; i--) { + u8 c = path[i]; + if (c == '/' || c == '\\') { + break; + } + path.len--; + } + + global_module_path = path; + global_module_path_set = true; + + + // array_free(&path_buf); + + return path; +} + #elif defined(GB_SYSTEM_OSX) #include @@ -1301,6 +1362,8 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta metrics = &target_freebsd_amd64; #elif defined(GB_SYSTEM_OPENBSD) metrics = &target_openbsd_amd64; + #elif defined(GB_SYSTEM_HAIKU) + metrics = &target_haiku_amd64; #elif defined(GB_CPU_ARM) metrics = &target_linux_arm64; #else @@ -1405,6 +1468,9 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta case TargetOs_openbsd: bc->link_flags = str_lit("-arch x86-64 "); break; + case TargetOs_haiku: + bc->link_flags = str_lit("-arch x86-64 "); + break; } } else if (bc->metrics.arch == TargetArch_i386) { switch (bc->metrics.os) { diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index d39be37a9..e00f6c053 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -4928,6 +4928,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case TargetOs_essence: case TargetOs_freebsd: case TargetOs_openbsd: + case TargetOs_haiku: switch (build_context.metrics.arch) { case TargetArch_i386: case TargetArch_amd64: diff --git a/src/checker.cpp b/src/checker.cpp index 569a3c76f..b8b8e21e5 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1007,6 +1007,7 @@ gb_internal void init_universal(void) { {"Linux", TargetOs_linux}, {"Essence", TargetOs_essence}, {"FreeBSD", TargetOs_freebsd}, + {"Haiku", TargetOs_haiku}, {"OpenBSD", TargetOs_openbsd}, {"WASI", TargetOs_wasi}, {"JS", TargetOs_js}, diff --git a/src/linker.cpp b/src/linker.cpp index 987fab7f7..4e39f2ddc 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -474,8 +474,8 @@ gb_internal i32 linker_stage(LinkerData *gen) { link_settings = gb_string_appendc(link_settings, "-Wl,-fini,'_odin_exit_point' "); } - } else if (build_context.metrics.os != TargetOs_openbsd) { - // OpenBSD defaults to PIE executable. do not pass -no-pie for it. + } else if (build_context.metrics.os != TargetOs_openbsd && build_context.metrics.os != TargetOs_haiku) { + // OpenBSD and Haiku default to PIE executable. do not pass -no-pie for it. link_settings = gb_string_appendc(link_settings, "-no-pie "); } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index fa76ac22f..01d7a23b2 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -2602,8 +2602,8 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { switch (build_context.reloc_mode) { case RelocMode_Default: - if (build_context.metrics.os == TargetOs_openbsd) { - // Always use PIC for OpenBSD: it defaults to PIE + if (build_context.metrics.os == TargetOs_openbsd || build_context.metrics.os == TargetOs_haiku) { + // Always use PIC for OpenBSD and Haiku: they default to PIE reloc_mode = LLVMRelocPIC; } break; diff --git a/src/tilde.cpp b/src/tilde.cpp index 06428f317..4fc7d1c9b 100644 --- a/src/tilde.cpp +++ b/src/tilde.cpp @@ -825,6 +825,7 @@ gb_internal bool cg_generate_code(Checker *c, LinkerData *linker_data) { case TargetOs_essence: case TargetOs_freebsd: case TargetOs_openbsd: + case TargetOs_haiku: debug_format = TB_DEBUGFMT_DWARF; break; } -- cgit v1.2.3 From a5558625228045830b0e90b3922f684350ff9beb Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Tue, 19 Mar 2024 19:43:41 +0100 Subject: linker improvements `path_to_fullpath` did different things on Windows&Unix, an attempt to bring them closer together was made here. This was prompted by the compiler completely ignoring `foreign import "foo.dylib"` when `foo.dylib` does not exist (because `path_to_fullpath` returns an empty string). Causing just unresolved symbol errors, when on Windows it would pass along the path to the linker and actually say it doesn't exist, which is now also the case for Unix. This also fixes some checker errors that relied on the Windows behaviour, for example: `Error: File name, , cannot be as a library name as it is not a valid identifier`. Made `-no-crt` require either `-default-to-nil-allocator` or `-default-to-panic-allocator` on Unix, the current default allocators rely on libc and this was not obvious and would immediately bring up unresolved symbol errors for the linked memory management functions, or just link with libc anyways because it was foreign imported. Added a suggestion to install `nasm` with the user's package manager when assembling using `nasm` fails on Unix, I saw some confusion about it in the Discord. Ignore explicit foreign imports of libc. It is already linked in later on in the linking process and would otherwise (at least on macOS) cause linker warnings for duplicate libraries. This also makes it so when using `-no-crt` and importing something that requires libc, linker errors are given (like I would expect), instead of silently still linking with libc because it was foreign imported. --- src/build_settings.cpp | 27 +++++++++++++++++++++++++-- src/linker.cpp | 14 +++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) (limited to 'src/linker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index fdaa971f1..fa57e3809 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1190,13 +1190,24 @@ gb_internal String path_to_fullpath(gbAllocator a, String s, bool *ok_) { char *p; mutex_lock(&fullpath_mutex); p = realpath(cast(char *)s.text, 0); + defer (free(p)); mutex_unlock(&fullpath_mutex); if(p == nullptr) { if (ok_) *ok_ = false; - return String{}; + + // Path doesn't exist or is malformed, Windows's `GetFullPathNameW` does not check for + // existence of the file where `realpath` does, which causes different behaviour between platforms. + // Two things could be done here: + // 1. clean the path and resolve it manually, just like the Windows function does, + // probably requires porting `filepath.clean` from Odin and doing some more processing. + // 2. just return a copy of the original path. + // + // I have opted for 2 because it is much simpler + we already return `ok = false` + further + // checks and processes will use the path and cause errors (which we want). + return copy_string(a, s); } if (ok_) *ok_ = true; - return make_string_c(p); + return copy_string(a, make_string_c(p)); } #else #error Implement system @@ -1939,6 +1950,18 @@ gb_internal bool init_build_paths(String init_filename) { } } + if (build_context.no_crt && !build_context.ODIN_DEFAULT_TO_NIL_ALLOCATOR && !build_context.ODIN_DEFAULT_TO_PANIC_ALLOCATOR) { + switch (build_context.metrics.os) { + case TargetOs_linux: + case TargetOs_darwin: + case TargetOs_essence: + case TargetOs_freebsd: + case TargetOs_openbsd: + case TargetOs_haiku: + gb_printf_err("-no-crt on unix systems requires either -default-to-nil-allocator or -default-to-panic-allocator to also be present because the default allocator requires crt\n"); + return false; + } + } if (bc->target_features_string.len != 0) { enable_target_feature({}, bc->target_features_string); diff --git a/src/linker.cpp b/src/linker.cpp index 0cdeaf8d9..9d7f16f1d 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -376,6 +376,10 @@ gb_internal i32 linker_stage(LinkerData *gen) { LIT(obj_file), LIT(build_context.extra_assembler_flags) ); + if (!result) { + gb_printf_err("executing `nasm` to assemble foreing import of %.*s failed.\n\tSuggestion: `nasm` does not ship with the compiler and should be installed with your system's package manager.\n", LIT(asm_file)); + return result; + } } array_add(&gen->output_object_paths, obj_file); } else { @@ -383,9 +387,13 @@ gb_internal i32 linker_stage(LinkerData *gen) { continue; } - // NOTE(zangent): Sometimes, you have to use -framework on MacOS. - // This allows you to specify '-f' in a #foreign_system_library, - // without having to implement any new syntax specifically for MacOS. + // Do not add libc again, this is added later already, and omitted with + // the `-no-crt` flag, not skipping here would cause duplicate library + // warnings when linking on darwin and might link libc silently even with `-no-crt`. + if (lib == str_lit("System.framework") || lib == str_lit("c")) { + continue; + } + if (build_context.metrics.os == TargetOs_darwin) { if (string_ends_with(lib, str_lit(".framework"))) { // framework thingie -- cgit v1.2.3 From 15c1e8274dc19735ca9857962424846148596d26 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Sat, 23 Mar 2024 22:12:05 +0100 Subject: darwin: fix ld warnings and set minimum os version --- src/build_settings.cpp | 34 ++++++++++++++++++++-------------- src/linker.cpp | 5 +++-- src/main.cpp | 2 +- 3 files changed, 24 insertions(+), 17 deletions(-) (limited to 'src/linker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 4be189cf1..19006ab2c 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -510,7 +510,7 @@ gb_global TargetMetrics target_darwin_amd64 = { TargetOs_darwin, TargetArch_amd64, 8, 8, 8, 16, - str_lit("x86_64-apple-darwin"), + str_lit("x86_64-apple-macosx"), // NOTE: Changes during initialization based on build flags. str_lit("e-m:o-i64:64-f80:128-n8:16:32:64-S128"), }; @@ -518,7 +518,7 @@ gb_global TargetMetrics target_darwin_arm64 = { TargetOs_darwin, TargetArch_arm64, 8, 8, 8, 16, - str_lit("arm64-apple-macosx11.0.0"), + str_lit("arm64-apple-macosx"), // NOTE: Changes during initialization based on build flags. str_lit("e-m:o-i64:64-i128:128-n32:64-S128"), }; @@ -1418,19 +1418,25 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta } bc->metrics = *metrics; - switch (subtarget) { - case Subtarget_Default: - break; - case Subtarget_iOS: - GB_ASSERT(metrics->os == TargetOs_darwin); - if (metrics->arch == TargetArch_arm64) { - bc->metrics.target_triplet = str_lit("arm64-apple-ios"); - } else if (metrics->arch == TargetArch_amd64) { - bc->metrics.target_triplet = str_lit("x86_64-apple-ios"); - } else { - GB_PANIC("Unknown architecture for darwin"); + if (metrics->os == TargetOs_darwin) { + if (bc->minimum_os_version_string.len == 0) { + bc->minimum_os_version_string = str_lit("11.0.0"); + } + + switch (subtarget) { + case Subtarget_Default: + bc->metrics.target_triplet = concatenate_strings(permanent_allocator(), bc->metrics.target_triplet, bc->minimum_os_version_string); + break; + case Subtarget_iOS: + if (metrics->arch == TargetArch_arm64) { + bc->metrics.target_triplet = str_lit("arm64-apple-ios"); + } else if (metrics->arch == TargetArch_amd64) { + bc->metrics.target_triplet = str_lit("x86_64-apple-ios"); + } else { + GB_PANIC("Unknown architecture for darwin"); + } + break; } - break; } bc->ODIN_OS = target_os_names[metrics->os]; diff --git a/src/linker.cpp b/src/linker.cpp index 9d7f16f1d..6699c9cb8 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -502,7 +502,6 @@ gb_internal i32 linker_stage(LinkerData *gen) { platform_lib_str = gb_string_appendc(platform_lib_str, "-L/opt/local/lib "); } - // This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit. if (build_context.minimum_os_version_string.len) { link_settings = gb_string_append_fmt(link_settings, "-mmacosx-version-min=%.*s ", LIT(build_context.minimum_os_version_string)); } @@ -513,7 +512,9 @@ gb_internal i32 linker_stage(LinkerData *gen) { if (!build_context.no_crt) { platform_lib_str = gb_string_appendc(platform_lib_str, "-lm "); if (build_context.metrics.os == TargetOs_darwin) { - platform_lib_str = gb_string_appendc(platform_lib_str, "-lSystem "); + // NOTE: adding this causes a warning about duplicate libraries, I think it is + // automatically assumed/added by clang when you don't do `-nostdlib`. + // platform_lib_str = gb_string_appendc(platform_lib_str, "-lSystem "); } else { platform_lib_str = gb_string_appendc(platform_lib_str, "-lc "); } diff --git a/src/main.cpp b/src/main.cpp index ab721a143..9c353653f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1925,7 +1925,7 @@ gb_internal void print_show_help(String const arg0, String const &command) { if (run_or_build) { print_usage_line(1, "-minimum-os-version:"); print_usage_line(2, "Sets the minimum OS version targeted by the application."); - print_usage_line(2, "Example: -minimum-os-version:12.0.0"); + print_usage_line(2, "Default: -minimum-os-version:11.0.0"); print_usage_line(2, "(Only used when target is Darwin.)"); print_usage_line(0, ""); -- cgit v1.2.3 From b26a685b769c99128f96a4b00c578775daec5192 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 25 Mar 2024 21:55:58 +0100 Subject: darwin: be less annoying about "incompatible" library versions After #3316 we set a default minimum version, now this will warn if you link with a library that is targeting later versions. This might be a bit annoying, especially when the user hasn't actually given Odin a minimum target. So this PR makes these warnings only show when you explicitly give a target version (afaik that is the only thing that -mmacosx-min-version actually does for us because we don't use it to compile anything, just to link). --- src/build_settings.cpp | 4 +++- src/linker.cpp | 5 ++++- src/main.cpp | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/linker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 19006ab2c..3a9951cb2 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -436,7 +436,9 @@ struct BuildContext { BlockingMutex target_features_mutex; StringSet target_features_set; String target_features_string; + String minimum_os_version_string; + bool minimum_os_version_string_given; }; gb_global BuildContext build_context = {0}; @@ -1419,7 +1421,7 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta bc->metrics = *metrics; if (metrics->os == TargetOs_darwin) { - if (bc->minimum_os_version_string.len == 0) { + if (!bc->minimum_os_version_string_given) { bc->minimum_os_version_string = str_lit("11.0.0"); } diff --git a/src/linker.cpp b/src/linker.cpp index 6699c9cb8..63987f9e8 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -502,9 +502,12 @@ gb_internal i32 linker_stage(LinkerData *gen) { platform_lib_str = gb_string_appendc(platform_lib_str, "-L/opt/local/lib "); } - if (build_context.minimum_os_version_string.len) { + // Only specify this flag if the user has given a minimum version to target. + // This will cause warnings to show up for mismatched libraries. + if (build_context.minimum_os_version_string_given) { link_settings = gb_string_append_fmt(link_settings, "-mmacosx-version-min=%.*s ", LIT(build_context.minimum_os_version_string)); } + // This points the linker to where the entry point is link_settings = gb_string_appendc(link_settings, "-e _main "); } diff --git a/src/main.cpp b/src/main.cpp index 9c353653f..79c3a1670 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1066,6 +1066,7 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_MinimumOSVersion: { GB_ASSERT(value.kind == ExactValue_String); build_context.minimum_os_version_string = value.value_string; + build_context.minimum_os_version_string_given = true; break; } case BuildFlag_RelocMode: { @@ -1926,7 +1927,7 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-minimum-os-version:"); print_usage_line(2, "Sets the minimum OS version targeted by the application."); print_usage_line(2, "Default: -minimum-os-version:11.0.0"); - print_usage_line(2, "(Only used when target is Darwin.)"); + print_usage_line(2, "Only used when target is Darwin, if given, linking mismatched versions will emit a warning."); print_usage_line(0, ""); print_usage_line(1, "-extra-linker-flags:"); -- cgit v1.2.3 From 19d566ebc5c9b0f99620226537c7f0fba1960333 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 25 Mar 2024 22:06:44 +0100 Subject: darwin: fix linker warning when building dynamic library Trying to fix all linker warnings that macOS comes up with, when building a dynamic library it currently emits `ld: warning: ignoring -e, not used for output type` --- src/linker.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/linker.cpp') diff --git a/src/linker.cpp b/src/linker.cpp index 63987f9e8..0e3169b22 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -508,8 +508,10 @@ gb_internal i32 linker_stage(LinkerData *gen) { link_settings = gb_string_append_fmt(link_settings, "-mmacosx-version-min=%.*s ", LIT(build_context.minimum_os_version_string)); } - // This points the linker to where the entry point is - link_settings = gb_string_appendc(link_settings, "-e _main "); + if (build_context.build_mode != BuildMode_DynamicLibrary) { + // This points the linker to where the entry point is + link_settings = gb_string_appendc(link_settings, "-e _main "); + } } if (!build_context.no_crt) { -- cgit v1.2.3 From 0e5a482c42f28c58da18213b2b3257304f357476 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 4 Apr 2024 16:11:26 +0100 Subject: Default to "smart" linker behaviour; Add `-min-link-libs` to use minimize link libs if wanted --- src/build_settings.cpp | 4 +++- src/linker.cpp | 60 +++++++++++++++++++++++--------------------------- src/main.cpp | 13 +++++++++++ 3 files changed, 43 insertions(+), 34 deletions(-) (limited to 'src/linker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 1ac9e451f..3b5d33ae3 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -412,7 +412,9 @@ struct BuildContext { bool dynamic_map_calls; - bool obfuscate_source_code_locations; + bool obfuscate_source_code_locations; + + bool min_link_libs; RelocMode reloc_mode; bool disable_red_zone; diff --git a/src/linker.cpp b/src/linker.cpp index 0e3169b22..2ff7ad0f4 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -139,9 +139,9 @@ gb_internal i32 linker_stage(LinkerData *gen) { } - StringSet libs = {}; - string_set_init(&libs, 64); - defer (string_set_destroy(&libs)); + StringSet min_libs_set = {}; + string_set_init(&min_libs_set, 64); + defer (string_set_destroy(&min_libs_set)); StringSet asm_files = {}; string_set_init(&asm_files, 64); @@ -149,6 +149,11 @@ gb_internal i32 linker_stage(LinkerData *gen) { for (Entity *e : gen->foreign_libraries) { GB_ASSERT(e->kind == Entity_LibraryName); + // NOTE(bill): Add these before the linking values + String extra_linker_flags = string_trim_whitespace(e->LibraryName.extra_linker_flags); + if (extra_linker_flags.len != 0) { + lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(extra_linker_flags)); + } for_array(i, e->LibraryName.paths) { String lib = string_trim_whitespace(e->LibraryName.paths[i]); // IMPORTANT NOTE(bill): calling `string_to_lower` here is not an issue because @@ -162,12 +167,11 @@ gb_internal i32 linker_stage(LinkerData *gen) { if (!string_set_update(&asm_files, lib)) { String asm_file = asm_files.entries[i].value; String obj_file = concatenate_strings(permanent_allocator(), asm_file, str_lit(".obj")); - String obj_format; -#if defined(GB_ARCH_64_BIT) - obj_format = str_lit("win64"); -#elif defined(GB_ARCH_32_BIT) + String obj_format = str_lit("win64"); + #if defined(GB_ARCH_32_BIT) obj_format = str_lit("win32"); -#endif // GB_ARCH_*_BIT + #endif + result = system_exec_command_line_app("nasm", "\"%.*s\\bin\\nasm\\windows\\nasm.exe\" \"%.*s\" " "-f \"%.*s\" " @@ -185,21 +189,13 @@ gb_internal i32 linker_stage(LinkerData *gen) { } array_add(&gen->output_object_paths, obj_file); } - } else { - if (!string_set_update(&libs, lib)) { - lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib)); - } + } else if (!string_set_update(&min_libs_set, lib) || + !build_context.min_link_libs) { + lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib)); } } } - for (Entity *e : gen->foreign_libraries) { - GB_ASSERT(e->kind == Entity_LibraryName); - if (e->LibraryName.extra_linker_flags.len != 0) { - lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(e->LibraryName.extra_linker_flags)); - } - } - if (build_context.build_mode == BuildMode_DynamicLibrary) { link_settings = gb_string_append_fmt(link_settings, " /DLL"); } else { @@ -318,12 +314,17 @@ gb_internal i32 linker_stage(LinkerData *gen) { string_set_init(&asm_files, 64); defer (string_set_destroy(&asm_files)); - StringSet libs = {}; - string_set_init(&libs, 64); - defer (string_set_destroy(&libs)); + StringSet min_libs_set = {}; + string_set_init(&min_libs_set, 64); + defer (string_set_destroy(&min_libs_set)); for (Entity *e : gen->foreign_libraries) { GB_ASSERT(e->kind == Entity_LibraryName); + // NOTE(bill): Add these before the linking values + String extra_linker_flags = string_trim_whitespace(e->LibraryName.extra_linker_flags); + if (extra_linker_flags.len != 0) { + lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(extra_linker_flags)); + } for (String lib : e->LibraryName.paths) { lib = string_trim_whitespace(lib); if (lib.len == 0) { @@ -336,19 +337,19 @@ gb_internal i32 linker_stage(LinkerData *gen) { String asm_file = lib; String obj_file = concatenate_strings(permanent_allocator(), asm_file, str_lit(".o")); String obj_format; -#if defined(GB_ARCH_64_BIT) + #if defined(GB_ARCH_64_BIT) if (is_osx) { obj_format = str_lit("macho64"); } else { obj_format = str_lit("elf64"); } -#elif defined(GB_ARCH_32_BIT) + #elif defined(GB_ARCH_32_BIT) if (is_osx) { obj_format = str_lit("macho32"); } else { obj_format = str_lit("elf32"); } -#endif // GB_ARCH_*_BIT + #endif // GB_ARCH_*_BIT if (is_osx) { // `as` comes with MacOS. @@ -383,7 +384,7 @@ gb_internal i32 linker_stage(LinkerData *gen) { } array_add(&gen->output_object_paths, obj_file); } else { - if (string_set_update(&libs, lib)) { + if (string_set_update(&min_libs_set, lib) && build_context.min_link_libs) { continue; } @@ -433,13 +434,6 @@ gb_internal i32 linker_stage(LinkerData *gen) { } } - for (Entity *e : gen->foreign_libraries) { - GB_ASSERT(e->kind == Entity_LibraryName); - if (e->LibraryName.extra_linker_flags.len != 0) { - lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(e->LibraryName.extra_linker_flags)); - } - } - gbString object_files = gb_string_make(heap_allocator(), ""); defer (gb_string_free(object_files)); for (String object_path : gen->output_object_paths) { diff --git a/src/main.cpp b/src/main.cpp index b8c21fd3b..2dbb72ca2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -296,6 +296,8 @@ enum BuildFlagKind { BuildFlag_ErrorPosStyle, BuildFlag_MaxErrorCount, + BuildFlag_MinLinkLibs, + // internal use only BuildFlag_InternalIgnoreLazy, BuildFlag_InternalIgnoreLLVMBuild, @@ -485,6 +487,8 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_ErrorPosStyle, str_lit("error-pos-style"), BuildFlagParam_String, Command_all); add_flag(&build_flags, BuildFlag_MaxErrorCount, str_lit("max-error-count"), BuildFlagParam_Integer, Command_all); + add_flag(&build_flags, BuildFlag_MinLinkLibs, str_lit("min-link-libs"), BuildFlagParam_None, Command__does_build); + add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_InternalIgnoreLLVMBuild, str_lit("internal-ignore-llvm-build"),BuildFlagParam_None, Command_all); @@ -1215,6 +1219,10 @@ gb_internal bool parse_build_flags(Array args) { break; } + case BuildFlag_MinLinkLibs: + build_context.min_link_libs = true; + break; + case BuildFlag_InternalIgnoreLazy: build_context.ignore_lazy = true; break; @@ -2008,6 +2016,11 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(2, "If not set, the default max error count is %d.", DEFAULT_MAX_ERROR_COLLECTOR_COUNT); print_usage_line(0, ""); + print_usage_line(1, "-min-link-libs"); + print_usage_line(2, "If set, the number of linked libraries will be minimized to prevent duplications."); + print_usage_line(2, "This is useful for so called \"dumb\" linkers compared to \"smart\" linkers."); + print_usage_line(0, ""); + print_usage_line(1, "-foreign-error-procedures"); print_usage_line(2, "States that the error procedures used in the runtime are defined in a separate translation unit."); print_usage_line(0, ""); -- cgit v1.2.3 From b979fd4c439f8b9eb30d800dec92a0a669617981 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 4 Apr 2024 16:14:05 +0100 Subject: Remove consecutive linking libraries --- src/linker.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/linker.cpp') diff --git a/src/linker.cpp b/src/linker.cpp index 2ff7ad0f4..aa36b3278 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -143,6 +143,8 @@ gb_internal i32 linker_stage(LinkerData *gen) { string_set_init(&min_libs_set, 64); defer (string_set_destroy(&min_libs_set)); + String prev_lib = {}; + StringSet asm_files = {}; string_set_init(&asm_files, 64); defer (string_set_destroy(&asm_files)); @@ -191,7 +193,10 @@ gb_internal i32 linker_stage(LinkerData *gen) { } } else if (!string_set_update(&min_libs_set, lib) || !build_context.min_link_libs) { - lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib)); + if (prev_lib != lib) { + lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib)); + } + prev_lib = lib; } } } @@ -317,6 +322,8 @@ gb_internal i32 linker_stage(LinkerData *gen) { StringSet min_libs_set = {}; string_set_init(&min_libs_set, 64); defer (string_set_destroy(&min_libs_set)); + + String prev_lib = {}; for (Entity *e : gen->foreign_libraries) { GB_ASSERT(e->kind == Entity_LibraryName); @@ -388,6 +395,11 @@ gb_internal i32 linker_stage(LinkerData *gen) { continue; } + if (prev_lib == lib) { + continue; + } + prev_lib = lib; + // Do not add libc again, this is added later already, and omitted with // the `-no-crt` flag, not skipping here would cause duplicate library // warnings when linking on darwin and might link libc silently even with `-no-crt`. -- cgit v1.2.3 From 9c958ee66d21b3197382bf95f8db275e106930c8 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 8 Apr 2024 20:42:09 +0200 Subject: fix nasm check --- src/linker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/linker.cpp') diff --git a/src/linker.cpp b/src/linker.cpp index aa36b3278..498a96c5f 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -384,7 +384,7 @@ gb_internal i32 linker_stage(LinkerData *gen) { LIT(obj_file), LIT(build_context.extra_assembler_flags) ); - if (!result) { + if (result) { gb_printf_err("executing `nasm` to assemble foreing import of %.*s failed.\n\tSuggestion: `nasm` does not ship with the compiler and should be installed with your system's package manager.\n", LIT(asm_file)); return result; } -- cgit v1.2.3