mirror of
https://github.com/Cheviiot/Vintner.git
synced 2026-08-03 15:57:24 +00:00
Initial implementation of msvc-go-wine
A single-binary Go tool for cross compiling with the real MSVC toolchain on Linux via Wine. Behaves as cl/link/lib/rc/midl/mt/dumpbin/msbuild/ nmake/ml/ml64/armasm/armasm64/cmd/findstr depending on the name it's invoked as, plus download/install/env/version management subcommands. - download: fetches the MSVC/WinSDK installer manifest, resolves package selection and dependencies, downloads and verifies payloads, unpacks VSIX/MSI packages, and applies a handful of compatibility patches so VsDevCmd.bat and MSBuild's SDK detection work without a Windows Registry (which doesn't exist under Wine). - install: locates the installed toolchain/SDK versions, normalizes header/library name casing, lays out per-architecture tool symlinks with an env.json config each, and compiles a small native launcher (toolrelay.exe) that lets mt.exe's CMake-compatibility exit code survive Wine's own exit-code truncation. - The wrapper runtime rewrites absolute unix paths in tool arguments into Wine's z:\... form, runs the real .exe under wine, and rewrites the tool's output back to plain unix paths. Verified end-to-end against a real MSVC/WinSDK download: cl, link, mt and the resulting hello.exe all work under Wine, including through the toolrelay.exe relay path and with paths containing non-ASCII characters. Offline unit tests cover the wrapper's path-rewrite/output-filter logic, install-time header lowercasing, and download package-selection/ dependency-resolution.
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
msvc-go-wine: skip VsDevCmd's telemetry upload.
|
||||
|
||||
There's no telemetry endpoint reachable (or wanted) under Wine. Rather than
|
||||
touching the conditional logic below, just set the opt-out switch the
|
||||
script already checks for on its own.
|
||||
|
||||
diff --git a/Common7/Tools/VsDevCmd.bat b/Common7/Tools/VsDevCmd.bat
|
||||
index f925e95..f3710ad 100644
|
||||
--- a/Common7/Tools/VsDevCmd.bat
|
||||
+++ b/Common7/Tools/VsDevCmd.bat
|
||||
@@ -247,6 +247,7 @@ exit /B 0
|
||||
:end
|
||||
|
||||
@REM Send Telemetry if user's VS is opted-in
|
||||
+set "VSCMD_SKIP_SENDTELEMETRY=1"
|
||||
if "%VSCMD_SKIP_SENDTELEMETRY%"=="" (
|
||||
if "%VSCMD_DEBUG%" NEQ "" (
|
||||
@echo [DEBUG:%~nx0] Sending telemetry
|
||||
@@ -0,0 +1,20 @@
|
||||
msvc-go-wine: always record the starting directory.
|
||||
|
||||
vsdevcmd_start.bat only saved __VSCMD_CURRENT_DIR when the caller passed
|
||||
-startdir=none, which doesn't hold up under Wine's cmd.exe (see
|
||||
https://bugs.winehq.org/show_bug.cgi?id=57137). Just save it
|
||||
unconditionally instead of gating on the flag.
|
||||
|
||||
diff --git a/Common7/Tools/vsdevcmd/core/vsdevcmd_start.bat b/Common7/Tools/vsdevcmd/core/vsdevcmd_start.bat
|
||||
index 21caae9..fc18228 100644
|
||||
--- a/Common7/Tools/vsdevcmd/core/vsdevcmd_start.bat
|
||||
+++ b/Common7/Tools/vsdevcmd/core/vsdevcmd_start.bat
|
||||
@@ -8,7 +8,7 @@ call "%~dp0parse_cmd.bat" %*
|
||||
if "%ERRORLEVEL%" NEQ "0" set /A __vscmd_vsdevcmd_errcount=__vscmd_vsdevcmd_errcount+1
|
||||
|
||||
@REM Save the current directory, if -startdir=none was specified by the user.
|
||||
-if /I "%VSCMD_ARG_STARTDIR%" == "none" set "__VSCMD_CURRENT_DIR=%CD%"
|
||||
+set "__VSCMD_CURRENT_DIR=%CD%"
|
||||
|
||||
if "%VSCMD_DEBUG%" GEQ "2" (
|
||||
@echo [DEBUG:%~n0] Parsing results...
|
||||
@@ -0,0 +1,66 @@
|
||||
msvc-go-wine: find the Windows SDK/UCRT dirs on disk before trying the registry.
|
||||
|
||||
winsdk.bat locates the Windows 10/11 SDK and Universal CRT SDK by querying
|
||||
the Windows Registry, which doesn't have real SDK installation entries
|
||||
under Wine. msvc-wine's own install layout always puts the SDK directly
|
||||
under "%VSINSTALLDIR%Windows Kits\10", so check that location first and
|
||||
only fall back to the registry-based lookups when it's not there.
|
||||
|
||||
diff --git a/Common7/Tools/vsdevcmd/core/winsdk.bat b/Common7/Tools/vsdevcmd/core/winsdk.bat
|
||||
index af09494..c303775 100644
|
||||
--- a/Common7/Tools/vsdevcmd/core/winsdk.bat
|
||||
+++ b/Common7/Tools/vsdevcmd/core/winsdk.bat
|
||||
@@ -64,6 +64,11 @@ exit /B 0
|
||||
|
||||
if "%VSCMD_DEBUG%" GEQ "3" goto :GetWin10SdkDirVerbose
|
||||
|
||||
+if exist "%VSINSTALLDIR%Windows Kits\10\include\" (
|
||||
+ SET "WindowsSdkDir=%VSINSTALLDIR%Windows Kits\10\"
|
||||
+ exit /B 0
|
||||
+)
|
||||
+
|
||||
call :GetWin10SdkDirHelper HKLM\SOFTWARE\Wow6432Node > nul 2>&1
|
||||
if errorlevel 1 call :GetWin10SdkDirHelper HKCU\SOFTWARE\Wow6432Node > nul 2>&1
|
||||
if errorlevel 1 call :GetWin10SdkDirHelper HKLM\SOFTWARE > nul 2>&1
|
||||
@@ -73,6 +78,11 @@ exit /B 0
|
||||
|
||||
:GetWin10SdkDirVerbose
|
||||
|
||||
+if exist "%VSINSTALLDIR%Windows Kits\10\include\" (
|
||||
+ SET "WindowsSdkDir=%VSINSTALLDIR%Windows Kits\10\"
|
||||
+ exit /B 0
|
||||
+)
|
||||
+
|
||||
call :GetWin10SdkDirHelper HKLM\SOFTWARE\Wow6432Node
|
||||
if errorlevel 1 call :GetWin10SdkDirHelper HKCU\SOFTWARE\Wow6432Node
|
||||
if errorlevel 1 call :GetWin10SdkDirHelper HKLM\SOFTWARE
|
||||
@@ -231,6 +241,14 @@ set UniversalCRTSdkDir=
|
||||
|
||||
if "%VSCMD_DEBUG%" GEQ "3" goto :GetUniversalCRTSdkDirVerbose
|
||||
|
||||
+if exist "%WindowsSdkDir%Lib\%WindowsSDKVersion%ucrt\" (
|
||||
+ SET "UniversalCRTSdkDir=%WindowsSdkDir%"
|
||||
+ exit /B 0
|
||||
+) else if exist "%VSINSTALLDIR%Windows Kits\10\Lib\" (
|
||||
+ SET "UniversalCRTSdkDir=%VSINSTALLDIR%Windows Kits\10\"
|
||||
+ exit /B 0
|
||||
+)
|
||||
+
|
||||
call :GetUniversalCRTSdkDirHelper HKLM\SOFTWARE\Wow6432Node > nul 2>&1
|
||||
if errorlevel 1 call :GetUniversalCRTSdkDirHelper HKCU\SOFTWARE\Wow6432Node > nul 2>&1
|
||||
if errorlevel 1 call :GetUniversalCRTSdkDirHelper HKLM\SOFTWARE > nul 2>&1
|
||||
@@ -240,6 +258,14 @@ exit /B 0
|
||||
|
||||
:GetUniversalCRTSdkDirVerbose
|
||||
|
||||
+if exist "%WindowsSdkDir%Lib\%WindowsSDKVersion%ucrt\" (
|
||||
+ SET "UniversalCRTSdkDir=%WindowsSdkDir%"
|
||||
+ exit /B 0
|
||||
+) else if exist "%VSINSTALLDIR%Windows Kits\10\Lib\" (
|
||||
+ SET "UniversalCRTSdkDir=%VSINSTALLDIR%Windows Kits\10\"
|
||||
+ exit /B 0
|
||||
+)
|
||||
+
|
||||
call :GetUniversalCRTSdkDirHelper HKLM\SOFTWARE\Wow6432Node
|
||||
if errorlevel 1 call :GetUniversalCRTSdkDirHelper HKCU\SOFTWARE\Wow6432Node
|
||||
if errorlevel 1 call :GetUniversalCRTSdkDirHelper HKLM\SOFTWARE
|
||||
@@ -0,0 +1,19 @@
|
||||
msvc-go-wine: don't hard-fail devcmd setup when ConnectionManagerExe is missing.
|
||||
|
||||
Not every MSVC/WinSDK download selection includes the Linux
|
||||
ConnectionManagerExe component; a missing optional component shouldn't
|
||||
abort the whole Developer Command Prompt setup.
|
||||
|
||||
diff --git a/Common7/Tools/vsdevcmd/ext/ConnectionManagerExe.bat b/Common7/Tools/vsdevcmd/ext/ConnectionManagerExe.bat
|
||||
index 871b9af..f069a25 100644
|
||||
--- a/Common7/Tools/vsdevcmd/ext/ConnectionManagerExe.bat
|
||||
+++ b/Common7/Tools/vsdevcmd/ext/ConnectionManagerExe.bat
|
||||
@@ -10,7 +10,7 @@ set "PATH=%PATH%;%VSINSTALLDIR%Common7\IDE\VC\Linux\bin\ConnectionManagerExe"
|
||||
goto :end
|
||||
|
||||
:error_setting_path
|
||||
-exit /B 1
|
||||
+exit /B 0
|
||||
|
||||
goto :end
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
msvc-go-wine: don't hard-fail devcmd setup when the bundled CMake/Ninja is missing.
|
||||
|
||||
Same reasoning as the ConnectionManagerExe fix: a missing optional
|
||||
component shouldn't abort the whole Developer Command Prompt setup.
|
||||
|
||||
diff --git a/Common7/Tools/vsdevcmd/ext/cmake.bat b/Common7/Tools/vsdevcmd/ext/cmake.bat
|
||||
index d9a1088..584f141 100644
|
||||
--- a/Common7/Tools/vsdevcmd/ext/cmake.bat
|
||||
+++ b/Common7/Tools/vsdevcmd/ext/cmake.bat
|
||||
@@ -10,7 +10,7 @@ set "PATH=%PATH%;%VSINSTALLDIR%Common7\IDE\CommonExtensions\Microsoft\CMake\CMak
|
||||
goto :end
|
||||
|
||||
:error_setting_path
|
||||
-exit /B 1
|
||||
+exit /B 0
|
||||
|
||||
goto :end
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
msvc-go-wine: make MSBuild resolve the Windows SDK / UCRT / preferred tool
|
||||
architecture from the VS install layout directly, since there's no
|
||||
Windows Registry under Wine for the stock .props files to query.
|
||||
|
||||
Populates MsvcGoWine_ExtraSdkRoots, which
|
||||
Microsoft.Cpp.WindowsSDK.props.patch (see the assets/patches directory)
|
||||
passes into GetLatestSDKTargetPlatformVersion as an extra search root.
|
||||
-->
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(WindowsSdkDir_10)' == '' and (
|
||||
'$(WindowsTargetPlatformVersion)' == '' or
|
||||
'$(WindowsTargetPlatformVersion)' == '10.0' or
|
||||
Exists('$(VSInstallRoot)\Windows Kits\10\Include\$(WindowsTargetPlatformVersion)\shared\sdkddkver.h'))">
|
||||
<MsvcGoWine_ExtraSdkRoots>$(VSInstallRoot)</MsvcGoWine_ExtraSdkRoots>
|
||||
<WindowsSdkDir_10>$(VSInstallRoot)\Windows Kits\10\</WindowsSdkDir_10>
|
||||
<UniversalCRTSdkDir_10 Condition="'$(UniversalCRTSdkDir_10)' == ''">$(WindowsSdkDir_10)</UniversalCRTSdkDir_10>
|
||||
<UCRTContentRoot Condition="'$(UCRTContentRoot)' == ''">$(WindowsSdkDir_10)</UCRTContentRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture Condition="'$(PROCESSOR_ARCHITECTURE)' == 'AMD64'">x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,20 @@
|
||||
msvc-go-wine: let MSBuild find the Windows SDK without the registry.
|
||||
|
||||
GetLatestSDKTargetPlatformVersion normally resolves the SDK via the
|
||||
registry, which has nothing to find under Wine. Pass it an extra list of
|
||||
roots (populated by msvc-go-wine.props, see the ImportBefore directory next
|
||||
to this file) so it can also look directly under the VS install root.
|
||||
|
||||
diff --git a/MSBuild/Microsoft/VC/v180/Microsoft.Cpp.WindowsSDK.props b/MSBuild/Microsoft/VC/v180/Microsoft.Cpp.WindowsSDK.props
|
||||
index 5003a04..2a785a4 100644
|
||||
--- a/MSBuild/Microsoft/VC/v180/Microsoft.Cpp.WindowsSDK.props
|
||||
+++ b/MSBuild/Microsoft/VC/v180/Microsoft.Cpp.WindowsSDK.props
|
||||
@@ -110,7 +110,7 @@ Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
<SDKVersion Condition="'$(SDKVersion)' == ''">10.0</SDKVersion>
|
||||
<SDKDisplayName Condition="'$(SDKDisplayName)' == ''">Windows 10</SDKDisplayName>
|
||||
|
||||
- <_LatestWindowsTargetPlatformVersion>$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion($(SDKIdentifier), $(SDKVersion)))</_LatestWindowsTargetPlatformVersion>
|
||||
+ <_LatestWindowsTargetPlatformVersion>$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion($(SDKIdentifier), $(SDKVersion), $(MsvcGoWine_ExtraSdkRoots.Split(';'))))</_LatestWindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == '' and '$(_LatestWindowsTargetPlatformVersion)' != ''">10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
Reference in New Issue
Block a user