mirror of
https://github.com/odin-lang/Odin.git
synced 2026-07-22 23:42:33 +00:00
Merge branch 'master' into bill/bedrock
This commit is contained in:
140
src/main.cpp
140
src/main.cpp
@@ -178,11 +178,44 @@ gb_internal i32 system_exec_command_line_app(char const *name, char const *fmt,
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
gb_internal void system_must_exec_command_line_app(char const *name, char const *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
system_exec_command_line_app_internal(/* exit_on_err= */ true, name, fmt, va);
|
||||
va_end(va);
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
#include <process.h>
|
||||
#else
|
||||
#include <spawn.h>
|
||||
extern char **environ;
|
||||
#endif
|
||||
|
||||
int run_subprocess(const char *name, const char **args) {
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
return (int)_spawnv(_P_WAIT, name, args);
|
||||
#else
|
||||
pid_t pid;
|
||||
int status;
|
||||
status = posix_spawn(&pid, name, NULL, NULL, (char *const *)args, environ);
|
||||
if (status != 0) {
|
||||
gb_printf_err("Could not spawn subprocess: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (waitpid(pid, &status, WUNTRACED) < 0) {
|
||||
gb_printf_err("Could not wait on subprocess: (pid: %d): %s\n", pid, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
return WEXITSTATUS(status);
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
struct rlimit limit = { 0, 0, };
|
||||
setrlimit(RLIMIT_CORE, &limit);
|
||||
raise(WTERMSIG(status));
|
||||
return -1;
|
||||
} else if (WIFSTOPPED(status)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
GB_PANIC("Subprocess failure");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
@@ -312,6 +345,7 @@ enum BuildFlagKind {
|
||||
BuildFlag_Debug,
|
||||
BuildFlag_DisableAssert,
|
||||
BuildFlag_NoBoundsCheck,
|
||||
BuildFlag_WebkitSwitchWorkaround,
|
||||
BuildFlag_NoTypeAssert,
|
||||
BuildFlag_NoDynamicLiterals,
|
||||
BuildFlag_DynamicLiterals,
|
||||
@@ -354,6 +388,7 @@ enum BuildFlagKind {
|
||||
BuildFlag_NoThreadLocal,
|
||||
|
||||
BuildFlag_RelocMode,
|
||||
BuildFlag_StackProtector,
|
||||
BuildFlag_DisableRedZone,
|
||||
|
||||
BuildFlag_DisableUnwind,
|
||||
@@ -549,6 +584,7 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_DisableAssert, str_lit("disable-assert"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_WebkitSwitchWorkaround, str_lit("webkit-switch-workaround"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_NoTypeAssert, str_lit("no-type-assert"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_NoThreadLocal, str_lit("no-thread-local"), BuildFlagParam_None, Command__does_check);
|
||||
add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None, Command__does_check);
|
||||
@@ -591,6 +627,7 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
add_flag(&build_flags, BuildFlag_MinimumOSVersion, str_lit("minimum-os-version"), BuildFlagParam_String, Command__does_build | Command_bundle_android);
|
||||
|
||||
add_flag(&build_flags, BuildFlag_RelocMode, str_lit("reloc-mode"), BuildFlagParam_String, Command__does_build);
|
||||
add_flag(&build_flags, BuildFlag_StackProtector, str_lit("stack-protector"), BuildFlagParam_String, Command__does_build);
|
||||
add_flag(&build_flags, BuildFlag_DisableRedZone, str_lit("disable-red-zone"), BuildFlagParam_None, Command__does_build);
|
||||
|
||||
add_flag(&build_flags, BuildFlag_DisableUnwind, str_lit("disable-unwind"), BuildFlagParam_None, Command__does_build);
|
||||
@@ -1243,6 +1280,9 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
case BuildFlag_NoBoundsCheck:
|
||||
build_context.no_bounds_check = true;
|
||||
break;
|
||||
case BuildFlag_WebkitSwitchWorkaround:
|
||||
build_context.webkit_switch_workaround = true;
|
||||
break;
|
||||
case BuildFlag_NoTypeAssert:
|
||||
build_context.no_type_assert = true;
|
||||
break;
|
||||
@@ -1439,6 +1479,26 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
|
||||
break;
|
||||
}
|
||||
case BuildFlag_StackProtector: {
|
||||
GB_ASSERT(value.kind == ExactValue_String);
|
||||
String v = value.value_string;
|
||||
if (v == "none") {
|
||||
build_context.stack_protector = StackProtector_None;
|
||||
} else if (v == "base") {
|
||||
build_context.stack_protector = StackProtector_Ssp;
|
||||
} else if (v == "all") {
|
||||
build_context.stack_protector = StackProtector_SspReq;
|
||||
} else if (v == "strong") {
|
||||
build_context.stack_protector = StackProtector_SspStrong;
|
||||
} else {
|
||||
gb_printf_err("-stack-protector flag expected one of the following\n");
|
||||
gb_printf_err("\tnone\n");
|
||||
gb_printf_err("\tbase\n");
|
||||
gb_printf_err("\tall\n");
|
||||
gb_printf_err("\tstrong\n");
|
||||
bad_flags = true;
|
||||
}
|
||||
}
|
||||
case BuildFlag_DisableRedZone:
|
||||
build_context.disable_red_zone = true;
|
||||
break;
|
||||
@@ -2913,6 +2973,11 @@ gb_internal int print_show_help(String const arg0, String command, String option
|
||||
print_usage_line(2, "Disables bounds checking program wide.");
|
||||
}
|
||||
|
||||
if (print_flag("-webkit-switch-workaround")) {
|
||||
print_usage_line(2, "Constrains 'typeid' values to 63 bits to avoid an OMG JIT crash in WebKit when running WASM builds.");
|
||||
print_usage_line(2, "Only needed for 'js_wasm32'/'js_wasm64p32' targets run in Safari/WebKit. See: https://github.com/odin-lang/Odin/issues/6810");
|
||||
}
|
||||
|
||||
if (print_flag("-no-crt")) {
|
||||
print_usage_line(2, "Disables automatic linking with the C Run Time.");
|
||||
}
|
||||
@@ -3008,6 +3073,16 @@ gb_internal int print_show_help(String const arg0, String command, String option
|
||||
print_usage_line(3, "-reloc-mode:dynamic-no-pic");
|
||||
}
|
||||
|
||||
if (print_flag("-stack-protector:<string>")) {
|
||||
print_usage_line(2, "Specifies the stack protector.");
|
||||
print_usage_line(2, "Available options:");
|
||||
print_usage_line(3, "-stack-protector:default");
|
||||
print_usage_line(3, "-stack-protector:none");
|
||||
print_usage_line(3, "-stack-protector:base");
|
||||
print_usage_line(3, "-stack-protector:all");
|
||||
print_usage_line(3, "-stack-protector:strong");
|
||||
}
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
if (print_flag("-resource:<filepath>")) {
|
||||
print_usage_line(2, "[Windows only]");
|
||||
@@ -3655,24 +3730,52 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
TIME_SECTION("init args");
|
||||
map_init(&build_context.defined_values);
|
||||
build_context.extra_packages.allocator = heap_allocator();
|
||||
|
||||
init_build_context_error_pos_style();
|
||||
|
||||
Array<String> args = setup_args(arg_count, arg_ptr);
|
||||
Array<String> run_args = array_make<String>(heap_allocator(), 0, arg_count);
|
||||
defer (array_free(&run_args));
|
||||
|
||||
String command = args[1];
|
||||
String init_filename = {};
|
||||
String run_args_string = {};
|
||||
isize last_non_run_arg = args.count;
|
||||
|
||||
isize double_dash_pos = -1;
|
||||
for_array(i, args) {
|
||||
if (args[i] == "--") {
|
||||
double_dash_pos = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (args[i] == "-help" || args[i] == "--help") {
|
||||
build_context.show_help = true;
|
||||
return print_show_help(args[0], command);
|
||||
}
|
||||
}
|
||||
|
||||
if (args.count > 2) {
|
||||
// NOTE(bill): Allow for both `odin command path -flags` and `odin command -flags path`
|
||||
// To do this, if the first argument after the command and last argument is NOT a flag,
|
||||
// then put that last parameter first
|
||||
isize end_arg = double_dash_pos >= 0 ? double_dash_pos : args.count-1;
|
||||
if (args[1] == "bundle" && args.count > 4) {
|
||||
if (string_starts_with(args[3], str_lit("-")) &&
|
||||
!string_starts_with(args[end_arg], str_lit("-"))) {
|
||||
String possible_path = args[end_arg];
|
||||
array_ordered_remove(&args, end_arg);
|
||||
array_inject_at(&args, 3, possible_path);
|
||||
}
|
||||
} else if (args.count > 3) {
|
||||
if (string_starts_with(args[2], str_lit("-")) &&
|
||||
!string_starts_with(args[end_arg], str_lit("-"))) {
|
||||
String possible_path = args[end_arg];
|
||||
array_ordered_remove(&args, end_arg);
|
||||
array_inject_at(&args, 2, possible_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool run_output = false;
|
||||
if (command == "run" || command == "test") {
|
||||
if (args.count < 3) {
|
||||
@@ -3684,9 +3787,6 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
build_context.command_kind = Command_test;
|
||||
}
|
||||
|
||||
Array<String> run_args = array_make<String>(heap_allocator(), 0, arg_count);
|
||||
defer (array_free(&run_args));
|
||||
|
||||
isize run_args_start_idx = -1;
|
||||
for_array(i, args) {
|
||||
if (args[i] == "--") {
|
||||
@@ -3708,7 +3808,6 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
}
|
||||
}
|
||||
args = array_slice(args, 0, last_non_run_arg);
|
||||
run_args_string = string_join_and_quote(heap_allocator(), run_args);
|
||||
|
||||
init_filename = args[2];
|
||||
run_output = true;
|
||||
@@ -3816,6 +3915,10 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
usage(args[0]);
|
||||
return 1;
|
||||
}
|
||||
// NOTE(Jeroen): `odin root` omits a newline on purpose so that it can be used in scripts.
|
||||
// e.g. `ODIN_CORE="$(odin root)core"`.
|
||||
// Human convenience is not a consideration.
|
||||
// Further pull requests to add a newline will be closed without comment.
|
||||
gb_printf("%.*s", LIT(odin_root_dir()));
|
||||
return 0;
|
||||
} else if (command == "clear-cache") {
|
||||
@@ -4301,8 +4404,23 @@ end_of_code_gen:;
|
||||
String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]);
|
||||
defer (gb_free(heap_allocator(), exe_name.text));
|
||||
|
||||
system_must_exec_command_line_app("odin run", "\"%.*s\" %.*s", LIT(exe_name), LIT(run_args_string));
|
||||
const char* exe_name_cstring = alloc_cstring(heap_allocator(), exe_name);
|
||||
Array<const char *> run_args_cstring = array_make<const char *>(heap_allocator(), 0, run_args.count);
|
||||
defer({
|
||||
for_array(i, run_args_cstring) { gb_free(heap_allocator(), (void*)run_args_cstring[i]); }
|
||||
array_free(&run_args_cstring);
|
||||
});
|
||||
|
||||
array_add(&run_args_cstring, exe_name_cstring);
|
||||
for_array(i, run_args) {
|
||||
array_add(&run_args_cstring, alloc_cstring(heap_allocator(), run_args[i]));
|
||||
}
|
||||
array_add(&run_args_cstring, NULL);
|
||||
|
||||
int subprocess_res = run_subprocess(exe_name_cstring, run_args_cstring.data);
|
||||
if (subprocess_res) {
|
||||
gb_exit(subprocess_res);
|
||||
}
|
||||
if (!build_context.keep_executable) {
|
||||
char const *filename = cast(char const *)exe_name.text;
|
||||
gb_file_remove(filename);
|
||||
|
||||
Reference in New Issue
Block a user