Merge pull request #1937 from IanLilleyT/rc_fix

Find rc.exe in Windows SDK
This commit is contained in:
Jeroen van Rijn
2022-08-09 16:03:17 +02:00
committed by GitHub
4 changed files with 200 additions and 177 deletions

View File

@@ -204,7 +204,7 @@ enum BuildPath : u8 {
BuildPath_Main_Package, // Input Path to the package directory (or file) we're building.
BuildPath_RC, // Input Path for .rc file, can be set with `-resource:`.
BuildPath_RES, // Output Path for .res file, generated from previous.
BuildPath_Win_SDK_Root, // windows_sdk_root
BuildPath_Win_SDK_Bin_Path, // windows_sdk_bin_path
BuildPath_Win_SDK_UM_Lib, // windows_sdk_um_library_path
BuildPath_Win_SDK_UCRT_Lib, // windows_sdk_ucrt_library_path
BuildPath_VS_EXE, // vs_exe_path
@@ -1336,7 +1336,7 @@ bool init_build_paths(String init_filename) {
if ((bc->command_kind & Command__does_build) && (!bc->ignore_microsoft_magic)) {
// NOTE(ic): It would be nice to extend this so that we could specify the Visual Studio version that we want instead of defaulting to the latest.
Find_Result_Utf8 find_result = find_visual_studio_and_windows_sdk_utf8();
Find_Result find_result = find_visual_studio_and_windows_sdk();
defer (mc_free_all());
if (find_result.windows_sdk_version == 0) {
@@ -1357,8 +1357,8 @@ bool init_build_paths(String init_filename) {
if (find_result.windows_sdk_um_library_path.len > 0) {
GB_ASSERT(find_result.windows_sdk_ucrt_library_path.len > 0);
if (find_result.windows_sdk_root.len > 0) {
bc->build_paths[BuildPath_Win_SDK_Root] = path_from_string(ha, find_result.windows_sdk_root);
if (find_result.windows_sdk_bin_path.len > 0) {
bc->build_paths[BuildPath_Win_SDK_Bin_Path] = path_from_string(ha, find_result.windows_sdk_bin_path);
}
if (find_result.windows_sdk_um_library_path.len > 0) {

View File

@@ -283,6 +283,9 @@ i32 linker_stage(lbGenerator *gen) {
String vs_exe_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_VS_EXE]);
defer (gb_free(heap_allocator(), vs_exe_path.text));
String windows_sdk_bin_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Win_SDK_Bin_Path]);
defer (gb_free(heap_allocator(), windows_sdk_bin_path.text));
char const *subsystem_str = build_context.use_subsystem_windows ? "WINDOWS" : "CONSOLE";
if (!build_context.use_lld) { // msvc
if (build_context.has_resource) {
@@ -292,7 +295,8 @@ i32 linker_stage(lbGenerator *gen) {
defer (gb_free(heap_allocator(), res_path.text));
result = system_exec_command_line_app("msvc-link",
"\"rc.exe\" /nologo /fo \"%.*s\" \"%.*s\"",
"\"%.*src.exe\" /nologo /fo \"%.*s\" \"%.*s\"",
LIT(windows_sdk_bin_path),
LIT(res_path),
LIT(rc_path)
);

View File

@@ -50,18 +50,7 @@ gb_global gbAllocator mc_allocator = heap_allocator();
struct Find_Result {
int windows_sdk_version; // Zero if no Windows SDK found.
wchar_t const *windows_sdk_root;
wchar_t const *windows_sdk_um_library_path;
wchar_t const *windows_sdk_ucrt_library_path;
wchar_t const *vs_exe_path;
wchar_t const *vs_library_path;
};
struct Find_Result_Utf8 {
int windows_sdk_version; // Zero if no Windows SDK found.
String windows_sdk_root;
String windows_sdk_bin_path;
String windows_sdk_um_library_path;
String windows_sdk_ucrt_library_path;
@@ -69,8 +58,6 @@ struct Find_Result_Utf8 {
String vs_library_path;
};
Find_Result_Utf8 find_visual_studio_and_windows_sdk_utf8();
String mc_wstring_to_string(wchar_t const *str) {
return string16_to_string(mc_allocator, make_string16_c(str));
}
@@ -87,6 +74,10 @@ String mc_concat(String a, String b, String c) {
return concatenate3_strings(mc_allocator, a, b, c);
}
String mc_concat(String a, String b, String c, String d) {
return concatenate4_strings(mc_allocator, a, b, c, d);
}
String mc_get_env(String key) {
char const * value = gb_get_env((char const *)key.text, mc_allocator);
return make_string_c(value);
@@ -219,19 +210,19 @@ struct DECLSPEC_UUID("42843719-DB4C-46C2-8E7C-64F1816EFD5B") DECLSPEC_NOVTABLE I
// The beginning of the actual code that does things.
struct Version_Data_Utf8 {
i32 best_version[4]; // For Windows 8 versions, only two of these numbers are used.
struct Version_Data {
i32 best_version[4];
String best_name;
};
typedef void (*MC_Visit_Proc)(String short_name, String full_name, Version_Data_Utf8 *data);
bool mc_visit_files(String dir_name, Version_Data_Utf8 *data, MC_Visit_Proc proc) {
typedef void (*MC_Visit_Proc)(String short_name, String full_name, Version_Data *data);
bool mc_visit_files(String dir_name, Version_Data *data, MC_Visit_Proc proc) {
// Visit everything in one folder (non-recursively). If it's a directory
// that doesn't start with ".", call the visit proc on it. The visit proc
// will see if the filename conforms to the expected versioning pattern.
String wildcard_name = mc_concat(dir_name, str_lit("\\*"));
String wildcard_name = mc_concat(dir_name, str_lit("*"));
defer (mc_free(wildcard_name));
MC_Find_Data find_data;
@@ -242,7 +233,7 @@ bool mc_visit_files(String dir_name, Version_Data_Utf8 *data, MC_Visit_Proc proc
bool success = true;
while (success) {
if ((find_data.file_attributes & FILE_ATTRIBUTE_DIRECTORY) && (find_data.filename[0] != '.')) {
String full_name = mc_concat(dir_name, str_lit("\\"), find_data.filename);
String full_name = mc_concat(dir_name, find_data.filename);
defer (mc_free(full_name));
proc(find_data.filename, full_name, data);
@@ -284,7 +275,7 @@ String find_windows_kit_root(HKEY key, String const version) {
return value;
}
void win10_best(String short_name, String full_name, Version_Data_Utf8 *data) {
void win10_best(String short_name, String full_name, Version_Data *data) {
// Find the Windows 10 subdirectory with the highest version number.
int i0, i1, i2, i3;
@@ -304,11 +295,11 @@ void win10_best(String short_name, String full_name, Version_Data_Utf8 *data) {
// we have to copy_string and free here because visit_files free's the full_name string
// after we execute this function, so Win*_Data would contain an invalid pointer.
if (data->best_name.len > 0) mc_free(data->best_name);
if (data->best_name.len) mc_free(data->best_name);
data->best_name = copy_string(mc_allocator, full_name);
if (data->best_name.len > 0) {
if (data->best_name.len) {
data->best_version[0] = i0;
data->best_version[1] = i1;
data->best_version[2] = i2;
@@ -316,34 +307,8 @@ void win10_best(String short_name, String full_name, Version_Data_Utf8 *data) {
}
}
void win8_best(String short_name, String full_name, Version_Data_Utf8 *data) {
// Find the Windows 8 subdirectory with the highest version number.
int i0, i1;
auto success = sscanf_s((const char *const)short_name.text, "winv%d.%d", &i0, &i1);
if (success < 2) return;
if (i0 < data->best_version[0]) return;
else if (i0 == data->best_version[0]) {
if (i1 < data->best_version[1]) return;
}
// we have to copy_string and free here because visit_files free's the full_name string
// after we execute this function, so Win*_Data would contain an invalid pointer.
if (data->best_name.len > 0) mc_free(data->best_name);
data->best_name = copy_string(mc_allocator, full_name);
if (data->best_name.len > 0) {
data->best_version[0] = i0;
data->best_version[1] = i1;
}
}
void find_windows_kit_root(Find_Result_Utf8 *result) {
// Information about the Windows 10 and Windows 8 development kits
// is stored in the same place in the registry. We open a key
// to that place, first checking preferntially for a Windows 10 kit,
// then, if that's not found, a Windows 8 kit.
void find_windows_kit_paths(Find_Result *result) {
bool sdk_found = false;
HKEY main_key;
@@ -355,44 +320,42 @@ void find_windows_kit_root(Find_Result_Utf8 *result) {
// Look for a Windows 10 entry.
String windows10_root = find_windows_kit_root(main_key, str_lit("KitsRoot10"));
if (windows10_root.len > 0) {
if (windows10_root.len) {
defer (mc_free(windows10_root));
String windows10_lib = mc_concat(windows10_root, str_lit("Lib"));
String windows10_lib = mc_concat(windows10_root, str_lit("Lib\\"));
Version_Data data_lib = {0};
mc_visit_files(windows10_lib, &data_lib, win10_best);
defer (mc_free(windows10_lib));
defer (mc_free(data_lib.best_name));
Version_Data_Utf8 data = {0};
mc_visit_files(windows10_lib, &data, win10_best);
if (data.best_name.len > 0) {
result->windows_sdk_version = 10;
result->windows_sdk_root = mc_concat(data.best_name, str_lit("\\"));
return;
String windows10_bin = mc_concat(windows10_root, str_lit("bin\\"));
Version_Data data_bin = {0};
mc_visit_files(windows10_bin, &data_bin, win10_best);
defer (mc_free(windows10_bin));
defer (mc_free(data_bin.best_name));
if (data_lib.best_name.len && data_bin.best_name.len) {
if (build_context.metrics.arch == TargetArch_amd64) {
result->windows_sdk_um_library_path = mc_concat(data_lib.best_name, str_lit("\\um\\x64\\"));
result->windows_sdk_ucrt_library_path = mc_concat(data_lib.best_name, str_lit("\\ucrt\\x64\\"));
result->windows_sdk_bin_path = mc_concat(data_bin.best_name, str_lit("\\x64\\"));
sdk_found = true;
} else if (build_context.metrics.arch == TargetArch_i386) {
result->windows_sdk_um_library_path = mc_concat(data_lib.best_name, str_lit("\\um\\x86\\"));
result->windows_sdk_ucrt_library_path = mc_concat(data_lib.best_name, str_lit("\\ucrt\\x86\\"));
result->windows_sdk_bin_path = mc_concat(data_bin.best_name, str_lit("\\x86\\"));
sdk_found = true;
}
}
mc_free(data.best_name);
}
// Look for a Windows 8 entry.
String windows8_root = find_windows_kit_root(main_key, str_lit("KitsRoot81"));
if (windows8_root.len > 0) {
defer (mc_free(windows8_root));
String windows8_lib = mc_concat(windows8_root, str_lit("Lib"));
defer (mc_free(windows8_lib));
Version_Data_Utf8 data = {0};
mc_visit_files(windows8_lib, &data, win8_best);
if (data.best_name.len > 0) {
result->windows_sdk_version = 8;
result->windows_sdk_root = mc_concat(data.best_name, str_lit("\\"));
return;
}
mc_free(data.best_name);
if (sdk_found) {
result->windows_sdk_version = 10;
}
// If we get here, we failed to find anything.
}
bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result_Utf8 *result) {
bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *result) {
// The name of this procedure is kind of cryptic. Its purpose is
// to fight through Microsoft craziness. The things that the fine
// Visual Studio team want you to do, JUST TO FIND A SINGLE FOLDER
@@ -555,54 +518,97 @@ bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result_Utf8
}
// NOTE(WalterPlinge): Environment variables can help to find Visual C++ and WinSDK paths for both
// official and portable installations (like mmozeiko's portable msvc script). This will only use
// the first paths it finds, and won't overwrite any values that `result` already has.
bool find_msvc_install_from_env_vars(Find_Result_Utf8 *result) {
// official and portable installations (like mmozeiko's portable msvc script).
void find_windows_kit_paths_from_env_vars(Find_Result *result) {
if (build_context.metrics.arch != TargetArch_amd64 && build_context.metrics.arch != TargetArch_i386) {
return false;
return;
}
// We can find windows sdk using the following combination of env vars:
// (UniversalCRTSdkDir or WindowsSdkDir) and (WindowsSDKLibVersion or WindowsSDKVersion)
bool sdk_found = false;
// We can find windows sdk lib dir using the following combination of env vars:
// (WindowsSdkDir or UniversalCRTSdkDir) and (WindowsSDKVersion or WindowsSDKLibVersion)
bool sdk_lib_found = false;
// We can find windows sdk bin dir using the following combination of env vars:
// (WindowsSdkVerBinPath) or ((WindowsSdkBinPath or WindowsSdkDir or UniversalCRTSdkDir) and (WindowsSDKVersion || WindowsSDKLibVersion))
bool sdk_bin_found = false;
// These appear to be suitable env vars used by Visual Studio
String win_sdk_ver_env = mc_get_env(str_lit("WindowsSDKVersion"));
String win_sdk_lib_env = mc_get_env(str_lit("WindowsSDKLibVersion"));
String win_sdk_lib_ver_env = mc_get_env(str_lit("WindowsSDKLibVersion"));
String win_sdk_dir_env = mc_get_env(str_lit("WindowsSdkDir"));
String crt_sdk_dir_env = mc_get_env(str_lit("UniversalCRTSdkDir"));
String win_sdk_bin_path_env = mc_get_env(str_lit("WindowsSdkBinPath"));
String win_sdk_ver_bin_path_env = mc_get_env(str_lit("WindowsSdkVerBinPath"));
defer ({
mc_free(win_sdk_ver_env);
mc_free(win_sdk_lib_env);
mc_free(win_sdk_lib_ver_env);
mc_free(win_sdk_dir_env);
mc_free(crt_sdk_dir_env);
mc_free(win_sdk_bin_path_env);
mc_free(win_sdk_ver_bin_path_env);
});
if (win_sdk_ver_bin_path_env.len || ((win_sdk_bin_path_env.len || win_sdk_dir_env.len || crt_sdk_dir_env.len) && (win_sdk_ver_env.len || win_sdk_lib_ver_env.len))) {
String bin;
defer (mc_free(bin));
if (win_sdk_ver_bin_path_env.len) {
String dir = win_sdk_ver_bin_path_env;
// Add trailing '\' in case it was missing
bin = mc_concat(dir, dir[dir.len - 1] != '\\' ? str_lit("\\") : str_lit(""));
} else {
String dir = win_sdk_bin_path_env.len ? win_sdk_bin_path_env : win_sdk_dir_env.len ? win_sdk_dir_env : crt_sdk_dir_env;
String ver = win_sdk_ver_env.len ? win_sdk_ver_env : win_sdk_lib_ver_env;
// Add trailing '\' in case it was missing
dir = mc_concat(dir, dir[dir.len - 1] != '\\' ? str_lit("\\") : str_lit(""));
ver = mc_concat(ver, ver[ver.len - 1] != '\\' ? str_lit("\\") : str_lit(""));
defer (mc_free(dir));
defer (mc_free(ver));
// Append "bin" for win_sdk_dir_env and crt_sdk_dir_env
String dir_bin = mc_concat(dir, win_sdk_bin_path_env.len ? str_lit("") : str_lit("bin\\"));
defer (mc_free(dir_bin));
bin = mc_concat(dir_bin, ver);
}
if (build_context.metrics.arch == TargetArch_amd64) {
result->windows_sdk_bin_path = mc_concat(bin, str_lit("x64\\"));
sdk_bin_found = true;
} else if (build_context.metrics.arch == TargetArch_i386) {
result->windows_sdk_bin_path = mc_concat(bin, str_lit("x86\\"));
sdk_bin_found = true;
}
}
// NOTE(WalterPlinge): If any combination is found, let's just assume they are correct
if ((win_sdk_ver_env.len || win_sdk_lib_env.len) && (win_sdk_dir_env.len || crt_sdk_dir_env.len)) {
//? Maybe we need to handle missing '\' at end of strings, so far it doesn't seem an issue
if ((win_sdk_ver_env.len || win_sdk_lib_ver_env.len) && (win_sdk_dir_env.len || crt_sdk_dir_env.len)) {
String dir = win_sdk_dir_env.len ? win_sdk_dir_env : crt_sdk_dir_env;
String ver = win_sdk_ver_env.len ? win_sdk_ver_env : win_sdk_lib_env;
String ver = win_sdk_ver_env.len ? win_sdk_ver_env : win_sdk_lib_ver_env;
// These have trailing '\' as we are just composing the path
String um_dir = build_context.metrics.arch == TargetArch_amd64
? str_lit("um\\x64\\")
: str_lit("um\\x86\\");
String ucrt_dir = build_context.metrics.arch == TargetArch_amd64
? str_lit("ucrt\\x64\\")
: str_lit("ucrt\\x86\\");
// Add trailing '\' in case it was missing
dir = mc_concat(dir, dir[dir.len - 1] != '\\' ? str_lit("\\") : str_lit(""));
ver = mc_concat(ver, ver[ver.len - 1] != '\\' ? str_lit("\\") : str_lit(""));
defer (mc_free(dir));
defer (mc_free(ver));
result->windows_sdk_root = mc_concat(dir, str_lit("Lib\\"), ver);
result->windows_sdk_um_library_path = mc_concat(result->windows_sdk_root, um_dir);
result->windows_sdk_ucrt_library_path = mc_concat(result->windows_sdk_root, ucrt_dir);
sdk_found = true;
if (build_context.metrics.arch == TargetArch_amd64) {
result->windows_sdk_um_library_path = mc_concat(dir, str_lit("Lib\\"), ver, str_lit("um\\x64\\"));
result->windows_sdk_ucrt_library_path = mc_concat(dir, str_lit("Lib\\"), ver, str_lit("ucrt\\x64\\"));
sdk_lib_found = true;
} else if (build_context.metrics.arch == TargetArch_i386) {
result->windows_sdk_um_library_path = mc_concat(dir, str_lit("Lib\\"), ver, str_lit("um\\x86\\"));
result->windows_sdk_ucrt_library_path = mc_concat(dir, str_lit("Lib\\"), ver, str_lit("ucrt\\x86\\"));
sdk_lib_found = true;
}
}
// If we haven't found it yet, we can loop through LIB for specific folders
//? This may not be robust enough using `um\x64` and `ucrt\x64`
if (!sdk_found) {
if (!sdk_lib_found) {
String lib = mc_get_env(str_lit("LIB"));
defer (mc_free(lib));
@@ -624,72 +630,67 @@ bool find_msvc_install_from_env_vars(Find_Result_Utf8 *result) {
continue;
}
hi = c;
String dir = substring(lib, lo, hi);
defer (lo = hi + 1);
// Skip when there are two ;; in a row
if (lo == hi) {
continue;
}
String dir = substring(lib, lo, hi);
// Remove the last slash so we can match with the strings above
String end = dir[dir.len - 1] == '\\'
? substring(dir, 0, dir.len - 1)
: substring(dir, 0, dir.len);
// Find one and we can make the other
if (string_ends_with(end, um_dir)) {
result->windows_sdk_um_library_path = mc_concat(end, str_lit("\\"));
break;
result->windows_sdk_um_library_path = mc_concat(end, str_lit("\\"));
} else if (string_ends_with(end, ucrt_dir)) {
result->windows_sdk_ucrt_library_path = mc_concat(end, str_lit("\\"));
}
if (result->windows_sdk_um_library_path.len && result->windows_sdk_ucrt_library_path.len) {
sdk_lib_found = true;
break;
}
}
// Get the root from the one we found, and make the other
// NOTE(WalterPlinge): we need to copy the string so that we don't risk a double free
if (result->windows_sdk_um_library_path.len > 0) {
String root = substring(result->windows_sdk_um_library_path, 0, result->windows_sdk_um_library_path.len - 1 - um_dir.len);
result->windows_sdk_root = copy_string(mc_allocator, root);
result->windows_sdk_ucrt_library_path = mc_concat(result->windows_sdk_root, ucrt_dir, str_lit("\\"));
} else if (result->windows_sdk_ucrt_library_path.len > 0) {
String root = substring(result->windows_sdk_ucrt_library_path, 0, result->windows_sdk_ucrt_library_path.len - 1 - ucrt_dir.len);
result->windows_sdk_root = copy_string(mc_allocator, root);
result->windows_sdk_um_library_path = mc_concat(result->windows_sdk_root, um_dir, str_lit("\\"));
}
if (result->windows_sdk_root.len > 0) {
sdk_found = true;
}
}
}
// NOTE(WalterPlinge): So far this function assumes it will only be called if MSVC was
// installed using mmozeiko's portable msvc script, which uses the windows 10 sdk.
// This may need to be changed later if it ends up causing problems.
if (sdk_found && result->windows_sdk_version == 0) {
if (sdk_bin_found && sdk_lib_found) {
result->windows_sdk_version = 10;
}
}
// NOTE(WalterPlinge): Environment variables can help to find Visual C++ and WinSDK paths for both
// official and portable installations (like mmozeiko's portable msvc script). This will only use
// the first paths it finds, and won't overwrite any values that `result` already has.
void find_visual_studio_paths_from_env_vars(Find_Result *result) {
if (build_context.metrics.arch != TargetArch_amd64 && build_context.metrics.arch != TargetArch_i386) {
return;
}
bool vs_found = false;
if (result->vs_exe_path.len > 0 && result->vs_library_path.len > 0) {
vs_found = true;
}
// We can find visual studio using VCToolsInstallDir
if (!vs_found) {
String vctid = mc_get_env(str_lit("VCToolsInstallDir"));
defer (mc_free(vctid));
String vctid = mc_get_env(str_lit("VCToolsInstallDir"));
defer (mc_free(vctid));
if (vctid.len) {
String exe = build_context.metrics.arch == TargetArch_amd64
? str_lit("bin\\Hostx64\\x64\\")
: str_lit("bin\\Hostx86\\x86\\");
String lib = build_context.metrics.arch == TargetArch_amd64
? str_lit("lib\\x64\\")
: str_lit("lib\\x86\\");
if (vctid.len) {
String exe = build_context.metrics.arch == TargetArch_amd64
? str_lit("bin\\Hostx64\\x64\\")
: str_lit("bin\\Hostx86\\x86\\");
String lib = build_context.metrics.arch == TargetArch_amd64
? str_lit("lib\\x64\\")
: str_lit("lib\\x86\\");
result->vs_exe_path = mc_concat(vctid, exe);
result->vs_library_path = mc_concat(vctid, lib);
vs_found = true;
}
result->vs_exe_path = mc_concat(vctid, exe);
result->vs_library_path = mc_concat(vctid, lib);
vs_found = true;
}
// If we haven't found it yet, we can loop through Path for specific folders
@@ -701,21 +702,32 @@ bool find_msvc_install_from_env_vars(Find_Result_Utf8 *result) {
String exe = build_context.metrics.arch == TargetArch_amd64
? str_lit("bin\\Hostx64\\x64")
: str_lit("bin\\Hostx86\\x86");
// The environment variable may have an uppercase X even though the folder is lowercase
String exe2 = build_context.metrics.arch == TargetArch_amd64
? str_lit("bin\\HostX64\\x64")
: str_lit("bin\\HostX86\\x86");
String lib = build_context.metrics.arch == TargetArch_amd64
? str_lit("lib\\x64")
: str_lit("lib\\x86");
isize lo = {0};
isize hi = {0};
for (isize c = 0; c < path.len; c += 1) {
if (path[c] != ';') {
for (isize c = 0; c <= path.len; c += 1) {
if (c != path.len && path[c] != ';') {
continue;
}
hi = c;
String dir = substring(path, lo, hi);
defer (lo = hi + 1);
// Skip when there are two ;; in a row
if (lo == hi) {
continue;
}
String dir = substring(path, lo, hi);
// Remove the last slash so we can match with the strings above
String end = dir[dir.len - 1] == '\\'
? substring(dir, 0, dir.len - 1)
: substring(dir, 0, dir.len);
@@ -726,7 +738,10 @@ bool find_msvc_install_from_env_vars(Find_Result_Utf8 *result) {
defer (mc_free(cl));
defer (mc_free(link));
if (!string_ends_with(end, exe) || !gb_file_exists((char *)cl.text) || !gb_file_exists((char *)link.text)) {
if (!string_ends_with(end, exe) && !string_ends_with(end, exe2)) {
continue;
}
if (!gb_file_exists((char *)cl.text) || !gb_file_exists((char *)link.text)) {
continue;
}
@@ -735,42 +750,36 @@ bool find_msvc_install_from_env_vars(Find_Result_Utf8 *result) {
result->vs_library_path = mc_concat(root, lib, str_lit("\\"));
vs_found = true;
break;
}
}
}
return sdk_found && vs_found;
}
Find_Result_Utf8 find_visual_studio_and_windows_sdk_utf8() {
Find_Result_Utf8 r = {};
find_windows_kit_root(&r);
if (r.windows_sdk_root.len > 0) {
if (build_context.metrics.arch == TargetArch_amd64) {
r.windows_sdk_um_library_path = mc_concat(r.windows_sdk_root, str_lit("um\\x64\\"));
r.windows_sdk_ucrt_library_path = mc_concat(r.windows_sdk_root, str_lit("ucrt\\x64\\"));
} else if (build_context.metrics.arch == TargetArch_i386) {
r.windows_sdk_um_library_path = mc_concat(r.windows_sdk_root, str_lit("um\\x86\\"));
r.windows_sdk_ucrt_library_path = mc_concat(r.windows_sdk_root, str_lit("ucrt\\x86\\"));
}
}
Find_Result find_visual_studio_and_windows_sdk() {
Find_Result r = {};
find_windows_kit_paths(&r);
find_visual_studio_by_fighting_through_microsoft_craziness(&r);
bool all_found =
r.windows_sdk_root.len > 0 &&
r.windows_sdk_um_library_path.len > 0 &&
r.windows_sdk_ucrt_library_path.len > 0 &&
r.vs_exe_path.len > 0 &&
r.vs_library_path.len > 0;
bool sdk_found =
r.windows_sdk_bin_path.len &&
r.windows_sdk_um_library_path.len &&
r.windows_sdk_ucrt_library_path.len ;
if (!all_found) {
find_msvc_install_from_env_vars(&r);
bool vs_found =
r.vs_exe_path.len &&
r.vs_library_path.len ;
if (!sdk_found) {
find_windows_kit_paths_from_env_vars(&r);
}
if (!vs_found) {
find_visual_studio_paths_from_env_vars(&r);
}
#if 0
printf("windows_sdk_root: %.*s\n", LIT(r.windows_sdk_root));
printf("windows_sdk_bin_path: %.*s\n", LIT(r.windows_sdk_bin_path));
printf("windows_sdk_um_library_path: %.*s\n", LIT(r.windows_sdk_um_library_path));
printf("windows_sdk_ucrt_library_path: %.*s\n", LIT(r.windows_sdk_ucrt_library_path));
printf("vs_exe_path: %.*s\n", LIT(r.vs_exe_path));

View File

@@ -324,6 +324,16 @@ String concatenate3_strings(gbAllocator a, String const &x, String const &y, Str
data[len] = 0;
return make_string(data, len);
}
String concatenate4_strings(gbAllocator a, String const &x, String const &y, String const &z, String const &w) {
isize len = x.len+y.len+z.len+w.len;
u8 *data = gb_alloc_array(a, u8, len+1);
gb_memmove(data, x.text, x.len);
gb_memmove(data+x.len, y.text, y.len);
gb_memmove(data+x.len+y.len, z.text, z.len);
gb_memmove(data+x.len+y.len+z.len, w.text, w.len);
data[len] = 0;
return make_string(data, len);
}
String string_join_and_quote(gbAllocator a, Array<String> strings) {
if (!strings.count) {