v.builder: try finding msvc from env variables, when not found from registry (#10072)

pull/10065/head
kevin70g 2021-05-10 15:15:50 +08:00 committed by GitHub
parent e9c84ce154
commit 28a22e5a84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 118 additions and 54 deletions

View File

@ -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 {