mirror of
https://github.com/odin-lang/Odin.git
synced 2026-09-02 02:03:35 +00:00
Merge pull request #7485 from Yawning/fix/linker-system
src: Use `posix_spawnp` instead of `system()` when invoking the linker
This commit is contained in:
@@ -739,6 +739,75 @@ gb_internal wchar_t **command_line_to_wargv(wchar_t *cmd_line, int *_argc, isize
|
||||
return argv;
|
||||
}
|
||||
|
||||
#elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX)
|
||||
|
||||
gb_internal char **command_line_to_spawn_argv(const char *cmd_line, int *_argc) {
|
||||
u32 i, j;
|
||||
|
||||
u32 len = cast(u32)strlen(cmd_line);
|
||||
i = len*gb_size_of(void *) + gb_size_of(void *);
|
||||
|
||||
char **argv = cast(char **)gb_alloc(gb_heap_allocator(), i + (len+1));
|
||||
char *_argv = (cast(char *)argv)+i;
|
||||
|
||||
u32 argc = 0;
|
||||
argv[argc] = _argv;
|
||||
bool in_quote = false;
|
||||
bool in_text = false;
|
||||
bool in_space = true;
|
||||
i = 0;
|
||||
j = 0;
|
||||
|
||||
for (;;) {
|
||||
char a = cmd_line[i];
|
||||
if (a == 0) {
|
||||
break;
|
||||
}
|
||||
if (in_quote) {
|
||||
if (a == '\"') {
|
||||
in_quote = false;
|
||||
} else {
|
||||
_argv[j++] = a;
|
||||
}
|
||||
} else {
|
||||
switch (a) {
|
||||
case '\"':
|
||||
in_quote = true;
|
||||
in_text = true;
|
||||
if (in_space) {
|
||||
// check_double_dash();
|
||||
argv[argc++] = _argv + j;
|
||||
}
|
||||
in_space = false;
|
||||
break;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\r':
|
||||
if (in_text) _argv[j++] = '\0';
|
||||
in_text = false;
|
||||
in_space = true;
|
||||
break;
|
||||
default:
|
||||
in_text = true;
|
||||
if (in_space) {
|
||||
// check_double_dash();
|
||||
argv[argc++] = _argv + j;
|
||||
}
|
||||
_argv[j++] = a;
|
||||
in_space = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
_argv[j] = '\0';
|
||||
argv[argc] = nullptr;
|
||||
|
||||
if (_argc) *_argc = argc;
|
||||
return argv;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#include "path.cpp"
|
||||
|
||||
@@ -810,6 +810,7 @@ try_cross_linking:;
|
||||
}
|
||||
} else if (build_context.build_mode != BuildMode_DynamicLibrary) {
|
||||
if (build_context.metrics.os != TargetOs_openbsd
|
||||
&& build_context.metrics.os != TargetOs_darwin
|
||||
&& build_context.metrics.arch != TargetArch_riscv64
|
||||
&& !is_android
|
||||
) {
|
||||
@@ -961,7 +962,7 @@ try_cross_linking:;
|
||||
if (is_android) {
|
||||
// ignore
|
||||
} else {
|
||||
link_settings = gb_string_appendc(link_settings, "-Wl,-rpath,\\$ORIGIN ");
|
||||
link_settings = gb_string_appendc(link_settings, "-Wl,-rpath,$ORIGIN ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
23
src/main.cpp
23
src/main.cpp
@@ -83,6 +83,10 @@ gb_global Timings global_timings = {0};
|
||||
|
||||
#include "bug_report.cpp"
|
||||
|
||||
#if defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX)
|
||||
int run_subprocess(const char *name, const char **args, bool honor_path = false);
|
||||
#endif
|
||||
|
||||
// NOTE(bill): 'name' is used in debugging and profiling modes
|
||||
gb_internal i32 system_exec_command_line_app_internal(bool exit_on_err, char const *name, char const *fmt, va_list va) {
|
||||
isize const cmd_cap = 64<<20; // 64 MiB should be more than enough
|
||||
@@ -154,7 +158,11 @@ gb_internal i32 system_exec_command_line_app_internal(bool exit_on_err, char con
|
||||
gb_printf_err("[SYSTEM CALL] %s\n", name);
|
||||
gb_printf_err("%s\n\n", cmd_line);
|
||||
}
|
||||
exit_code = system(cmd_line);
|
||||
|
||||
int argc;
|
||||
char **argv = command_line_to_spawn_argv(cmd_line, &argc);
|
||||
|
||||
exit_code = run_subprocess(argv[0], cast(const char**)(argv), true);
|
||||
if (exit_on_err && WIFSIGNALED(exit_code)) {
|
||||
struct rlimit limit = { 0, 0, };
|
||||
setrlimit(RLIMIT_CORE, &limit);
|
||||
@@ -236,10 +244,19 @@ int run_subprocess(String const &exe_name, wchar_t *after_double_dash_raw) {
|
||||
return exit_code;
|
||||
}
|
||||
#else
|
||||
int run_subprocess(const char *name, const char **args) {
|
||||
int run_subprocess(const char *name, const char **args, bool honor_path) {
|
||||
pid_t pid;
|
||||
int status;
|
||||
status = posix_spawn(&pid, name, NULL, NULL, (char *const *)args, environ);
|
||||
|
||||
String exec_name = make_string_c(args[0]);
|
||||
exec_name = last_path_element(exec_name);
|
||||
args[0] = alloc_cstring(gb_heap_allocator(), exec_name);
|
||||
|
||||
if (!honor_path) {
|
||||
status = posix_spawn(&pid, name, NULL, NULL, (char *const *)args, environ);
|
||||
} else {
|
||||
status = posix_spawnp(&pid, name, NULL, NULL, (char *const *)args, environ);
|
||||
}
|
||||
if (status != 0) {
|
||||
gb_printf_err("Could not spawn subprocess: %s\n", strerror(errno));
|
||||
return -1;
|
||||
|
||||
Reference in New Issue
Block a user