From 591118c68804bf89b9ee3d371b14c54133f4655c Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Sun, 18 May 2025 10:51:08 -0400 Subject: Use `--sysroot` instead of `-Wl,-syslibroot` on Darwin This keeps the linker from using the wrong SDK and mirrors how we build the Odin compiler itself in `build_odin.sh`. --- src/linker.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/linker.cpp') diff --git a/src/linker.cpp b/src/linker.cpp index ec165ef7d..087bb49f1 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -769,7 +769,17 @@ try_cross_linking:; 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 "); + // Get the MacOSX SDK path. + gbString darwin_sdk_path = gb_string_make(temporary_allocator(), ""); + if (!system_exec_command_line_app_output("xcrun --sdk macosx --show-sdk-path", &darwin_sdk_path)) { + darwin_sdk_path = gb_string_set(darwin_sdk_path, "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"); + } else { + // Trim the trailing newline. + darwin_sdk_path = gb_string_trim_space(darwin_sdk_path); + } + platform_lib_str = gb_string_append_fmt(platform_lib_str, "--sysroot %s ", darwin_sdk_path); + + platform_lib_str = gb_string_appendc(platform_lib_str, "-L/usr/local/lib "); // Homebrew's default library path, checking if it exists to avoid linking warnings. if (gb_file_exists("/opt/homebrew/lib")) { -- cgit v1.2.3 From c090a28b9d390ccd5352af2b2443491be806e464 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Tue, 20 May 2025 18:56:18 -0400 Subject: Add `/usr/local/lib` to FreeBSD linker path --- src/linker.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/linker.cpp') diff --git a/src/linker.cpp b/src/linker.cpp index 087bb49f1..41d4a13a1 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -801,6 +801,9 @@ try_cross_linking:; // This points the linker to where the entry point is link_settings = gb_string_appendc(link_settings, "-e _main "); } + } else if (build_context.metrics.os == TargetOs_freebsd) { + // FreeBSD pkg installs third-party shared libraries in /usr/local/lib. + platform_lib_str = gb_string_appendc(platform_lib_str, "-Wl,-L/usr/local/lib "); } else if (build_context.metrics.os == TargetOs_openbsd) { // OpenBSD ports install shared libraries in /usr/local/lib. Also, we must explicitly link libpthread. platform_lib_str = gb_string_appendc(platform_lib_str, "-lpthread -Wl,-L/usr/local/lib "); -- cgit v1.2.3 From 6c5b96948e827a0b22435c1bb367414c8a187666 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Thu, 22 May 2025 20:47:10 -0400 Subject: Enable all sanitizers on FreeBSD --- src/build_settings.cpp | 12 ++++++------ src/linker.cpp | 12 ++++++++++++ src/llvm_backend.cpp | 20 ++++++++++++++++---- 3 files changed, 34 insertions(+), 10 deletions(-) (limited to 'src/linker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 4f573a8ca..9c530df19 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -2303,9 +2303,10 @@ gb_internal bool init_build_paths(String init_filename) { case TargetOs_windows: case TargetOs_linux: case TargetOs_darwin: + case TargetOs_freebsd: break; default: - gb_printf_err("-sanitize:address is only supported on windows, linux, and darwin\n"); + gb_printf_err("-sanitize:address is only supported on Windows, Linux, Darwin, and FreeBSD\n"); return false; } } @@ -2313,12 +2314,10 @@ gb_internal bool init_build_paths(String init_filename) { if (build_context.sanitizer_flags & SanitizerFlag_Memory) { switch (build_context.metrics.os) { case TargetOs_linux: + case TargetOs_freebsd: break; default: - gb_printf_err("-sanitize:memory is only supported on linux\n"); - return false; - } - if (build_context.metrics.os != TargetOs_linux) { + gb_printf_err("-sanitize:memory is only supported on Linux and FreeBSD\n"); return false; } } @@ -2327,9 +2326,10 @@ gb_internal bool init_build_paths(String init_filename) { switch (build_context.metrics.os) { case TargetOs_linux: case TargetOs_darwin: + case TargetOs_freebsd: break; default: - gb_printf_err("-sanitize:thread is only supported on linux and darwin\n"); + gb_printf_err("-sanitize:thread is only supported on Linux, Darwin, and FreeBSD\n"); return false; } } diff --git a/src/linker.cpp b/src/linker.cpp index 41d4a13a1..447d66d0a 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -802,6 +802,18 @@ try_cross_linking:; link_settings = gb_string_appendc(link_settings, "-e _main "); } } else if (build_context.metrics.os == TargetOs_freebsd) { + if (build_context.sanitizer_flags & (SanitizerFlag_Address | SanitizerFlag_Memory)) { + // It's imperative that `pthread` is linked before `libc`, + // otherwise ASan/MSan will be unable to call `pthread_key_create` + // because FreeBSD's `libthr` implementation of `pthread` + // needs to replace the relevant stubs first. + // + // (Presumably TSan implements its own `pthread` interface, + // which is why it isn't required.) + // + // See: https://reviews.llvm.org/D39254 + platform_lib_str = gb_string_appendc(platform_lib_str, "-lpthread "); + } // FreeBSD pkg installs third-party shared libraries in /usr/local/lib. platform_lib_str = gb_string_appendc(platform_lib_str, "-Wl,-L/usr/local/lib "); } else if (build_context.metrics.os == TargetOs_openbsd) { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index f0bbe5473..90e7b2793 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3425,36 +3425,48 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { if (build_context.sanitizer_flags & SanitizerFlag_Address) { - if (build_context.metrics.os == TargetOs_windows) { + switch (build_context.metrics.os) { + case TargetOs_windows: { auto paths = array_make(heap_allocator(), 0, 1); String path = concatenate_strings(permanent_allocator(), build_context.ODIN_ROOT, str_lit("\\bin\\llvm\\windows\\clang_rt.asan-x86_64.lib")); array_add(&paths, path); Entity *lib = alloc_entity_library_name(nullptr, make_token_ident("asan_lib"), nullptr, slice_from_array(paths), str_lit("asan_lib")); array_add(&gen->foreign_libraries, lib); - } else if (build_context.metrics.os == TargetOs_darwin || build_context.metrics.os == TargetOs_linux) { + } break; + case TargetOs_darwin: + case TargetOs_linux: + case TargetOs_freebsd: if (!build_context.extra_linker_flags.text) { build_context.extra_linker_flags = str_lit("-fsanitize=address"); } else { build_context.extra_linker_flags = concatenate_strings(permanent_allocator(), build_context.extra_linker_flags, str_lit(" -fsanitize=address")); } + break; } } if (build_context.sanitizer_flags & SanitizerFlag_Memory) { - if (build_context.metrics.os == TargetOs_darwin || build_context.metrics.os == TargetOs_linux) { + switch (build_context.metrics.os) { + case TargetOs_linux: + case TargetOs_freebsd: if (!build_context.extra_linker_flags.text) { build_context.extra_linker_flags = str_lit("-fsanitize=memory"); } else { build_context.extra_linker_flags = concatenate_strings(permanent_allocator(), build_context.extra_linker_flags, str_lit(" -fsanitize=memory")); } + break; } } if (build_context.sanitizer_flags & SanitizerFlag_Thread) { - if (build_context.metrics.os == TargetOs_darwin || build_context.metrics.os == TargetOs_linux) { + switch (build_context.metrics.os) { + case TargetOs_darwin: + case TargetOs_linux: + case TargetOs_freebsd: if (!build_context.extra_linker_flags.text) { build_context.extra_linker_flags = str_lit("-fsanitize=thread"); } else { build_context.extra_linker_flags = concatenate_strings(permanent_allocator(), build_context.extra_linker_flags, str_lit(" -fsanitize=thread")); } + break; } } -- cgit v1.2.3 From 229c734820f4cfa3deb84386e1613a982d92eede Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Mon, 26 May 2025 18:58:59 +0200 Subject: Add comments to `builtin.odin`, documenting ODIN_* constants. (#5218) And document constants not previously listed. --- base/builtin/builtin.odin | 230 ++++++++++++++++++++++++++++++++++++++++++++-- src/build_settings.cpp | 135 +++++++++++++-------------- src/checker.cpp | 31 +++++-- src/linker.cpp | 6 +- src/main.cpp | 10 +- 5 files changed, 324 insertions(+), 88 deletions(-) (limited to 'src/linker.cpp') diff --git a/base/builtin/builtin.odin b/base/builtin/builtin.odin index 14da9603d..019fd93ff 100644 --- a/base/builtin/builtin.odin +++ b/base/builtin/builtin.odin @@ -7,13 +7,226 @@ nil :: nil false :: 0!=0 true :: 0==0 -ODIN_OS :: ODIN_OS -ODIN_ARCH :: ODIN_ARCH -ODIN_ENDIAN :: ODIN_ENDIAN -ODIN_VENDOR :: ODIN_VENDOR -ODIN_VERSION :: ODIN_VERSION -ODIN_ROOT :: ODIN_ROOT -ODIN_DEBUG :: ODIN_DEBUG +// The following constants are added in `checker.cpp`'s `init_universal` procedure. + +/* + An `enum` value indicating what the CPU architecture of the target is. + Possible values are: `.amd64`, `.i386`, `.arm32`, `.arm64`, `.wasm32`, `.wasm64p32`, and `.riscv64`. +*/ +ODIN_ARCH :: ODIN_ARCH + +/* + A `string` indicating what the CPU architecture of the target is. + Possible values are: "amd64", "i386", "arm32", "arm64", "wasm32", "wasm64p32", "riscv64". +*/ +ODIN_ARCH_STRING :: ODIN_ARCH_STRING + +/* + An `enum` value indicating the type of compiled output, chosen using `-build-mode`. + Possible values are: `.Executable`, `.Dynamic`, `.Static`, `.Object`, `.Assembly`, and `.LLVM_IR`. +*/ +ODIN_BUILD_MODE :: ODIN_BUILD_MODE + +/* + A `string` containing the name of the folder that contains the entry point, + e.g. for `%ODIN_ROOT%/examples/demo`, this would contain `demo`. +*/ +ODIN_BUILD_PROJECT_NAME :: ODIN_BUILD_PROJECT_NAME + +/* + An `i64` containing the time at which the executable was compiled, in nanoseconds. + This is compatible with the `time.Time` type, i.e. `time.Time{_nsec=ODIN_COMPILE_TIMESTAMP}` +*/ +ODIN_COMPILE_TIMESTAMP :: ODIN_COMPILE_TIMESTAMP + +/* + `true` if the `-debug` command line switch is passed, which enables debug info generation. +*/ +ODIN_DEBUG :: ODIN_DEBUG + +/* + `true` if the `-default-to-nil-allocator` command line switch is passed, + which sets the initial `context.allocator` to an allocator that does nothing. +*/ +ODIN_DEFAULT_TO_NIL_ALLOCATOR :: ODIN_DEFAULT_TO_NIL_ALLOCATOR + +/* + `true` if the `-default-to-panic-allocator` command line switch is passed, + which sets the initial `context.allocator` to an allocator that panics if allocated from. +*/ +ODIN_DEFAULT_TO_PANIC_ALLOCATOR :: ODIN_DEFAULT_TO_PANIC_ALLOCATOR + +/* + `true` if the `-disable-assert` command line switch is passed, + which removes all calls to `assert` from the program. +*/ +ODIN_DISABLE_ASSERT :: ODIN_DISABLE_ASSERT + +/* + An `enum` value indicating the endianness of the target. + Possible values are: `.Little` and `.Big`. +*/ +ODIN_ENDIAN :: ODIN_ENDIAN + +/* + An `enum` value indicating the endianness of the target. + Possible values are: "little" and "big". +*/ +ODIN_ENDIAN_STRING :: ODIN_ENDIAN_STRING + +/* + An `enum` value set using the `-error-pos-style` switch, indicating the source location style used for compile errors and warnings. + Possible values are: `.Default` (Odin-style) and `.Unix`. +*/ +ODIN_ERROR_POS_STYLE :: ODIN_ERROR_POS_STYLE + +/* + `true` if the `-foreign-error-procedures` command line switch is passed, + which inhibits generation of runtime error procedures, so that they can be in a separate compilation unit. +*/ +ODIN_FOREIGN_ERROR_PROCEDURES :: ODIN_FOREIGN_ERROR_PROCEDURES + +/* + A `string` describing the microarchitecture used for code generation. + If not set using the `-microarch` command line switch, the compiler will pick a default. + Possible values include, but are not limited to: "sandybridge", "x86-64-v2". +*/ +ODIN_MICROARCH_STRING :: ODIN_MICROARCH_STRING + +/* + An `int` value representing the minimum OS version given to the linker, calculated as `major * 10_000 + minor * 100 + revision`. + If not set using the `-minimum-os-version` command line switch, it defaults to `0`. +*/ +ODIN_MINIMUM_OS_VERSION :: ODIN_MINIMUM_OS_VERSION + +/* + `true` if the `-no-bounds-check` command line switch is passed, which disables bounds checking at runtime. +*/ +ODIN_NO_BOUNDS_CHECK :: ODIN_NO_BOUNDS_CHECK + +/* + `true` if the `-no-crt` command line switch is passed, which inhibits linking with the C Runtime Library, a.k.a. LibC. +*/ +ODIN_NO_CRT :: ODIN_NO_CRT + +/* + `true` if the `-no-entry-point` command line switch is passed, which makes the declaration of a `main` procedure optional. +*/ +ODIN_NO_ENTRY_POINT :: ODIN_NO_ENTRY_POINT + +/* + `true` if the `-no-rtti` command line switch is passed, which inhibits generation of full Runtime Type Information. +*/ +ODIN_NO_RTTI :: ODIN_NO_RTTI + +/* + `true` if the `-no-type-assert` command line switch is passed, which disables type assertion checking program wide. +*/ +ODIN_NO_TYPE_ASSERT :: ODIN_NO_TYPE_ASSERT + +/* + An `enum` value indicating the optimization level selected using the `-o` command line switch. + Possible values are: `.None`, `.Minimal`, `.Size`, `.Speed`, and `.Aggressive`. +*/ +ODIN_OPTIMIZATION_MODE :: ODIN_OPTIMIZATION_MODE + +/* + An `enum` value indicating what the target operating system is. +*/ +ODIN_OS :: ODIN_OS + +/* + A `string` indicating what the target operating system is. +*/ +ODIN_OS_STRING :: ODIN_OS_STRING + +/* + An `enum` value indicating the platform subtarget, chosen using the `-subtarget` switch. + Possible values are: `.Default` `.iOS`, and `.Android`. +*/ +ODIN_PLATFORM_SUBTARGET :: ODIN_PLATFORM_SUBTARGET + +/* + A `string` representing the path of the folder containing the Odin compiler, + relative to which we expect to find the `base` and `core` package collections. +*/ +ODIN_ROOT :: ODIN_ROOT + +/* + A `bit_set` indicating the sanitizer flags set using the `-sanitize` command line switch. + Supported flags are `.Address`, `.Memory`, and `.Thread`. +*/ +ODIN_SANITIZER_FLAGS :: ODIN_SANITIZER_FLAGS + +/* + `true` if the code is being compiled via an invocation of `odin test`. +*/ +ODIN_TEST :: ODIN_TEST + +/* + `true` if built using the experimental Tilde backend. +*/ +ODIN_TILDE :: ODIN_TILDE + +/* + `true` if the `-use-separate-modules` command line switch is passed, + which builds each package into its own object file, and then links them together, instead of performing a unity build. +*/ +ODIN_USE_SEPARATE_MODULES :: ODIN_USE_SEPARATE_MODULES + +/* + `true` if Valgrind integration is supported on the target. +*/ +ODIN_VALGRIND_SUPPORT :: ODIN_VALGRIND_SUPPORT + +/* + A `string` which identifies the compiler being used. The official compiler sets this to `"odin"`. +*/ +ODIN_VENDOR :: ODIN_VENDOR + +/* + A `string` containing the version of the Odin compiler, typically in the format `dev-YYYY-MM`. +*/ +ODIN_VERSION :: ODIN_VERSION + +/* + A `string` containing the Git hash part of the Odin version. + Empty if `.git` could not be detected at the time the compiler was built. +*/ +ODIN_VERSION_HASH :: ODIN_VERSION_HASH + +/* + An `enum` set by the `-subsystem` flag, specifying which Windows subsystem the PE file was created for. + Possible values are: + `.Unknown` - Default and only value on non-Windows platforms + `.Console` - Default on Windows + `.Windows` - Can be used by graphical applications so Windows doesn't open an empty console + + There are some other possible values for e.g. EFI applications, but only Console and Windows are supported. + + See also: https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_optional_header64 +*/ +ODIN_WINDOWS_SUBSYSTEM :: ODIN_WINDOWS_SUBSYSTEM + +/* + An `string` set by the `-subsystem` flag, specifying which Windows subsystem the PE file was created for. + Possible values are: + "UNKNOWN" - Default and only value on non-Windows platforms + "CONSOLE" - Default on Windows + "WINDOWS" - Can be used by graphical applications so Windows doesn't open an empty console + + There are some other possible values for e.g. EFI applications, but only Console and Windows are supported. + + See also: https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_optional_header64 +*/ +ODIN_WINDOWS_SUBSYSTEM_STRING :: ODIN_WINDOWS_SUBSYSTEM_STRING + +/* + `true` if LLVM supports the f16 type. +*/ +__ODIN_LLVM_F16_SUPPORTED :: __ODIN_LLVM_F16_SUPPORTED + + byte :: u8 // alias @@ -131,3 +344,6 @@ soa_zip :: proc(slices: ...) -> #soa[]Struct --- soa_unzip :: proc(value: $S/#soa[]$E) -> (slices: ...) --- unreachable :: proc() -> ! --- + +// Where T is a string, slice, dynamic array, or pointer to an array type +raw_data :: proc(t: $T) -> rawptr \ No newline at end of file diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 00594c1b4..9d1685cd7 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -31,6 +31,24 @@ enum TargetOsKind : u16 { TargetOs_COUNT, }; +gb_global String target_os_names[TargetOs_COUNT] = { + str_lit(""), + str_lit("windows"), + str_lit("darwin"), + str_lit("linux"), + str_lit("essence"), + str_lit("freebsd"), + str_lit("openbsd"), + str_lit("netbsd"), + str_lit("haiku"), + + str_lit("wasi"), + str_lit("js"), + str_lit("orca"), + + str_lit("freestanding"), +}; + enum TargetArchKind : u16 { TargetArch_Invalid, @@ -45,6 +63,17 @@ enum TargetArchKind : u16 { TargetArch_COUNT, }; +gb_global String target_arch_names[TargetArch_COUNT] = { + str_lit(""), + str_lit("amd64"), + str_lit("i386"), + str_lit("arm32"), + str_lit("arm64"), + str_lit("wasm32"), + str_lit("wasm64p32"), + str_lit("riscv64"), +}; + enum TargetEndianKind : u8 { TargetEndian_Little, TargetEndian_Big, @@ -52,6 +81,11 @@ enum TargetEndianKind : u8 { TargetEndian_COUNT, }; +gb_global String target_endian_names[TargetEndian_COUNT] = { + str_lit("little"), + str_lit("big"), +}; + enum TargetABIKind : u16 { TargetABI_Default, @@ -61,7 +95,14 @@ enum TargetABIKind : u16 { TargetABI_COUNT, }; +gb_global String target_abi_names[TargetABI_COUNT] = { + str_lit(""), + str_lit("win64"), + str_lit("sysv"), +}; + enum Windows_Subsystem : u8 { + Windows_Subsystem_UNKNOWN, Windows_Subsystem_BOOT_APPLICATION, Windows_Subsystem_CONSOLE, // Default, Windows_Subsystem_EFI_APPLICATION, @@ -75,38 +116,23 @@ enum Windows_Subsystem : u8 { Windows_Subsystem_COUNT, }; -struct MicroarchFeatureList { - String microarch; - String features; -}; - -gb_global String target_os_names[TargetOs_COUNT] = { +gb_global String windows_subsystem_names[Windows_Subsystem_COUNT] = { str_lit(""), - str_lit("windows"), - str_lit("darwin"), - str_lit("linux"), - str_lit("essence"), - str_lit("freebsd"), - str_lit("openbsd"), - str_lit("netbsd"), - str_lit("haiku"), - - str_lit("wasi"), - str_lit("js"), - str_lit("orca"), - - str_lit("freestanding"), + str_lit("BOOT_APPLICATION"), + str_lit("CONSOLE"), // Default + str_lit("EFI_APPLICATION"), + str_lit("EFI_BOOT_SERVICE_DRIVER"), + str_lit("EFI_ROM"), + str_lit("EFI_RUNTIME_DRIVER"), + str_lit("NATIVE"), + str_lit("POSIX"), + str_lit("WINDOWS"), + str_lit("WINDOWSCE"), }; -gb_global String target_arch_names[TargetArch_COUNT] = { - str_lit(""), - str_lit("amd64"), - str_lit("i386"), - str_lit("arm32"), - str_lit("arm64"), - str_lit("wasm32"), - str_lit("wasm64p32"), - str_lit("riscv64"), +struct MicroarchFeatureList { + String microarch; + String features; }; #if defined(GB_SYSTEM_WINDOWS) @@ -114,20 +140,8 @@ gb_global String target_arch_names[TargetArch_COUNT] = { #else #include #endif - #include "build_settings_microarch.cpp" -gb_global String target_endian_names[TargetEndian_COUNT] = { - str_lit("little"), - str_lit("big"), -}; - -gb_global String target_abi_names[TargetABI_COUNT] = { - str_lit(""), - str_lit("win64"), - str_lit("sysv"), -}; - gb_global TargetEndianKind target_endians[TargetArch_COUNT] = { TargetEndian_Little, TargetEndian_Little, @@ -138,19 +152,6 @@ gb_global TargetEndianKind target_endians[TargetArch_COUNT] = { TargetEndian_Little, }; -gb_global String windows_subsystem_names[Windows_Subsystem_COUNT] = { - str_lit("BOOT_APPLICATION"), - str_lit("CONSOLE"), // Default - str_lit("EFI_APPLICATION"), - str_lit("EFI_BOOT_SERVICE_DRIVER"), - str_lit("EFI_ROM"), - str_lit("EFI_RUNTIME_DRIVER"), - str_lit("NATIVE"), - str_lit("POSIX"), - str_lit("WINDOWS"), - str_lit("WINDOWSCE"), -}; - #ifndef ODIN_VERSION_RAW #define ODIN_VERSION_RAW "dev-unknown-unknown" #endif @@ -393,17 +394,17 @@ String linker_choices[Linker_COUNT] = { // This stores the information for the specify architecture of this build struct BuildContext { // Constants - String ODIN_OS; // Target operating system - String ODIN_ARCH; // Target architecture - String ODIN_VENDOR; // Compiler vendor - String ODIN_VERSION; // Compiler version - String ODIN_ROOT; // Odin ROOT - String ODIN_BUILD_PROJECT_NAME; // Odin main/initial package's directory name - String ODIN_WINDOWS_SUBSYSTEM; // Empty string for non-Windows targets - bool ODIN_DEBUG; // Odin in debug mode - bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not - bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing) - bool ODIN_DEFAULT_TO_PANIC_ALLOCATOR; // Whether the default allocator is a "panic" allocator or not (i.e. panics on any call to it) + String ODIN_OS; // Target operating system + String ODIN_ARCH; // Target architecture + String ODIN_VENDOR; // Compiler vendor + String ODIN_VERSION; // Compiler version + String ODIN_ROOT; // Odin ROOT + String ODIN_BUILD_PROJECT_NAME; // Odin main/initial package's directory name + Windows_Subsystem ODIN_WINDOWS_SUBSYSTEM; // .Console, .Windows + bool ODIN_DEBUG; // Odin in debug mode + bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not + bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing) + bool ODIN_DEFAULT_TO_PANIC_ALLOCATOR; // Whether the default allocator is a "panic" allocator or not (i.e. panics on any call to it) bool ODIN_FOREIGN_ERROR_PROCEDURES; bool ODIN_VALGRIND_SUPPORT; @@ -1788,8 +1789,8 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta } // Default to subsystem:CONSOLE on Windows targets - if (bc->ODIN_WINDOWS_SUBSYSTEM == "" && bc->metrics.os == TargetOs_windows) { - bc->ODIN_WINDOWS_SUBSYSTEM = windows_subsystem_names[Windows_Subsystem_CONSOLE]; + if (bc->ODIN_WINDOWS_SUBSYSTEM == Windows_Subsystem_UNKNOWN && bc->metrics.os == TargetOs_windows) { + bc->ODIN_WINDOWS_SUBSYSTEM = Windows_Subsystem_CONSOLE; } if (subtarget == Subtarget_Android) { diff --git a/src/checker.cpp b/src/checker.cpp index aaa815365..9bc02cd87 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1078,11 +1078,30 @@ gb_internal void init_universal(void) { add_global_bool_constant("true", true); add_global_bool_constant("false", false); - add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR); - add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION); - add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); - add_global_string_constant("ODIN_BUILD_PROJECT_NAME", bc->ODIN_BUILD_PROJECT_NAME); - add_global_string_constant("ODIN_WINDOWS_SUBSYSTEM", bc->ODIN_WINDOWS_SUBSYSTEM); + add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR); + add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION); + add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); + add_global_string_constant("ODIN_BUILD_PROJECT_NAME", bc->ODIN_BUILD_PROJECT_NAME); + + { + GlobalEnumValue values[Windows_Subsystem_COUNT] = { + {"Unknown", Windows_Subsystem_UNKNOWN}, + {"Boot_Application", Windows_Subsystem_BOOT_APPLICATION}, + {"Console", Windows_Subsystem_CONSOLE}, + {"EFI_Application", Windows_Subsystem_EFI_APPLICATION}, + {"EFI_Boot_Service_Driver", Windows_Subsystem_EFI_BOOT_SERVICE_DRIVER}, + {"EFI_Rom", Windows_Subsystem_EFI_ROM}, + {"EFI_Runtime_Driver", Windows_Subsystem_EFI_RUNTIME_DRIVER}, + {"Native", Windows_Subsystem_NATIVE}, + {"Posix", Windows_Subsystem_POSIX}, + {"Windows", Windows_Subsystem_WINDOWS}, + {"Windows_CE", Windows_Subsystem_WINDOWSCE}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_Windows_Subsystem_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_WINDOWS_SUBSYSTEM", bc->ODIN_WINDOWS_SUBSYSTEM); + add_global_string_constant("ODIN_WINDOWS_SUBSYSTEM_STRING", windows_subsystem_names[bc->ODIN_WINDOWS_SUBSYSTEM]); + } { GlobalEnumValue values[TargetOs_COUNT] = { @@ -1102,7 +1121,7 @@ gb_internal void init_universal(void) { }; auto fields = add_global_enum_type(str_lit("Odin_OS_Type"), values, gb_count_of(values)); - add_global_enum_constant(fields, "ODIN_OS", bc->metrics.os); + add_global_enum_constant(fields, "ODIN_OS", bc->metrics.os); add_global_string_constant("ODIN_OS_STRING", target_os_names[bc->metrics.os]); } diff --git a/src/linker.cpp b/src/linker.cpp index 447d66d0a..71aee3a3b 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -321,7 +321,7 @@ try_cross_linking:; "", LIT(build_context.ODIN_ROOT), object_files, LIT(output_filename), link_settings, - LIT(build_context.ODIN_WINDOWS_SUBSYSTEM), + LIT(windows_subsystem_names[build_context.ODIN_WINDOWS_SUBSYSTEM]), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), lib_str @@ -341,7 +341,7 @@ try_cross_linking:; "", LIT(build_context.ODIN_ROOT), object_files, LIT(output_filename), link_settings, - LIT(build_context.ODIN_WINDOWS_SUBSYSTEM), + LIT(windows_subsystem_names[build_context.ODIN_WINDOWS_SUBSYSTEM]), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), lib_str @@ -404,7 +404,7 @@ try_cross_linking:; "", LIT(vs_exe_path), LIT(linker_name), object_files, LIT(res_path), LIT(output_filename), link_settings, - LIT(build_context.ODIN_WINDOWS_SUBSYSTEM), + LIT(windows_subsystem_names[build_context.ODIN_WINDOWS_SUBSYSTEM]), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), lib_str diff --git a/src/main.cpp b/src/main.cpp index 1ffdd0dba..dfc2f3213 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1627,9 +1627,9 @@ gb_internal bool parse_build_flags(Array args) { GB_ASSERT(value.kind == ExactValue_String); String subsystem = value.value_string; bool subsystem_found = false; - for (int i = 0; i < Windows_Subsystem_COUNT; i++) { + for (int i = 1; i < Windows_Subsystem_COUNT; i++) { if (str_eq_ignore_case(subsystem, windows_subsystem_names[i])) { - build_context.ODIN_WINDOWS_SUBSYSTEM = windows_subsystem_names[i]; + build_context.ODIN_WINDOWS_SUBSYSTEM = Windows_Subsystem(i); subsystem_found = true; break; } @@ -1638,7 +1638,7 @@ gb_internal bool parse_build_flags(Array args) { // WINDOW is a hidden alias for WINDOWS. Check it. String subsystem_windows_alias = str_lit("WINDOW"); if (!subsystem_found && str_eq_ignore_case(subsystem, subsystem_windows_alias)) { - build_context.ODIN_WINDOWS_SUBSYSTEM = windows_subsystem_names[Windows_Subsystem_WINDOWS]; + build_context.ODIN_WINDOWS_SUBSYSTEM = Windows_Subsystem_WINDOWS; subsystem_found = true; break; } @@ -1646,8 +1646,8 @@ gb_internal bool parse_build_flags(Array args) { if (!subsystem_found) { gb_printf_err("Invalid -subsystem string, got %.*s. Expected one of:\n", LIT(subsystem)); gb_printf_err("\t"); - for (int i = 0; i < Windows_Subsystem_COUNT; i++) { - if (i > 0) { + for (int i = 1; i < Windows_Subsystem_COUNT; i++) { + if (i > 1) { gb_printf_err(", "); } gb_printf_err("%.*s", LIT(windows_subsystem_names[i])); -- cgit v1.2.3 From 0d0f311df1e31102f4138c1a28110f86dcf60fca Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 29 May 2025 19:02:46 +0200 Subject: Always provide /PDB option to linker if generating debug info. radlink by default places the .PDB file in the working directory, even if /OUT says to place it elsewhere, unlike link.exe, which places it next to the executable by default. So, if compiling using -debug, we generate a PDB path even if -pdb-name wasn't used to override it. --- src/build_settings.cpp | 16 ++++++++++++---- src/linker.cpp | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src/linker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 9d1685cd7..e46670528 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -2066,10 +2066,6 @@ gb_internal bool init_build_paths(String init_filename) { } } - if (bc->pdb_filepath.len > 0) { - bc->build_paths[BuildPath_PDB] = path_from_string(ha, bc->pdb_filepath); - } - if ((bc->command_kind & Command__does_build) && (!bc->ignore_microsoft_magic)) { // NOTE(ic): It would be nice to extend this so that we could specify the Visual Studio version that we want instead of defaulting to the latest. Find_Result find_result = find_visual_studio_and_windows_sdk(); @@ -2268,6 +2264,18 @@ gb_internal bool init_build_paths(String init_filename) { bc->build_paths[BuildPath_Output] = output_path; } + if (build_context.metrics.os == TargetOs_windows && build_context.ODIN_DEBUG) { + if (bc->pdb_filepath.len > 0) { + bc->build_paths[BuildPath_PDB] = path_from_string(ha, bc->pdb_filepath); + } else { + Path pdb_path; + pdb_path.basename = copy_string(ha, bc->build_paths[BuildPath_Output].basename); + pdb_path.name = copy_string(ha, bc->build_paths[BuildPath_Output].name); + pdb_path.ext = copy_string(ha, STR_LIT("pdb")); + bc->build_paths[BuildPath_PDB] = pdb_path; + } + } + // Do we have an extension? We might not if the output filename was supplied. if (bc->build_paths[BuildPath_Output].ext.len == 0) { if (build_context.metrics.os == TargetOs_windows || is_arch_wasm() || build_context.build_mode != BuildMode_Executable) { diff --git a/src/linker.cpp b/src/linker.cpp index 71aee3a3b..f10e47ec3 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -281,7 +281,7 @@ try_cross_linking:; link_settings = gb_string_append_fmt(link_settings, " /ENTRY:mainCRTStartup"); } - if (build_context.pdb_filepath != "") { + if (build_context.build_paths[BuildPath_PDB].name != "") { String pdb_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_PDB]); link_settings = gb_string_append_fmt(link_settings, " /PDB:\"%.*s\"", LIT(pdb_path)); } -- cgit v1.2.3 From 405bf7cd5549edd1f718fce2b53f845dde6fe690 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sun, 1 Jun 2025 15:59:38 +0200 Subject: Also clean up .dSym on Darwin --- src/build_settings.cpp | 28 ++++++++++++++++++---------- src/linker.cpp | 6 +++--- src/main.cpp | 12 +++++++----- 3 files changed, 28 insertions(+), 18 deletions(-) (limited to 'src/linker.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index e0ca03a61..2c444f4eb 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -288,7 +288,7 @@ enum BuildPath : u8 { BuildPath_VS_LIB, // vs_library_path BuildPath_Output, // Output Path for .exe, .dll, .so, etc. Can be overridden with `-out:`. - BuildPath_PDB, // Output Path for .pdb file, can be overridden with `-pdb-name:`. + BuildPath_Symbols, // Output Path for .pdb or .dSym file, can be overridden with `-pdb-name:`. BuildPathCOUNT, }; @@ -2292,15 +2292,23 @@ gb_internal bool init_build_paths(String init_filename) { bc->build_paths[BuildPath_Output] = output_path; } - if (build_context.metrics.os == TargetOs_windows && build_context.ODIN_DEBUG) { - if (bc->pdb_filepath.len > 0) { - bc->build_paths[BuildPath_PDB] = path_from_string(ha, bc->pdb_filepath); - } else { - Path pdb_path; - pdb_path.basename = copy_string(ha, bc->build_paths[BuildPath_Output].basename); - pdb_path.name = copy_string(ha, bc->build_paths[BuildPath_Output].name); - pdb_path.ext = copy_string(ha, STR_LIT("pdb")); - bc->build_paths[BuildPath_PDB] = pdb_path; + if (build_context.ODIN_DEBUG) { + if (build_context.metrics.os == TargetOs_windows) { + if (bc->pdb_filepath.len > 0) { + bc->build_paths[BuildPath_Symbols] = path_from_string(ha, bc->pdb_filepath); + } else { + Path symbol_path; + symbol_path.basename = copy_string(ha, bc->build_paths[BuildPath_Output].basename); + symbol_path.name = copy_string(ha, bc->build_paths[BuildPath_Output].name); + symbol_path.ext = copy_string(ha, STR_LIT("pdb")); + bc->build_paths[BuildPath_Symbols] = symbol_path; + } + } else if (build_context.metrics.os == TargetOs_darwin) { + Path symbol_path; + symbol_path.basename = copy_string(ha, bc->build_paths[BuildPath_Output].basename); + symbol_path.name = copy_string(ha, bc->build_paths[BuildPath_Output].name); + symbol_path.ext = copy_string(ha, STR_LIT("dSym")); + bc->build_paths[BuildPath_Symbols] = symbol_path; } } diff --git a/src/linker.cpp b/src/linker.cpp index f10e47ec3..2210c1306 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -281,9 +281,9 @@ try_cross_linking:; link_settings = gb_string_append_fmt(link_settings, " /ENTRY:mainCRTStartup"); } - if (build_context.build_paths[BuildPath_PDB].name != "") { - String pdb_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_PDB]); - link_settings = gb_string_append_fmt(link_settings, " /PDB:\"%.*s\"", LIT(pdb_path)); + if (build_context.build_paths[BuildPath_Symbols].name != "") { + String symbol_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Symbols]); + link_settings = gb_string_append_fmt(link_settings, " /PDB:\"%.*s\"", LIT(symbol_path)); } if (build_context.build_mode != BuildMode_StaticLibrary) { diff --git a/src/main.cpp b/src/main.cpp index b0f839509..af321258c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3890,12 +3890,14 @@ end_of_code_gen:; char const *filename = cast(char const *)exe_name.text; gb_file_remove(filename); - if (build_context.metrics.os == TargetOs_windows && build_context.ODIN_DEBUG) { - String pdb_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_PDB]); - defer (gb_free(heap_allocator(), pdb_path.text)); + if (build_context.ODIN_DEBUG) { + if (build_context.metrics.os == TargetOs_windows || build_context.metrics.os == TargetOs_darwin) { + String symbol_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Symbols]); + defer (gb_free(heap_allocator(), symbol_path.text)); - filename = cast(char const *)pdb_path.text; - gb_file_remove(filename); + filename = cast(char const *)symbol_path.text; + gb_file_remove(filename); + } } } } -- cgit v1.2.3