diff --git a/bootstrap/include/nest/base.h b/bootstrap/include/nest/base.h index e07adea..456371d 100644 --- a/bootstrap/include/nest/base.h +++ b/bootstrap/include/nest/base.h @@ -1,6 +1,50 @@ #pragma once #include +#include + +typedef enum CpuArchitecture : u8 +{ + CPU_ARCH_X86_64, + CPU_ARCH_AARCH64, +} CpuArchitecture; + +fn String cpu_to_string(CpuArchitecture cpu) +{ + switch (cpu) + { + case CPU_ARCH_X86_64: + return strlit("x86_64"); + case CPU_ARCH_AARCH64: + return strlit("aarch64"); + } +} + +typedef enum OperatingSystem : u8 +{ + OPERATING_SYSTEM_LINUX, + OPERATING_SYSTEM_MAC, + OPERATING_SYSTEM_WINDOWS, +} OperatingSystem; + +fn String operating_system_to_string(OperatingSystem os) +{ + switch (os) + { + case OPERATING_SYSTEM_LINUX: + return strlit("linux"); + case OPERATING_SYSTEM_MAC: + return strlit("macos"); + case OPERATING_SYSTEM_WINDOWS: + return strlit("windows"); + } +} + +STRUCT(Target) +{ + CpuArchitecture cpu; + OperatingSystem os; +}; typedef enum CompilerBackend : u8 { @@ -9,7 +53,7 @@ typedef enum CompilerBackend : u8 COMPILER_BACKEND_COUNT, } CompilerBackend; -fn String compiler_backend_to_string(CompilerBackend backend) +fn String compiler_backend_to_one_char_string(CompilerBackend backend) { switch (backend) { @@ -22,14 +66,104 @@ fn String compiler_backend_to_string(CompilerBackend backend) } } -fn CompilerBackend string_to_compiler_backend(String string) +fn String compiler_backend_to_string(CompilerBackend backend) +{ + switch (backend) + { + case COMPILER_BACKEND_NEST: + return strlit("nest"); + case COMPILER_BACKEND_LLVM: + return strlit("llvm"); + case COMPILER_BACKEND_COUNT: + unreachable(); + } +} + +typedef enum BinaryFileType : u8 +{ + BINARY_FILE_OBJECT, + BINARY_FILE_STATIC_LIBRARY, + BINARY_FILE_DYNAMIC_LIBRARY, + BINARY_FILE_EXECUTABLE, +} BinaryFileType; + +STRUCT(BinaryPathOptions) +{ + String build_directory; + String name; + Target target; + CompilerBackend backend; + BinaryFileType binary_file_type; +}; + +fn String binary_path_from_options(Arena* arena, BinaryPathOptions options) +{ + String object_extension; + switch (options.target.os) + { + case OPERATING_SYSTEM_WINDOWS: + object_extension = strlit(".obj"); + break; + default: + object_extension = strlit(".o"); + break; + } + String executable_extension; + switch (options.target.os) + { + case OPERATING_SYSTEM_WINDOWS: + executable_extension = strlit(".exe"); + break; + default: + executable_extension = strlit(""); + break; + } + + String extension; + switch (options.binary_file_type) + { + case BINARY_FILE_OBJECT: + extension = object_extension; + break; + case BINARY_FILE_STATIC_LIBRARY: + unreachable(); + break; + case BINARY_FILE_DYNAMIC_LIBRARY: + unreachable(); + break; + case BINARY_FILE_EXECUTABLE: + extension = executable_extension; + break; + } + + auto backend_string = compiler_backend_to_string(options.backend); + auto cpu_string = cpu_to_string(options.target.cpu); + auto os_string = operating_system_to_string(options.target.os); + String parts[] = { + options.build_directory, + strlit("/"), + options.name, + // strlit("_"), + // cpu_string, + // strlit("_"), + // os_string, + // strlit("_"), + // backend_string, + extension, + }; + + auto result = arena_join_string(arena, (Slice(String)) array_to_slice(parts)); + return result; +} + +fn CompilerBackend one_char_string_to_compiler_backend(String string) { CompilerBackend result = COMPILER_BACKEND_COUNT; for (u32 i = 0; i < COMPILER_BACKEND_COUNT; i += 1) { auto candidate = (CompilerBackend)i; - if (s_equal(compiler_backend_to_string(candidate), string)) + if (s_equal(compiler_backend_to_one_char_string(candidate), string)) { result = candidate; break; @@ -39,25 +173,6 @@ fn CompilerBackend string_to_compiler_backend(String string) return result; } -typedef enum CpuArchitecture : u8 -{ - CPU_ARCH_X86_64, - CPU_ARCH_AARCH64, -} CpuArchitecture; - -typedef enum OperatingSystem : u8 -{ - OPERATING_SYSTEM_LINUX, - OPERATING_SYSTEM_MAC, - OPERATING_SYSTEM_WINDOWS, -} OperatingSystem; - -STRUCT(Target) -{ - CpuArchitecture cpu; - OperatingSystem os; -}; - STRUCT(CodegenOptions) { String test_name; @@ -65,3 +180,23 @@ STRUCT(CodegenOptions) CompilerBackend backend; u8 generate_debug_information; }; + +fn Target native_target_get() +{ + Target target = { +#if _WIN32 + .cpu = CPU_ARCH_X86_64, + .os = OPERATING_SYSTEM_WINDOWS, +#elif defined(__APPLE__) + .cpu = CPU_ARCH_AARCH64, + .os = OPERATING_SYSTEM_MAC, +#elif defined(__linux__) + .cpu = CPU_ARCH_X86_64, + .os = OPERATING_SYSTEM_LINUX, +#else +#error "Unknown platform" +#endif + }; + + return target; +} diff --git a/bootstrap/include/std/os.h b/bootstrap/include/std/os.h index faba3e4..3189a07 100644 --- a/bootstrap/include/std/os.h +++ b/bootstrap/include/std/os.h @@ -1,3 +1,5 @@ +#pragma once + #include STRUCT(OSFileOpenFlags) diff --git a/bootstrap/nest/main.c b/bootstrap/nest/main.c index f95f75b..10bbf2b 100644 --- a/bootstrap/nest/main.c +++ b/bootstrap/nest/main.c @@ -23576,28 +23576,21 @@ fn void code_generation(Thread* restrict thread, CodegenOptions options) auto* restrict builder = &cfg_builder; VirtualBuffer(u8) code = {}; - auto object_path = arena_join_string(thread->arena, (Slice(String)) array_to_slice(((String[]) { - strlit("nest/"), - options.test_name, - strlit(".o"), - // options.backend == COMPILER_BACKEND_C ? strlit(".c") : strlit(".o"), - }))); + auto object_path = binary_path_from_options(thread->arena, (BinaryPathOptions) { + .build_directory = strlit("nest"), + .name = options.test_name, + .target = options.target, + .backend = options.backend, + .binary_file_type = BINARY_FILE_OBJECT, + }); - auto exe_path_view = s_get_slice(u8, object_path, 0, object_path.length - 2); - u32 extra_bytes = 0; -#if _WIN32 - extra_bytes = strlen(".exe"); -#endif - String exe_path = { - .pointer = arena_allocate_bytes(thread->arena, exe_path_view.length + extra_bytes + 1, 1), - .length = exe_path_view.length + extra_bytes, - }; - - memcpy(exe_path.pointer, exe_path_view.pointer, exe_path_view.length); -#if _WIN32 - memcpy(exe_path.pointer + exe_path_view.length, ".exe", extra_bytes); -#endif - exe_path.pointer[exe_path_view.length + extra_bytes] = 0; + auto exe_path = binary_path_from_options(thread->arena, (BinaryPathOptions) { + .build_directory = strlit("nest"), + .name = options.test_name, + .target = options.target, + .backend = options.backend, + .binary_file_type = BINARY_FILE_EXECUTABLE, + }); for (u32 function_i = 0; function_i < thread->buffer.functions.length; function_i += 1) { @@ -24791,7 +24784,7 @@ void entry_point(int argc, char* argv[], char* envp[]) } String source_file_path = arguments.pointer[1]; - CompilerBackend compiler_backend = string_to_compiler_backend(arguments.pointer[2]); + CompilerBackend compiler_backend = one_char_string_to_compiler_backend(arguments.pointer[2]); if (compiler_backend == COMPILER_BACKEND_COUNT) { print("Invalid backend: {s}\n", arguments.pointer[2]); @@ -24799,20 +24792,7 @@ void entry_point(int argc, char* argv[], char* envp[]) } u8 emit_ir = arguments.length >= 4 && arguments.pointer[3].pointer[0] == 'y'; - Target target = { -#if _WIN32 - .cpu = CPU_ARCH_X86_64, - .os = OPERATING_SYSTEM_WINDOWS, -#elif defined(__APPLE__) - .cpu = CPU_ARCH_AARCH64, - .os = OPERATING_SYSTEM_MAC, -#elif defined(__linux__) - .cpu = CPU_ARCH_X86_64, - .os = OPERATING_SYSTEM_LINUX, -#else -#error "Unknown platform" -#endif - }; + Target target = native_target_get(); os_directory_make(strlit("nest")); diff --git a/bootstrap/runner/runner.c b/bootstrap/runner/runner.c index 331b0af..584d384 100644 --- a/bootstrap/runner/runner.c +++ b/bootstrap/runner/runner.c @@ -22,7 +22,7 @@ typedef enum CMakeBuildType fn void run(Arena* arena, char** envp, String compiler_path, CompilerBackend compiler_backend, u8 debug, char* nest_source_path) { CStringSlice args = {}; - auto compiler_backend_string = compiler_backend_to_string(compiler_backend); + auto compiler_backend_string = compiler_backend_to_one_char_string(compiler_backend); #define common_compile_and_run_args \ string_to_c(compiler_path), \ @@ -87,6 +87,8 @@ fn void run_tests(Arena* arena, String compiler_path, TestOptions const * const print("COMPILER BUILD [OK]\n"); print("===========================\n\n"); + Target target = native_target_get(); + for (u32 test_i = 0; test_i < test_options->test_paths.length; test_i += 1) { String test_path = test_options->test_paths.pointer[test_i]; @@ -97,7 +99,7 @@ fn void run_tests(Arena* arena, String compiler_path, TestOptions const * const for (u32 engine_i = 0; engine_i < test_options->compiler_backends.length; engine_i += 1) { CompilerBackend compiler_backend = test_options->compiler_backends.pointer[engine_i]; - auto compiler_backend_string = compiler_backend_to_string(compiler_backend); + auto compiler_backend_string = compiler_backend_to_one_char_string(compiler_backend); char* arguments[] = { string_to_c(compiler_path), @@ -110,16 +112,15 @@ fn void run_tests(Arena* arena, String compiler_path, TestOptions const * const // if (compiler_backend != COMPILER_BACKEND_INTERPRETER) { - String path_split[] = { - strlit("./" nest_dir "/"), - test_name, -#if _WIN32 - strlit(".exe"), -#endif - }; - String out_program = arena_join_string(arena, ((Slice(String)) array_to_slice(path_split))); + auto executable = binary_path_from_options(arena, (BinaryPathOptions) { + .build_directory = strlit(nest_dir), + .name = test_name, + .target = target, + .backend = compiler_backend, + .binary_file_type = BINARY_FILE_EXECUTABLE, + }); char* run_arguments[] = { - string_to_c(out_program), + string_to_c(executable), 0, }; run_command(arena, (CStringSlice) array_to_slice(run_arguments), envp); @@ -155,9 +156,9 @@ void entry_point(int argc, char* argv[], char* envp[]) char* c_argument = argv[i]; auto argument = cstr(c_argument); - if (string_to_compiler_backend(argument) != COMPILER_BACKEND_COUNT) + if (one_char_string_to_compiler_backend(argument) != COMPILER_BACKEND_COUNT) { - preferred_compiler_backend = string_to_compiler_backend(argument); + preferred_compiler_backend = one_char_string_to_compiler_backend(argument); } else if (string_starts_with(argument, strlit("build_type="))) { diff --git a/bootstrap/std/os.c b/bootstrap/std/os.c index 630ab06..e8a7dd8 100644 --- a/bootstrap/std/os.c +++ b/bootstrap/std/os.c @@ -1352,6 +1352,7 @@ String file_read(Arena* arena, String path) void file_write(FileWriteOptions options) { + print("Writing file \"{s}\"...\n", options.path); auto fd = os_file_open(options.path, (OSFileOpenFlags) { .write = 1, .truncate = 1,