mirror of
https://github.com/Cheviiot/Vintner.git
synced 2026-08-03 15:57:24 +00:00
Fix MSBuild toolset/SDK detection under Wine
msbuild <project>.vcxproj previously failed with MSB8020 ("build tools for
vNNN cannot be found") because MSBuild's own toolset/SDK resolution reads
a different set of environment variables than cl/link/lib do directly
(VCInstallDir_<N>, VCToolsInstallDir_<N>, VsInstallRoot,
WindowsSdkDir_10, WindowsTargetPlatformVersion, DisableRegistryUse, etc) -
none of which the generic INCLUDE/LIB/WINEPATH env covered.
Added msbuildEnv, populated for every MSBuild toolset generation actually
present under MSBuild/Microsoft/VC/v*, and wired into the msbuild wrapper.
Verified end-to-end: msbuild successfully builds ocornut/imgui's
example_win32_directx11.vcxproj (retargeted from its original v141
PlatformToolset to this install's v145) - compiles all 8 sources and
links against d3d11.lib/d3dcompiler.lib/dxgi.lib, producing a valid
PE32+ executable.
This commit is contained in:
@@ -16,6 +16,14 @@ type Paths struct {
|
||||
SDKBinDir string // <dest>/kits/10/bin/<sdkver>/<host> - mc/midl/mt/rc live here
|
||||
MSBuildBinDir string // <dest>/MSBuild/Current/Bin/<dotnetHost> - MSBuild.exe lives here
|
||||
|
||||
// Windows-notation ("z:\...") equivalents of the paths above, needed to
|
||||
// populate the MSBuild-specific environment variables its toolset/SDK
|
||||
// detection props read (see msbuildEnv in the wrapper package).
|
||||
BaseWin string // z:\<dest>
|
||||
MSVCBaseWin string // z:\<dest>\vc
|
||||
MSVCDirWin string // z:\<dest>\vc\tools\msvc\<ver>
|
||||
SDKBaseWin string // z:\<dest>\kits\10
|
||||
|
||||
Include string
|
||||
Lib string
|
||||
LibPath string
|
||||
@@ -89,6 +97,11 @@ func NewPaths(cfg *Config, baseUnix string) *Paths {
|
||||
SDKBinDir: sdkBinDir,
|
||||
MSBuildBinDir: msbuildBinDir,
|
||||
|
||||
BaseWin: winBase,
|
||||
MSVCBaseWin: msvcBase,
|
||||
MSVCDirWin: msvcDirWin,
|
||||
SDKBaseWin: sdkBase,
|
||||
|
||||
Include: include,
|
||||
Lib: lib,
|
||||
LibPath: lib,
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package wrapper
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Cheviiot/msvc-go-wine/internal/wineenv"
|
||||
)
|
||||
|
||||
var reToolsetDir = regexp.MustCompile(`^v(\d+)$`)
|
||||
|
||||
// msbuildEnv returns the extra environment variables MSBuild's own
|
||||
// SDK/toolset-detection property sheets need. The generic INCLUDE/LIB/
|
||||
// WINEPATH set by buildEnv are enough for cl/link/lib invoked directly, but
|
||||
// MSBuild resolves the compiler location and Windows SDK through a
|
||||
// different, registry-oriented mechanism - DisableRegistryUse=true
|
||||
// redirects that lookup to these variables instead of a (nonexistent)
|
||||
// Windows Registry.
|
||||
func msbuildEnv(cfg *wineenv.Config, paths *wineenv.Paths) map[string]string {
|
||||
env := map[string]string{
|
||||
"DisableRegistryUse": "true",
|
||||
"VCToolsVersion": cfg.MSVCVer,
|
||||
"VsInstallRoot": paths.BaseWin + `\`,
|
||||
"VSInstallDir": paths.BaseWin + `\`,
|
||||
|
||||
"MicrosoftKitRoot": paths.BaseWin + `\`,
|
||||
"SDKReferenceDirectoryRoot": paths.BaseWin + `\`,
|
||||
"SDKExtensionDirectoryRoot": paths.BaseWin + `\`,
|
||||
"MSBUILDSDKREFERENCEDIRECTORY": paths.BaseWin + `\`,
|
||||
"MSBUILDMULTIPLATFORMSDKREFERENCEDIRECTORY": paths.BaseWin + `\`,
|
||||
|
||||
"WindowsSdkDir_10": paths.SDKBaseWin + `\`,
|
||||
"UniversalCRTSdkDir_10": paths.SDKBaseWin + `\`,
|
||||
"WindowsSdkDir": paths.SDKBaseWin + `\`,
|
||||
"UniversalCRTSdkDir": paths.SDKBaseWin + `\`,
|
||||
"WindowsTargetPlatformVersion": cfg.SDKVer,
|
||||
"UCRTContentRoot": paths.SDKBaseWin + `\`,
|
||||
"NETFXKitsDir": paths.SDKBaseWin + `\`,
|
||||
"NETFXSDKDir": paths.SDKBaseWin + `\`,
|
||||
|
||||
// WDK-specific properties; harmless when not building a driver.
|
||||
"WDKKitVersion": "10",
|
||||
"Driver_SpectreMitigation": "false",
|
||||
"SignMode": "off",
|
||||
"Inf2CatNoCatalog": "true",
|
||||
"ApiValidator_Enable": "False",
|
||||
|
||||
"Platform": msbuildPlatform(cfg.Arch),
|
||||
}
|
||||
|
||||
// Microsoft.Cpp.props resolves the compiler/toolset location through
|
||||
// VCInstallDir_<N>/VCToolsInstallDir_<N>, where <N> is whatever numeric
|
||||
// suffix the installed MSBuild toolset property sheets use (e.g.
|
||||
// .../MSBuild/Microsoft/VC/v180 -> "180"). Populate every one actually
|
||||
// present, so a project pinned to any of them resolves to the one real
|
||||
// toolchain that's installed.
|
||||
matches, _ := filepath.Glob(filepath.Join(paths.BaseUnix, "MSBuild", "Microsoft", "VC", "v*"))
|
||||
for _, m := range matches {
|
||||
sub := reToolsetDir.FindStringSubmatch(filepath.Base(m))
|
||||
if sub == nil {
|
||||
continue
|
||||
}
|
||||
env["VCInstallDir_"+sub[1]] = paths.MSVCBaseWin + `\`
|
||||
env["VCToolsInstallDir_"+sub[1]] = paths.MSVCDirWin + `\`
|
||||
}
|
||||
|
||||
if strings.HasSuffix(paths.MSBuildBinDir, "amd64") {
|
||||
env["PreferredToolArchitecture"] = "x64"
|
||||
}
|
||||
|
||||
return env
|
||||
}
|
||||
|
||||
func msbuildPlatform(arch string) string {
|
||||
switch arch {
|
||||
case "x86":
|
||||
return "Win32"
|
||||
case "arm":
|
||||
return "ARM"
|
||||
case "arm64":
|
||||
return "ARM64"
|
||||
default:
|
||||
return arch
|
||||
}
|
||||
}
|
||||
@@ -70,9 +70,15 @@ func Run(tool string, args []string) int {
|
||||
var exitCode int
|
||||
switch {
|
||||
case s.rawStdout:
|
||||
// MSBuild: skip all filtering/toolrelay, inherit stdio directly.
|
||||
// MSBuild: skip all filtering/toolrelay, inherit stdio directly, and
|
||||
// add the extra environment MSBuild's own toolset/SDK-detection
|
||||
// props need on top of the generic INCLUDE/LIB/WINEPATH.
|
||||
cmd := exec.Command(wineBin, append([]string{toolExePath}, rewritten...)...)
|
||||
cmd.Env = buildEnv(paths)
|
||||
env := buildEnv(paths)
|
||||
for k, v := range msbuildEnv(cfg, paths) {
|
||||
env = append(env, k+"="+v)
|
||||
}
|
||||
cmd.Env = env
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
Reference in New Issue
Block a user