Merge remote-tracking branch 'upstream/master' into windows-cross-compile

This commit is contained in:
A1029384756 committed 2026-10-05 08:31:04 -04:00
commit ba04d81d40
187 files changed
+33377 -16504

No files matched your search

+164 -7
View File
@@ -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 {