mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 14:48:47 +00:00
essence cross compile
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
when ODIN_OS == "windows" do export "core:os_windows.odin";
|
when ODIN_OS == "windows" do export "core:os_windows.odin";
|
||||||
when ODIN_OS == "osx" do export "core:os_x.odin";
|
when ODIN_OS == "osx" do export "core:os_x.odin";
|
||||||
when ODIN_OS == "linux" do export "core:os_linux.odin";
|
when ODIN_OS == "linux" do export "core:os_linux.odin";
|
||||||
|
when ODIN_OS == "essence" do export "core:os_essence.odin";
|
||||||
|
|
||||||
import "mem.odin";
|
import "mem.odin";
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
foreign import api "system:api"
|
||||||
|
|
||||||
|
Handle :: int;
|
||||||
|
Errno :: int;
|
||||||
|
|
||||||
|
O_RDONLY :: 1;
|
||||||
|
O_WRONLY :: 2;
|
||||||
|
O_CREATE :: 4;
|
||||||
|
O_TRUNC :: 4;
|
||||||
|
|
||||||
|
OS_Node_Type :: enum i32 {
|
||||||
|
File = 0,
|
||||||
|
Directory = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_Node_Information :: struct #ordered {
|
||||||
|
handle: Handle,
|
||||||
|
id: [16]u8,
|
||||||
|
ntype: OS_Node_Type,
|
||||||
|
size: i64,
|
||||||
|
position: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
foreign api {
|
||||||
|
@(link_name="OSHelloWorld") os_hello_world :: proc() ---;
|
||||||
|
@(link_name="OSPrintDirect") os_print_direct :: proc(string: ^u8, length: int) ---;
|
||||||
|
@(link_name="OSHeapAllocate") os_heap_allocate :: proc(bytes: int, zero: bool) -> rawptr ---;
|
||||||
|
@(link_name="OSHeapFree") os_heap_free :: proc(address: rawptr) ---;
|
||||||
|
@(link_name="OSOpenNode") os_open_node :: proc(path: ^u8, path_length: int, flags: u64, information: ^OS_Node_Information) -> Errno ---;
|
||||||
|
@(link_name="OSResizeFile") os_resize_file :: proc(handle: Handle, new_size: u64) -> Errno ---;
|
||||||
|
@(link_name="OSCloseHandle") os_close_handle :: proc(handle: Handle) ---;
|
||||||
|
@(link_name="OSWriteFileSync") os_write_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---;
|
||||||
|
@(link_name="OSReadFileSync") os_read_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---;
|
||||||
|
@(link_name="OSInitialiseAPI") os_initialise_api :: proc() -> int ---;
|
||||||
|
@(link_name="OSTerminateProcess") os_terminate_process :: proc(handle: Handle) ---;
|
||||||
|
@(link_name="realloc") os_heap_reallocate :: proc(address: rawptr, size: int) -> rawptr ---;
|
||||||
|
}
|
||||||
|
|
||||||
|
stdin := cast(Handle) -1; // Not implemented
|
||||||
|
stdout := cast(Handle) 0;
|
||||||
|
stderr := cast(Handle) 0;
|
||||||
|
|
||||||
|
current_thread_id :: proc() -> int {
|
||||||
|
// Not implemented
|
||||||
|
return int(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_alloc :: proc(size: int) -> rawptr {
|
||||||
|
return os_heap_allocate(size, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_free :: proc(address: rawptr) {
|
||||||
|
os_heap_free(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_resize :: proc(address: rawptr, new_size: int) -> rawptr {
|
||||||
|
return os_heap_reallocate(address, new_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errno) {
|
||||||
|
information := new(OS_Node_Information);
|
||||||
|
error := os_open_node(&path[0], len(path), cast(u64) mode, information);
|
||||||
|
if (error < -1) { return 0,1; }
|
||||||
|
information.position = 0;
|
||||||
|
if (mode&O_TRUNC==O_TRUNC) {
|
||||||
|
error := os_resize_file(information.handle, 0);
|
||||||
|
if (error < -1) { return 0,1; }
|
||||||
|
}
|
||||||
|
return cast(Handle) cast(uintptr) information,0;
|
||||||
|
}
|
||||||
|
|
||||||
|
close :: proc(fd: Handle) {
|
||||||
|
information := cast(^OS_Node_Information) cast(uintptr) fd;
|
||||||
|
os_close_handle(information.handle);
|
||||||
|
free(information);
|
||||||
|
}
|
||||||
|
|
||||||
|
file_size :: proc(fd: Handle) -> (i64, Errno) {
|
||||||
|
// Not (properly) implemented
|
||||||
|
information := cast(^OS_Node_Information) cast(uintptr) fd;
|
||||||
|
return information.size,0;
|
||||||
|
}
|
||||||
|
|
||||||
|
write :: proc(fd: Handle, data: []u8) -> (int, Errno) {
|
||||||
|
if (fd == 0) {
|
||||||
|
os_print_direct(&data[0], len(data));
|
||||||
|
return len(data), 0;
|
||||||
|
} else if (fd == 1) {
|
||||||
|
assert(false);
|
||||||
|
return 0, 1;
|
||||||
|
} else {
|
||||||
|
information := cast(^OS_Node_Information) cast(uintptr) fd;
|
||||||
|
count := os_write_file_sync(information.handle, information.position, cast(i64) len(data), cast(rawptr) &data[0]);
|
||||||
|
if (count < 0) { return 0, 1; }
|
||||||
|
information.position += count;
|
||||||
|
return cast(int) count, 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
read :: proc(fd: Handle, data: []u8) -> (int, Errno) {
|
||||||
|
if (fd == 0 || fd == 1) {
|
||||||
|
assert(false);
|
||||||
|
return 0, 1;
|
||||||
|
} else {
|
||||||
|
information := cast(^OS_Node_Information) cast(uintptr) fd;
|
||||||
|
count := os_read_file_sync(information.handle, information.position, cast(i64) len(data), cast(rawptr) &data[0]);
|
||||||
|
if (count < 0) { return 0, 1; }
|
||||||
|
information.position += count;
|
||||||
|
return cast(int) count, 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os_terminate_this_process :: proc() {
|
||||||
|
os_terminate_process(0x1001);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x100000;
|
||||||
|
.text BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.text)
|
||||||
|
}
|
||||||
|
.rodata BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.rodata)
|
||||||
|
}
|
||||||
|
.data BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(COMMON)
|
||||||
|
*(.bss)
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-1
@@ -309,6 +309,8 @@ String get_fullpath_core(gbAllocator a, String path) {
|
|||||||
|
|
||||||
|
|
||||||
String const ODIN_VERSION = str_lit("0.7.1");
|
String const ODIN_VERSION = str_lit("0.7.1");
|
||||||
|
String cross_compile_target = str_lit("");
|
||||||
|
String cross_compile_lib_dir = str_lit("");
|
||||||
|
|
||||||
void init_build_context(void) {
|
void init_build_context(void) {
|
||||||
BuildContext *bc = &build_context;
|
BuildContext *bc = &build_context;
|
||||||
@@ -330,6 +332,10 @@ void init_build_context(void) {
|
|||||||
bc->ODIN_OS = str_lit("linux");
|
bc->ODIN_OS = str_lit("linux");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (cross_compile_target.len) {
|
||||||
|
bc->ODIN_OS = cross_compile_target;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(GB_ARCH_64_BIT)
|
#if defined(GB_ARCH_64_BIT)
|
||||||
bc->ODIN_ARCH = str_lit("amd64");
|
bc->ODIN_ARCH = str_lit("amd64");
|
||||||
#else
|
#else
|
||||||
@@ -376,7 +382,11 @@ void init_build_context(void) {
|
|||||||
bc->max_align = 16;
|
bc->max_align = 16;
|
||||||
|
|
||||||
bc->llc_flags = str_lit("-march=x86-64 ");
|
bc->llc_flags = str_lit("-march=x86-64 ");
|
||||||
bc->link_flags = str_lit(LINK_FLAG_X64 " ");
|
if (str_eq_ignore_case(cross_compile_target, str_lit("Essence"))) {
|
||||||
|
bc->link_flags = str_lit(" ");
|
||||||
|
} else {
|
||||||
|
bc->link_flags = str_lit(LINK_FLAG_X64 " ");
|
||||||
|
}
|
||||||
} else if (bc->ODIN_ARCH == "x86") {
|
} else if (bc->ODIN_ARCH == "x86") {
|
||||||
bc->word_size = 4;
|
bc->word_size = 4;
|
||||||
bc->max_align = 8;
|
bc->max_align = 8;
|
||||||
|
|||||||
@@ -8634,6 +8634,14 @@ void ir_gen_tree(irGen *s) {
|
|||||||
if (!(build_context.is_dll && !has_dll_main)) {
|
if (!(build_context.is_dll && !has_dll_main)) {
|
||||||
// main :: proc(argc: i32, argv: ^^u8) -> i32
|
// main :: proc(argc: i32, argv: ^^u8) -> i32
|
||||||
String name = str_lit("main");
|
String name = str_lit("main");
|
||||||
|
|
||||||
|
if (str_eq_ignore_case(cross_compile_target, str_lit("Essence"))) {
|
||||||
|
// This is a bit hacky,
|
||||||
|
// because this makes this function the first function run in the executable
|
||||||
|
// so it won't actually have the argc/argv arguments.
|
||||||
|
name = str_lit("ProgramEntry");
|
||||||
|
}
|
||||||
|
|
||||||
Type *proc_params = make_type_tuple(a);
|
Type *proc_params = make_type_tuple(a);
|
||||||
Type *proc_results = make_type_tuple(a);
|
Type *proc_results = make_type_tuple(a);
|
||||||
|
|
||||||
|
|||||||
+47
-5
@@ -77,6 +77,7 @@ i32 system_exec_command_line_app(char *name, bool is_silent, char *fmt, ...) {
|
|||||||
va_end(va);
|
va_end(va);
|
||||||
cmd = make_string(cast(u8 *)&cmd_line, cmd_len-1);
|
cmd = make_string(cast(u8 *)&cmd_line, cmd_len-1);
|
||||||
|
|
||||||
|
//printf("do: %s\n", cmd_line);
|
||||||
exit_code = system(&cmd_line[0]);
|
exit_code = system(&cmd_line[0]);
|
||||||
|
|
||||||
// pid_t pid = fork();
|
// pid_t pid = fork();
|
||||||
@@ -210,6 +211,8 @@ enum BuildFlagKind {
|
|||||||
BuildFlag_Collection,
|
BuildFlag_Collection,
|
||||||
BuildFlag_BuildMode,
|
BuildFlag_BuildMode,
|
||||||
BuildFlag_Debug,
|
BuildFlag_Debug,
|
||||||
|
BuildFlag_CrossCompile,
|
||||||
|
BuildFlag_CrossLibDir,
|
||||||
|
|
||||||
BuildFlag_COUNT,
|
BuildFlag_COUNT,
|
||||||
};
|
};
|
||||||
@@ -246,6 +249,8 @@ bool parse_build_flags(Array<String> args) {
|
|||||||
add_flag(&build_flags, BuildFlag_Collection, str_lit("collection"), BuildFlagParam_String);
|
add_flag(&build_flags, BuildFlag_Collection, str_lit("collection"), BuildFlagParam_String);
|
||||||
add_flag(&build_flags, BuildFlag_BuildMode, str_lit("build-mode"), BuildFlagParam_String);
|
add_flag(&build_flags, BuildFlag_BuildMode, str_lit("build-mode"), BuildFlagParam_String);
|
||||||
add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None);
|
add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None);
|
||||||
|
add_flag(&build_flags, BuildFlag_CrossCompile, str_lit("cross-compile"), BuildFlagParam_String);
|
||||||
|
add_flag(&build_flags, BuildFlag_CrossLibDir, str_lit("cross-lib-dir"), BuildFlagParam_String);
|
||||||
|
|
||||||
|
|
||||||
Array<String> flag_args = args;
|
Array<String> flag_args = args;
|
||||||
@@ -399,6 +404,33 @@ bool parse_build_flags(Array<String> args) {
|
|||||||
build_context.keep_temp_files = true;
|
build_context.keep_temp_files = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BuildFlag_CrossCompile: {
|
||||||
|
GB_ASSERT(value.kind == ExactValue_String);
|
||||||
|
cross_compile_target = value.value_string;
|
||||||
|
#ifdef GB_SYSTEM_UNIX
|
||||||
|
#ifdef GB_ARCH_64_BIT
|
||||||
|
if (str_eq_ignore_case(cross_compile_target, str_lit("Essence"))) {
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
gb_printf_err("Unsupported cross compilation target '%.*s'\n", LIT(cross_compile_target));
|
||||||
|
gb_printf_err("Currently supported targets: Essence (from 64-bit Unixes only)\n");
|
||||||
|
bad_flags = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case BuildFlag_CrossLibDir: {
|
||||||
|
GB_ASSERT(value.kind == ExactValue_String);
|
||||||
|
if (cross_compile_lib_dir.len) {
|
||||||
|
gb_printf_err("Multiple cross compilation library directories\n");
|
||||||
|
bad_flags = true;
|
||||||
|
} else {
|
||||||
|
cross_compile_lib_dir = concatenate_strings(heap_allocator(), str_lit("-L"), value.value_string);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case BuildFlag_Collection: {
|
case BuildFlag_Collection: {
|
||||||
GB_ASSERT(value.kind == ExactValue_String);
|
GB_ASSERT(value.kind == ExactValue_String);
|
||||||
String str = value.value_string;
|
String str = value.value_string;
|
||||||
@@ -831,10 +863,12 @@ int main(int arg_count, char **arg_ptr) {
|
|||||||
"llc \"%.*s.bc\" -filetype=obj -relocation-model=pic -O%d "
|
"llc \"%.*s.bc\" -filetype=obj -relocation-model=pic -O%d "
|
||||||
"%.*s "
|
"%.*s "
|
||||||
// "-debug-pass=Arguments "
|
// "-debug-pass=Arguments "
|
||||||
|
"%s"
|
||||||
"",
|
"",
|
||||||
LIT(output_base),
|
LIT(output_base),
|
||||||
build_context.optimization_level,
|
build_context.optimization_level,
|
||||||
LIT(build_context.llc_flags));
|
LIT(build_context.llc_flags),
|
||||||
|
str_eq_ignore_case(cross_compile_target, str_lit("Essence")) ? "-mtriple=x86_64-pc-none-elf" : "");
|
||||||
if (exit_code != 0) {
|
if (exit_code != 0) {
|
||||||
return exit_code;
|
return exit_code;
|
||||||
}
|
}
|
||||||
@@ -916,14 +950,19 @@ int main(int arg_count, char **arg_ptr) {
|
|||||||
// It probably has to do with including the entire CRT, but
|
// It probably has to do with including the entire CRT, but
|
||||||
// that's quite a complicated issue to solve while remaining distro-agnostic.
|
// that's quite a complicated issue to solve while remaining distro-agnostic.
|
||||||
// Clang can figure out linker flags for us, and that's good enough _for now_.
|
// Clang can figure out linker flags for us, and that's good enough _for now_.
|
||||||
linker = "clang -Wno-unused-command-line-argument";
|
if (str_eq_ignore_case(cross_compile_target, str_lit("Essence"))) {
|
||||||
|
linker = "x86_64-elf-gcc -T core/sys/essence_linker_userland64.ld -ffreestanding -nostdlib -lgcc -g -z max-page-size=0x1000 -Wno-unused-command-line-argument";
|
||||||
|
} else {
|
||||||
|
linker = "clang -Wno-unused-command-line-argument";
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
exit_code = system_exec_command_line_app("ld-link", true,
|
exit_code = system_exec_command_line_app("ld-link", true,
|
||||||
"%s \"%.*s.o\" -o \"%.*s%s\" %s "
|
"%s \"%.*s.o\" -o \"%.*s%s\" %s "
|
||||||
"-lc -lm "
|
" %s "
|
||||||
" %.*s "
|
" %.*s "
|
||||||
" %s "
|
" %s "
|
||||||
|
" %.*s "
|
||||||
#if defined(GB_SYSTEM_OSX)
|
#if defined(GB_SYSTEM_OSX)
|
||||||
// This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit.
|
// This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit.
|
||||||
// NOTE: If you change this (although this minimum is as low as you can go with Odin working)
|
// NOTE: If you change this (although this minimum is as low as you can go with Odin working)
|
||||||
@@ -933,8 +972,11 @@ int main(int arg_count, char **arg_ptr) {
|
|||||||
" -e _main "
|
" -e _main "
|
||||||
#endif
|
#endif
|
||||||
, linker, LIT(output_base), LIT(output_base), output_ext,
|
, linker, LIT(output_base), LIT(output_base), output_ext,
|
||||||
lib_str, LIT(build_context.link_flags),
|
lib_str,
|
||||||
link_settings
|
str_eq_ignore_case(cross_compile_target, str_lit("Essence")) ? "" : "-lc -lm",
|
||||||
|
LIT(build_context.link_flags),
|
||||||
|
link_settings,
|
||||||
|
LIT(cross_compile_lib_dir)
|
||||||
);
|
);
|
||||||
if (exit_code != 0) {
|
if (exit_code != 0) {
|
||||||
return exit_code;
|
return exit_code;
|
||||||
|
|||||||
Reference in New Issue
Block a user