mirror of
https://github.com/odin-lang/Odin.git
synced 2026-10-09 22:32:13 -04:00
Merge remote-tracking branch 'upstream/master' into windows-cross-compile
This commit is contained in:
commit
ba04d81d40
187 files changed
+33377
-16504
No files matched your search
+164
-7
@@ -13,6 +13,85 @@ struct LinkerData {
|
||||
gb_internal i32 system_exec_command_line_app(char const *name, char const *fmt, ...);
|
||||
gb_internal bool system_exec_command_line_app_output(char const *command, gbString *output);
|
||||
|
||||
gb_internal i32 system_exec_msvc_linker_app(char const *name, char const *fmt, ...) {
|
||||
isize const cmd_cap = 64<<20;
|
||||
char *cmd = gb_alloc_array(heap_allocator(), char, cmd_cap);
|
||||
defer (gb_free(heap_allocator(), cmd));
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
isize cmd_len = gb_snprintf_va(cmd, cmd_cap-1, fmt, va) - 1;
|
||||
va_end(va);
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
// NOTE(bill, 2026-10-03): CreateProcessW limits the command line to 32767 UTF-16 code units so we need to pass the arguments into a response file
|
||||
if (cmd_len >= 32767 && !build_context.print_linker_flags) {
|
||||
char const *exe_end = cmd[0] == '"' ? gb_char_first_occurence(cmd+1, '"') : nullptr;
|
||||
GB_ASSERT(exe_end != nullptr);
|
||||
isize exe_len = exe_end+1 - cmd;
|
||||
|
||||
gbString rsp = gb_string_make_reserve(heap_allocator(), cmd_len);
|
||||
defer (gb_string_free(rsp));
|
||||
|
||||
// NOTE(bill): link.exe rejects response file lines of 128 KiB or more
|
||||
bool in_quotes = false;
|
||||
bool separate = false;
|
||||
isize backslashes = 0;
|
||||
for (char const *c = cmd+exe_len; *c; c++) {
|
||||
if (!in_quotes && (*c == ' ' || *c == '\t')) {
|
||||
separate = gb_string_length(rsp) > 0;
|
||||
continue;
|
||||
}
|
||||
if (separate) {
|
||||
rsp = gb_string_appendc(rsp, "\n");
|
||||
separate = false;
|
||||
}
|
||||
if (*c == '"' && (backslashes & 1) == 0) {
|
||||
in_quotes = !in_quotes;
|
||||
}
|
||||
backslashes = *c == '\\' ? backslashes+1 : 0;
|
||||
rsp = gb_string_append_length(rsp, c, 1);
|
||||
}
|
||||
|
||||
String dir = temporary_directory(temporary_allocator());
|
||||
if (dir.len == 0) {
|
||||
dir = build_context.build_paths[BuildPath_Output].basename;
|
||||
}
|
||||
|
||||
gbString rsp_path = gb_string_make(heap_allocator(), "");
|
||||
defer (gb_string_free(rsp_path));
|
||||
|
||||
rsp_path = gb_string_append_fmt(rsp_path, "%.*s/%.*s-%u.rsp", LIT(dir), LIT(build_context.build_paths[BuildPath_Output].name), GetCurrentProcessId());
|
||||
|
||||
{
|
||||
gbFile f = {};
|
||||
if (gb_file_create(&f, rsp_path) != gbFileError_None) {
|
||||
gb_printf_err("Failed to create linker response file: %s\n", rsp_path);
|
||||
return -1;
|
||||
}
|
||||
if (build_context.linker_choice != Linker_Default && build_context.linker_choice != Linker_radlink) {
|
||||
// NOTE(bill): link.exe reads a response file without a BOM in the ANSI code page but radlink does not skip a BOM
|
||||
gb_file_write(&f, "\xef\xbb\xbf", 3);
|
||||
}
|
||||
gb_file_write(&f, rsp, gb_string_length(rsp));
|
||||
gb_file_close(&f);
|
||||
}
|
||||
|
||||
if (build_context.show_system_calls) {
|
||||
gb_printf_err("[RESPONSE FILE] %s\n%s\n\n", rsp_path, rsp);
|
||||
}
|
||||
|
||||
i32 result = system_exec_command_line_app(name, "%.*s @\"%s\"", cast(int)exe_len, cmd, rsp_path);
|
||||
if (!build_context.keep_temp_files) {
|
||||
gb_file_remove(rsp_path);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
return system_exec_command_line_app(name, "%.*s", cast(int)cmd_len, cmd);
|
||||
}
|
||||
|
||||
// No longer required not that LLVM 14 is removed(?)
|
||||
gb_internal void linker_enable_system_library_linking(LinkerData *ld) {
|
||||
ld->needs_system_library_linked = true;
|
||||
@@ -161,7 +240,7 @@ gb_internal i32 linker_stage(LinkerData *gen) {
|
||||
try_cross_linking:;
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
String section_name = str_lit("msvc-link");
|
||||
String section_name = str_lit("rad-link");
|
||||
bool is_windows = build_context.metrics.os == TargetOs_windows;
|
||||
#else
|
||||
String section_name = str_lit("ld-link");
|
||||
@@ -174,12 +253,13 @@ try_cross_linking:;
|
||||
switch (build_context.linker_choice) {
|
||||
case Linker_Default: break;
|
||||
case Linker_lld: section_name = str_lit("lld-link"); break;
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
case Linker_radlink: break;
|
||||
#endif
|
||||
#if defined(GB_SYSTEM_LINUX) || defined(GB_SYSTEM_FREEBSD) || defined(GB_SYSTEM_NETBSD)
|
||||
case Linker_mold: section_name = str_lit("mold-link"); break;
|
||||
#endif
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
case Linker_radlink: section_name = str_lit("rad-link"); break;
|
||||
#endif
|
||||
case Linker_msvc: section_name = str_lit("msvc-link"); break;
|
||||
default:
|
||||
gb_printf_err("'%.*s' linker is not supported on this platform\n", LIT(linker_choices[build_context.linker_choice]));
|
||||
return 1;
|
||||
@@ -209,7 +289,6 @@ try_cross_linking:;
|
||||
add_path(build_context.build_paths[BuildPath_VS_LIB].basename);
|
||||
}
|
||||
|
||||
|
||||
StringSet min_libs_set = {};
|
||||
string_set_init(&min_libs_set, 64);
|
||||
defer (string_set_destroy(&min_libs_set));
|
||||
@@ -367,6 +446,10 @@ try_cross_linking:;
|
||||
|
||||
if (build_context.ODIN_DEBUG) {
|
||||
link_settings = gb_string_append_fmt(link_settings, " /DEBUG");
|
||||
if (build_context.build_mode != BuildMode_StaticLibrary) {
|
||||
// NOTE(bill): `/opt:ref` would also fold identical functions, which is slow and confuses the debugger
|
||||
link_settings = gb_string_append_fmt(link_settings, " /OPT:NOICF");
|
||||
}
|
||||
}
|
||||
|
||||
gbString object_files = gb_string_make(heap_allocator(), "");
|
||||
@@ -387,8 +470,36 @@ try_cross_linking:;
|
||||
lld_lto_flags = gb_string_append_fmt(lld_lto_flags, "/opt:lldltojobs=%d ", build_context.thread_count);
|
||||
}
|
||||
|
||||
String res_path = {};
|
||||
String rc_path = {};
|
||||
defer (gb_free(heap_allocator(), res_path.text));
|
||||
defer (gb_free(heap_allocator(), rc_path.text));
|
||||
|
||||
if (build_context.has_resource) {
|
||||
res_path = quote_path(heap_allocator(), build_context.build_paths[BuildPath_RES]);
|
||||
rc_path = quote_path(heap_allocator(), build_context.build_paths[BuildPath_RC]);
|
||||
|
||||
if (build_context.build_paths[BuildPath_RC].basename == "") {
|
||||
debugf("Using precompiled resource %.*s\n", LIT(res_path));
|
||||
} else {
|
||||
debugf("Compiling resource %.*s\n", LIT(res_path));
|
||||
|
||||
result = system_exec_command_line_app("resource compiler",
|
||||
"\"%.*src.exe\" /nologo /fo %.*s %.*s",
|
||||
LIT(windows_sdk_bin_path),
|
||||
LIT(res_path),
|
||||
LIT(rc_path)
|
||||
);
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (build_context.linker_choice) {
|
||||
case Linker_lld:
|
||||
<<<<<<< HEAD
|
||||
{
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
char linker_path[4096] = {0};
|
||||
@@ -420,12 +531,31 @@ try_cross_linking:;
|
||||
lib_str,
|
||||
lld_lto_flags
|
||||
);
|
||||
=======
|
||||
result = system_exec_msvc_linker_app("msvc-lld-link",
|
||||
"\"%.*s\\bin\\lld-link\" %s %.*s -OUT:\"%.*s\" %s "
|
||||
"/nologo /incremental:no /opt:ref /subsystem:%.*s "
|
||||
"%.*s "
|
||||
"%.*s "
|
||||
"%s "
|
||||
"%s "
|
||||
"",
|
||||
LIT(build_context.ODIN_ROOT), object_files, LIT(res_path), LIT(output_filename),
|
||||
link_settings,
|
||||
LIT(windows_subsystem_names[build_context.ODIN_WINDOWS_SUBSYSTEM]),
|
||||
LIT(build_context.link_flags),
|
||||
LIT(build_context.extra_linker_flags),
|
||||
lib_str,
|
||||
lld_lto_flags
|
||||
);
|
||||
>>>>>>> upstream/master
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
<<<<<<< HEAD
|
||||
case Linker_radlink:
|
||||
result = system_exec_command_line_app("msvc-rad-link",
|
||||
"\"%.*s\\bin\\radlink\" %s -OUT:\"%.*s\" %s "
|
||||
@@ -472,7 +602,11 @@ try_cross_linking:;
|
||||
} else {
|
||||
res_path = {};
|
||||
}
|
||||
=======
|
||||
break;
|
||||
>>>>>>> upstream/master
|
||||
|
||||
case Linker_msvc: {
|
||||
String linker_name = str_lit("link.exe");
|
||||
switch (build_context.build_mode) {
|
||||
case BuildMode_Executable:
|
||||
@@ -489,8 +623,7 @@ try_cross_linking:;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
result = system_exec_command_line_app("msvc-link",
|
||||
result = system_exec_msvc_linker_app("msvc-link",
|
||||
"\"%.*s%.*s\" %s %.*s -OUT:\"%.*s\" %s "
|
||||
"/nologo /subsystem:%.*s "
|
||||
"%.*s "
|
||||
@@ -504,11 +637,35 @@ try_cross_linking:;
|
||||
LIT(build_context.extra_linker_flags),
|
||||
lib_str
|
||||
);
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: { // radlink
|
||||
result = system_exec_msvc_linker_app("msvc-rad-link",
|
||||
"\"%.*s\\bin\\radlink\" %s %.*s -OUT:\"%.*s\" %s "
|
||||
"/nologo /incremental:no /opt:ref /subsystem:%.*s "
|
||||
"%.*s "
|
||||
"%.*s "
|
||||
"%s "
|
||||
"",
|
||||
LIT(build_context.ODIN_ROOT), object_files, LIT(res_path), LIT(output_filename),
|
||||
link_settings,
|
||||
LIT(windows_subsystem_names[build_context.ODIN_WINDOWS_SUBSYSTEM]),
|
||||
LIT(build_context.link_flags),
|
||||
LIT(build_context.extra_linker_flags),
|
||||
lib_str
|
||||
);
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
Reference in new issue
Block a user