2024-10-25 07:05:50 -06:00

203 lines
4.3 KiB
C

#pragma once
#include <std/base.h>
#include <std/os.h>
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
{
COMPILER_BACKEND_NEST,
COMPILER_BACKEND_LLVM,
COMPILER_BACKEND_COUNT,
} CompilerBackend;
fn String compiler_backend_to_one_char_string(CompilerBackend backend)
{
switch (backend)
{
case COMPILER_BACKEND_NEST:
return strlit("n");
case COMPILER_BACKEND_LLVM:
return strlit("l");
case COMPILER_BACKEND_COUNT:
unreachable();
}
}
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_one_char_string(candidate), string))
{
result = candidate;
break;
}
}
return result;
}
STRUCT(CodegenOptions)
{
String test_name;
Target target;
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;
}