mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 14:48:47 +00:00
-no-crt flag for windows amd64
This commit is contained in:
@@ -85,6 +85,7 @@ struct BuildContext {
|
|||||||
bool keep_temp_files;
|
bool keep_temp_files;
|
||||||
bool no_bounds_check;
|
bool no_bounds_check;
|
||||||
bool no_output_files;
|
bool no_output_files;
|
||||||
|
bool no_crt;
|
||||||
|
|
||||||
gbAffinity affinity;
|
gbAffinity affinity;
|
||||||
isize thread_count;
|
isize thread_count;
|
||||||
@@ -528,7 +529,7 @@ void init_build_context(void) {
|
|||||||
|
|
||||||
gbString llc_flags = gb_string_make_reserve(heap_allocator(), 64);
|
gbString llc_flags = gb_string_make_reserve(heap_allocator(), 64);
|
||||||
if (bc->ODIN_DEBUG) {
|
if (bc->ODIN_DEBUG) {
|
||||||
llc_flags = gb_string_appendc(llc_flags, "-debug-compile ");
|
// llc_flags = gb_string_appendc(llc_flags, "-debug-compile ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(zangent): The linker flags to set the build architecture are different
|
// NOTE(zangent): The linker flags to set the build architecture are different
|
||||||
|
|||||||
@@ -1314,6 +1314,19 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
add_dependency_to_set(c, scope_lookup(c->info.runtime_package->scope, required_runtime_entities[i]));
|
add_dependency_to_set(c, scope_lookup(c->info.runtime_package->scope, required_runtime_entities[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (build_context.no_crt) {
|
||||||
|
String required_no_crt_entities[] = {
|
||||||
|
// NOTE(bill): Only if these exist
|
||||||
|
str_lit("memcpy"),
|
||||||
|
str_lit("memmove"),
|
||||||
|
str_lit("memset"),
|
||||||
|
// str_lit("memcmp"),
|
||||||
|
};
|
||||||
|
for (isize i = 0; i < gb_count_of(required_no_crt_entities); i++) {
|
||||||
|
add_dependency_to_set(c, scope_lookup(c->info.runtime_package->scope, required_no_crt_entities[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AstPackage *mem = get_core_package(&c->info, str_lit("mem"));
|
AstPackage *mem = get_core_package(&c->info, str_lit("mem"));
|
||||||
String required_mem_entities[] = {
|
String required_mem_entities[] = {
|
||||||
str_lit("zero"),
|
str_lit("zero"),
|
||||||
|
|||||||
+80
-34
@@ -622,6 +622,7 @@ struct irGen {
|
|||||||
bool opt_called;
|
bool opt_called;
|
||||||
String output_base;
|
String output_base;
|
||||||
String output_name;
|
String output_name;
|
||||||
|
bool print_chkstk;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1353,6 +1354,7 @@ void ir_add_foreign_library_path(irModule *m, Entity *e) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ok = true;
|
||||||
for_array(path_index, m->foreign_library_paths) {
|
for_array(path_index, m->foreign_library_paths) {
|
||||||
String path = m->foreign_library_paths[path_index];
|
String path = m->foreign_library_paths[path_index];
|
||||||
#if defined(GB_SYSTEM_WINDOWS)
|
#if defined(GB_SYSTEM_WINDOWS)
|
||||||
@@ -1360,10 +1362,14 @@ void ir_add_foreign_library_path(irModule *m, Entity *e) {
|
|||||||
#else
|
#else
|
||||||
if (str_eq(path, library_path)) {
|
if (str_eq(path, library_path)) {
|
||||||
#endif
|
#endif
|
||||||
continue;
|
ok = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
array_add(&m->foreign_library_paths, library_path);
|
|
||||||
|
if (ok) {
|
||||||
|
array_add(&m->foreign_library_paths, library_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8416,51 +8422,91 @@ void ir_gen_tree(irGen *s) {
|
|||||||
ir_emit_return(proc, v_zero32);
|
ir_emit_return(proc, v_zero32);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 && defined(GB_SYSTEM_WINDOWS)
|
#if defined(GB_SYSTEM_WINDOWS)
|
||||||
if (!m->build_context->is_dll && !has_win_main) {
|
// if (!m->build_context->is_dll && !has_win_main) {
|
||||||
// proc WinMain(inst, prev: rawptr, cmd_line: ^byte, cmd_show: i32) -> i32
|
// // proc WinMain(inst, prev: rawptr, cmd_line: ^byte, cmd_show: i32) -> i32
|
||||||
String name = str_lit("WinMain");
|
// String name = str_lit("WinMain");
|
||||||
Type *proc_params = alloc_type_tuple();
|
// Type *proc_params = alloc_type_tuple();
|
||||||
Type *proc_results = alloc_type_tuple();
|
// Type *proc_results = alloc_type_tuple();
|
||||||
|
|
||||||
Scope *proc_scope = gb_alloc_item(a, Scope);
|
// Scope *proc_scope = gb_alloc_item(a, Scope);
|
||||||
|
|
||||||
proc_params->Tuple.variables = gb_alloc_array(a, Entity *, 4);
|
// proc_params->Tuple.variables = gb_alloc_array(a, Entity *, 4);
|
||||||
proc_params->Tuple.variable_count = 4;
|
// proc_params->Tuple.variable_count = 4;
|
||||||
|
|
||||||
proc_results->Tuple.variables = gb_alloc_array(a, Entity *, 1);
|
// proc_results->Tuple.variables = gb_alloc_array(a, Entity *, 1);
|
||||||
proc_results->Tuple.variable_count = 1;
|
// proc_results->Tuple.variable_count = 1;
|
||||||
|
|
||||||
proc_params->Tuple.variables[0] = alloc_entity_param(proc_scope, blank_token, t_rawptr, false);
|
// proc_params->Tuple.variables[0] = alloc_entity_param(proc_scope, blank_token, t_rawptr, false);
|
||||||
proc_params->Tuple.variables[1] = alloc_entity_param(proc_scope, blank_token, t_rawptr, false);
|
// proc_params->Tuple.variables[1] = alloc_entity_param(proc_scope, blank_token, t_rawptr, false);
|
||||||
proc_params->Tuple.variables[2] = alloc_entity_param(proc_scope, blank_token, t_u8_ptr, false);
|
// proc_params->Tuple.variables[2] = alloc_entity_param(proc_scope, blank_token, t_u8_ptr, false);
|
||||||
proc_params->Tuple.variables[3] = alloc_entity_param(proc_scope, blank_token, t_i32, false);
|
// proc_params->Tuple.variables[3] = alloc_entity_param(proc_scope, blank_token, t_i32, false);
|
||||||
|
|
||||||
proc_results->Tuple.variables[0] = alloc_entity_param(proc_scope, empty_token, t_i32, false);
|
// proc_results->Tuple.variables[0] = alloc_entity_param(proc_scope, empty_token, t_i32, false);
|
||||||
|
|
||||||
|
|
||||||
Type *proc_type = alloc_type_proc(a, proc_scope,
|
// Type *proc_type = alloc_type_proc(a, proc_scope,
|
||||||
proc_params, 4,
|
// proc_params, 4,
|
||||||
proc_results, 1, false, ProcCC_Std);
|
// proc_results, 1, false, ProcCC_Std);
|
||||||
|
|
||||||
Ast *body = alloc_ast_node(nullptr, Ast_Invalid);
|
// Ast *body = alloc_ast_node(nullptr, Ast_Invalid);
|
||||||
Entity *e = alloc_entity_procedure(a, nullptr, make_token_ident(name), proc_type, 0);
|
// Entity *e = alloc_entity_procedure(a, nullptr, make_token_ident(name), proc_type, 0);
|
||||||
irValue *p = ir_value_procedure(m, e, proc_type, nullptr, body, name);
|
// irValue *p = ir_value_procedure(m, e, proc_type, nullptr, body, name);
|
||||||
|
|
||||||
m->entry_point_entity = e;
|
// m->entry_point_entity = e;
|
||||||
|
|
||||||
map_set(&m->values, hash_entity(e), p);
|
// map_set(&m->values, hash_entity(e), p);
|
||||||
map_set(&m->members, hash_string(name), p);
|
// map_set(&m->members, hash_string(name), p);
|
||||||
|
|
||||||
irProcedure *proc = &p->Proc;
|
// irProcedure *proc = &p->Proc;
|
||||||
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
|
// proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
|
||||||
e->Procedure.link_name = name;
|
// e->Procedure.link_name = name;
|
||||||
|
|
||||||
ir_begin_procedure_body(proc);
|
// ir_begin_procedure_body(proc);
|
||||||
ir_emit_runtime_call(proc, "main", nullptr, 0);
|
// ir_emit_runtime_call(proc, "main", nullptr, 0);
|
||||||
ir_emit_return(proc, v_one32);
|
// ir_emit_return(proc, v_one32);
|
||||||
ir_end_procedure_body(proc);
|
// ir_end_procedure_body(proc);
|
||||||
|
// }
|
||||||
|
if (!build_context.is_dll && build_context.no_crt) {
|
||||||
|
s->print_chkstk = true;
|
||||||
|
|
||||||
|
{
|
||||||
|
// void mainCRTStartup(void)
|
||||||
|
String name = str_lit("mainCRTStartup");
|
||||||
|
Type *proc_params = alloc_type_tuple();
|
||||||
|
Type *proc_results = alloc_type_tuple();
|
||||||
|
|
||||||
|
|
||||||
|
Type *proc_type = alloc_type_proc(nullptr,
|
||||||
|
nullptr, 0,
|
||||||
|
nullptr, 0,
|
||||||
|
false,
|
||||||
|
ProcCC_StdCall);
|
||||||
|
|
||||||
|
Ast *body = alloc_ast_node(nullptr, Ast_Invalid);
|
||||||
|
Entity *e = alloc_entity_procedure(nullptr, make_token_ident(name), proc_type, 0);
|
||||||
|
irValue *p = ir_value_procedure(m, e, proc_type, nullptr, body, name);
|
||||||
|
|
||||||
|
m->entry_point_entity = e;
|
||||||
|
|
||||||
|
map_set(&m->values, hash_entity(e), p);
|
||||||
|
map_set(&m->members, hash_string(name), p);
|
||||||
|
|
||||||
|
irProcedure *proc = &p->Proc;
|
||||||
|
// proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
|
||||||
|
e->Procedure.link_name = name;
|
||||||
|
|
||||||
|
ir_begin_procedure_body(proc);
|
||||||
|
ir_emit(proc, ir_alloc_instr(proc, irInstr_StartupRuntime));
|
||||||
|
irValue **found = map_get(&proc->module->values, hash_entity(entry_point));
|
||||||
|
if (found != nullptr) {
|
||||||
|
Array<irValue *> args = {};
|
||||||
|
ir_emit_call(proc, *found, args);
|
||||||
|
}
|
||||||
|
ir_end_procedure_body(proc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
{ // Startup Runtime
|
{ // Startup Runtime
|
||||||
// Cleanup(bill): probably better way of doing code insertion
|
// Cleanup(bill): probably better way of doing code insertion
|
||||||
|
|||||||
@@ -1737,6 +1737,15 @@ void print_llvm_ir(irGen *ir) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ir->print_chkstk) {
|
||||||
|
// TODO(bill): Clean up this code
|
||||||
|
ir_write_str_lit(f, "\n\n");
|
||||||
|
ir_write_str_lit(f, "define void @__chkstk() #0 {\n");
|
||||||
|
ir_write_str_lit(f, "\tcall void asm sideeffect \"push %rcx \\09\\0Apush %rax \\09\\0Acmp $$0x1000,%rax \\09\\0Alea 24(%rsp),%rcx \\09\\0Ajb 1f \\09\\0A2: \\09\\0Asub $$0x1000,%rcx \\09\\0Aorl $$0,(%rcx) \\09\\0Asub $$0x1000,%rax \\09\\0Acmp $$0x1000,%rax \\09\\0Aja 2b \\09\\0A1: \\09\\0Asub %rax,%rcx \\09\\0Aorl $$0,(%rcx) \\09\\0Apop %rax \\09\\0Apop %rcx \\09\\0Aret \\09\\0A\", \"~{dirflag},~{fpsr},~{flags}\"()\n");
|
||||||
|
ir_write_str_lit(f, "\tret void\n");
|
||||||
|
ir_write_str_lit(f, "}\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE(bill): Print procedures with bodies next
|
// NOTE(bill): Print procedures with bodies next
|
||||||
for_array(member_index, m->members.entries) {
|
for_array(member_index, m->members.entries) {
|
||||||
auto *entry = &m->members.entries[member_index];
|
auto *entry = &m->members.entries[member_index];
|
||||||
|
|||||||
+11
-4
@@ -22,7 +22,7 @@ i32 system_exec_command_line_app(char *name, bool is_silent, char *fmt, ...) {
|
|||||||
#if defined(GB_SYSTEM_WINDOWS)
|
#if defined(GB_SYSTEM_WINDOWS)
|
||||||
STARTUPINFOW start_info = {gb_size_of(STARTUPINFOW)};
|
STARTUPINFOW start_info = {gb_size_of(STARTUPINFOW)};
|
||||||
PROCESS_INFORMATION pi = {0};
|
PROCESS_INFORMATION pi = {0};
|
||||||
char cmd_line[4096] = {0};
|
char cmd_line[4*1024] = {0};
|
||||||
isize cmd_len;
|
isize cmd_len;
|
||||||
va_list va;
|
va_list va;
|
||||||
gbTempArenaMemory tmp;
|
gbTempArenaMemory tmp;
|
||||||
@@ -212,6 +212,7 @@ enum BuildFlagKind {
|
|||||||
BuildFlag_CrossCompile,
|
BuildFlag_CrossCompile,
|
||||||
BuildFlag_CrossLibDir,
|
BuildFlag_CrossLibDir,
|
||||||
BuildFlag_NoBoundsCheck,
|
BuildFlag_NoBoundsCheck,
|
||||||
|
BuildFlag_NoCRT,
|
||||||
|
|
||||||
BuildFlag_COUNT,
|
BuildFlag_COUNT,
|
||||||
};
|
};
|
||||||
@@ -252,6 +253,7 @@ bool parse_build_flags(Array<String> args) {
|
|||||||
add_flag(&build_flags, BuildFlag_CrossCompile, str_lit("cross-compile"), BuildFlagParam_String);
|
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);
|
add_flag(&build_flags, BuildFlag_CrossLibDir, str_lit("cross-lib-dir"), BuildFlagParam_String);
|
||||||
add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None);
|
add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None);
|
||||||
|
add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None);
|
||||||
|
|
||||||
GB_ASSERT(args.count >= 3);
|
GB_ASSERT(args.count >= 3);
|
||||||
Array<String> flag_args = array_slice(args, 3, args.count);
|
Array<String> flag_args = array_slice(args, 3, args.count);
|
||||||
@@ -551,6 +553,10 @@ bool parse_build_flags(Array<String> args) {
|
|||||||
case BuildFlag_NoBoundsCheck:
|
case BuildFlag_NoBoundsCheck:
|
||||||
build_context.no_bounds_check = true;
|
build_context.no_bounds_check = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BuildFlag_NoCRT:
|
||||||
|
build_context.no_crt = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -840,7 +846,6 @@ int main(int arg_count, char **arg_ptr) {
|
|||||||
// defer (ir_gen_destroy(&ir_gen));
|
// defer (ir_gen_destroy(&ir_gen));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
timings_start_section(&timings, str_lit("llvm ir gen"));
|
timings_start_section(&timings, str_lit("llvm ir gen"));
|
||||||
ir_gen_tree(&ir_gen);
|
ir_gen_tree(&ir_gen);
|
||||||
|
|
||||||
@@ -879,6 +884,7 @@ int main(int arg_count, char **arg_ptr) {
|
|||||||
|
|
||||||
for_array(i, ir_gen.module.foreign_library_paths) {
|
for_array(i, ir_gen.module.foreign_library_paths) {
|
||||||
String lib = ir_gen.module.foreign_library_paths[i];
|
String lib = ir_gen.module.foreign_library_paths[i];
|
||||||
|
GB_ASSERT(lib.len < gb_count_of(lib_str_buf)-1);
|
||||||
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
|
||||||
" \"%.*s\"", LIT(lib));
|
" \"%.*s\"", LIT(lib));
|
||||||
lib_str = gb_string_appendc(lib_str, lib_str_buf);
|
lib_str = gb_string_appendc(lib_str, lib_str_buf);
|
||||||
@@ -893,6 +899,9 @@ int main(int arg_count, char **arg_ptr) {
|
|||||||
link_settings = gb_string_append_fmt(link_settings, "/DLL");
|
link_settings = gb_string_append_fmt(link_settings, "/DLL");
|
||||||
} else {
|
} else {
|
||||||
link_settings = gb_string_append_fmt(link_settings, "/ENTRY:mainCRTStartup");
|
link_settings = gb_string_append_fmt(link_settings, "/ENTRY:mainCRTStartup");
|
||||||
|
if (build_context.no_crt) {
|
||||||
|
link_settings = gb_string_append_fmt(link_settings, " /nodefaultlib");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ir_gen.module.generate_debug_info) {
|
if (ir_gen.module.generate_debug_info) {
|
||||||
@@ -913,7 +922,6 @@ int main(int arg_count, char **arg_ptr) {
|
|||||||
exit_code = system_exec_command_line_app("msvc-link", true,
|
exit_code = system_exec_command_line_app("msvc-link", true,
|
||||||
"link \"%.*s.obj\" \"%.*s.res\" -OUT:\"%.*s.%s\" %s "
|
"link \"%.*s.obj\" \"%.*s.res\" -OUT:\"%.*s.%s\" %s "
|
||||||
"/defaultlib:libcmt "
|
"/defaultlib:libcmt "
|
||||||
// "/nodefaultlib "
|
|
||||||
"/nologo /incremental:no /opt:ref /subsystem:CONSOLE "
|
"/nologo /incremental:no /opt:ref /subsystem:CONSOLE "
|
||||||
" %.*s "
|
" %.*s "
|
||||||
" %s "
|
" %s "
|
||||||
@@ -926,7 +934,6 @@ int main(int arg_count, char **arg_ptr) {
|
|||||||
exit_code = system_exec_command_line_app("msvc-link", true,
|
exit_code = system_exec_command_line_app("msvc-link", true,
|
||||||
"link \"%.*s.obj\" -OUT:\"%.*s.%s\" %s "
|
"link \"%.*s.obj\" -OUT:\"%.*s.%s\" %s "
|
||||||
"/defaultlib:libcmt "
|
"/defaultlib:libcmt "
|
||||||
// "/nodefaultlib "
|
|
||||||
"/nologo /incremental:no /opt:ref /subsystem:CONSOLE "
|
"/nologo /incremental:no /opt:ref /subsystem:CONSOLE "
|
||||||
" %.*s "
|
" %.*s "
|
||||||
" %s "
|
" %s "
|
||||||
|
|||||||
+7
-7
@@ -142,16 +142,15 @@ String const token_strings[] = {
|
|||||||
|
|
||||||
struct TokenPos {
|
struct TokenPos {
|
||||||
String file;
|
String file;
|
||||||
isize line;
|
isize offset; // starting at 0
|
||||||
isize column;
|
isize line; // starting at 1
|
||||||
|
isize column; // starting at 1
|
||||||
};
|
};
|
||||||
|
|
||||||
TokenPos token_pos(String file, isize line, isize column) {
|
|
||||||
TokenPos pos = {file, line, column};
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
i32 token_pos_cmp(TokenPos const &a, TokenPos const &b) {
|
i32 token_pos_cmp(TokenPos const &a, TokenPos const &b) {
|
||||||
|
if (a.offset != b.offset) {
|
||||||
|
return (a.offset < b.offset) ? -1 : +1;
|
||||||
|
}
|
||||||
if (a.line != b.line) {
|
if (a.line != b.line) {
|
||||||
return (a.line < b.line) ? -1 : +1;
|
return (a.line < b.line) ? -1 : +1;
|
||||||
}
|
}
|
||||||
@@ -825,6 +824,7 @@ Token tokenizer_get_token(Tokenizer *t) {
|
|||||||
token.string = make_string(t->curr, 1);
|
token.string = make_string(t->curr, 1);
|
||||||
token.pos.file = t->fullpath;
|
token.pos.file = t->fullpath;
|
||||||
token.pos.line = t->line_count;
|
token.pos.line = t->line_count;
|
||||||
|
token.pos.offset = t->curr - t->start;
|
||||||
token.pos.column = t->curr - t->line + 1;
|
token.pos.column = t->curr - t->line + 1;
|
||||||
|
|
||||||
Rune curr_rune = t->curr_rune;
|
Rune curr_rune = t->curr_rune;
|
||||||
|
|||||||
Reference in New Issue
Block a user