diff --git a/vlib/v/builder/msvc.v b/vlib/v/builder/msvc.v index 5f9ee8ead2..123e2e7c86 100644 --- a/vlib/v/builder/msvc.v +++ b/vlib/v/builder/msvc.v @@ -80,15 +80,28 @@ struct WindowsKit { // Try and find the root key for installed windows kits fn find_windows_kit_root(target_arch string) ?WindowsKit { + $if windows { + wkroot := find_windows_kit_root_by_reg(target_arch) or { + if wkroot := find_windows_kit_root_by_env(target_arch) { + return wkroot + } + return err + } + + return wkroot + } $else { + return error('Host OS does not support finding a windows kit') + } +} + +// Try to find the root key for installed windows kits from registry +fn find_windows_kit_root_by_reg(target_arch string) ?WindowsKit { $if windows { root_key := RegKey(0) path := 'SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots' rc := C.RegOpenKeyEx(builder.hkey_local_machine, path.to_wide(), 0, builder.key_query_value | builder.key_wow64_32key | builder.key_enumerate_sub_keys, &root_key) - // TODO: Fix defer inside ifs - // defer { - // C.RegCloseKey(root_key) - // } + if rc != 0 { return error('Unable to open root key') } @@ -97,30 +110,44 @@ fn find_windows_kit_root(target_arch string) ?WindowsKit { C.RegCloseKey(root_key) return error('Unable to find a windows kit') } - kit_lib := kit_root + 'Lib' - files := os.ls(kit_lib) ? - mut highest_path := '' - mut highest_int := 0 - for f in files { - no_dot := f.replace('.', '') - v_int := no_dot.int() - if v_int > highest_int { - highest_int = v_int - highest_path = f - } - } - kit_lib_highest := kit_lib + '\\$highest_path' - kit_include_highest := kit_lib_highest.replace('Lib', 'Include') C.RegCloseKey(root_key) - return WindowsKit{ - um_lib_path: kit_lib_highest + '\\um\\$target_arch' - ucrt_lib_path: kit_lib_highest + '\\ucrt\\$target_arch' - um_include_path: kit_include_highest + '\\um' - ucrt_include_path: kit_include_highest + '\\ucrt' - shared_include_path: kit_include_highest + '\\shared' + return new_windows_kit(kit_root, target_arch) + } $else { + return error('Host OS does not support finding a windows kit') + } +} + +fn new_windows_kit(kit_root string, target_arch string) ?WindowsKit { + kit_lib := kit_root + 'Lib' + files := os.ls(kit_lib) ? + mut highest_path := '' + mut highest_int := 0 + for f in files { + no_dot := f.replace('.', '') + v_int := no_dot.int() + if v_int > highest_int { + highest_int = v_int + highest_path = f } } - return error('Host OS does not support finding a windows kit') + kit_lib_highest := kit_lib + '\\$highest_path' + kit_include_highest := kit_lib_highest.replace('Lib', 'Include') + return WindowsKit{ + um_lib_path: kit_lib_highest + '\\um\\$target_arch' + ucrt_lib_path: kit_lib_highest + '\\ucrt\\$target_arch' + um_include_path: kit_include_highest + '\\um' + ucrt_include_path: kit_include_highest + '\\ucrt' + shared_include_path: kit_include_highest + '\\shared' + } +} + +fn find_windows_kit_root_by_env(target_arch string) ?WindowsKit { + kit_root := os.getenv('WindowsSdkDir') + if kit_root == '' { + return none + } + + return new_windows_kit(kit_root, target_arch) } struct VsInstallation { @@ -130,39 +157,76 @@ struct VsInstallation { } fn find_vs(vswhere_dir string, host_arch string, target_arch string) ?VsInstallation { - $if !windows { + $if windows { + vsinst := find_vs_by_reg(vswhere_dir, host_arch, target_arch) or { + if vsinst := find_vs_by_env(host_arch, target_arch) { + return vsinst + } + return err + } + return vsinst + } $else { return error('Host OS does not support finding a Visual Studio installation') } - // Emily: - // VSWhere is guaranteed to be installed at this location now - // If its not there then end user needs to update their visual studio - // installation! - res := os.execute('"$vswhere_dir\\Microsoft Visual Studio\\Installer\\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath') - if res.exit_code != 0 { - return error_with_code(res.output, res.exit_code) - } - res_output := res.output.trim_right('\r\n') - // println('res: "$res"') - version := os.read_file('$res_output\\VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt') or { - // println('Unable to find msvc version') - return error('Unable to find vs installation') - } - version2 := version // TODO remove. cgen option bug if expr - // println('version: $version') - v := if version.ends_with('\n') { version2[..version.len - 2] } else { version2 } - lib_path := '$res.output\\VC\\Tools\\MSVC\\$v\\lib\\$target_arch' - include_path := '$res.output\\VC\\Tools\\MSVC\\$v\\include' - if os.exists('$lib_path\\vcruntime.lib') { - p := '$res.output\\VC\\Tools\\MSVC\\$v\\bin\\Host$host_arch\\$target_arch' - // println('$lib_path $include_path') - return VsInstallation{ - exe_path: p - lib_path: lib_path - include_path: include_path +} + +fn find_vs_by_reg(vswhere_dir string, host_arch string, target_arch string) ?VsInstallation { + $if windows { + // Emily: + // VSWhere is guaranteed to be installed at this location now + // If its not there then end user needs to update their visual studio + // installation! + res := os.execute('"$vswhere_dir\\Microsoft Visual Studio\\Installer\\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath') + if res.exit_code != 0 { + return error_with_code(res.output, res.exit_code) } + res_output := res.output.trim_right('\r\n') + // println('res: "$res"') + version := os.read_file('$res_output\\VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt') or { + // println('Unable to find msvc version') + return error('Unable to find vs installation') + } + version2 := version // TODO remove. cgen option bug if expr + // println('version: $version') + v := if version.ends_with('\n') { version2[..version.len - 2] } else { version2 } + lib_path := '$res.output\\VC\\Tools\\MSVC\\$v\\lib\\$target_arch' + include_path := '$res.output\\VC\\Tools\\MSVC\\$v\\include' + if os.exists('$lib_path\\vcruntime.lib') { + p := '$res.output\\VC\\Tools\\MSVC\\$v\\bin\\Host$host_arch\\$target_arch' + // println('$lib_path $include_path') + return VsInstallation{ + exe_path: p + lib_path: lib_path + include_path: include_path + } + } + println('Unable to find vs installation (attempted to use lib path "$lib_path")') + return error('Unable to find vs exe folder') + } $else { + return error('Host OS does not support finding a Visual Studio installation') + } +} + +fn find_vs_by_env(host_arch string, target_arch string) ?VsInstallation { + vs_dir := os.getenv('VSINSTALLDIR') + if vs_dir == '' { + return none + } + + vc_tools_dir := os.getenv('VCToolsInstallDir') + if vc_tools_dir == '' { + return none + } + + bin_dir := '${vc_tools_dir}bin\\Host$host_arch\\$target_arch' + lib_path := '${vc_tools_dir}lib\\$target_arch' + include_path := '${vc_tools_dir}include' + + return VsInstallation{ + exe_path: bin_dir + lib_path: lib_path + include_path: include_path } - println('Unable to find vs installation (attempted to use lib path "$lib_path")') - return error('Unable to find vs exe folder') } fn find_msvc(m64_target bool) ?MsvcResult {