mirror of
https://github.com/Cheviiot/Vintner.git
synced 2026-08-04 00:07: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,39 @@
|
||||
package wrapper
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// clPostProcess mirrors cl's post-run fixup for `/P /Fi<file>` (preprocess-
|
||||
// to-file): the generated file still has CRLF endings and z:-prefixed
|
||||
// #line directives, so run it through the same line-directive rewrite used
|
||||
// for stdout.
|
||||
func clPostProcess(origArgs []string) {
|
||||
var hasP bool
|
||||
var fiFile string
|
||||
for _, a := range origArgs {
|
||||
switch {
|
||||
case a == "-P" || a == "/P":
|
||||
hasP = true
|
||||
case strings.HasPrefix(a, "-Fi") || strings.HasPrefix(a, "/Fi"):
|
||||
fiFile = a[3:]
|
||||
}
|
||||
}
|
||||
if !hasP || fiFile == "" {
|
||||
return
|
||||
}
|
||||
data, err := os.ReadFile(fiFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
lines := strings.Split(string(data), "\n")
|
||||
for i, line := range lines {
|
||||
line = stripCR(line)
|
||||
if reLineDirective.MatchString(line) {
|
||||
line = strings.ReplaceAll(stripFirstZDrive(line), `\\`, `/`)
|
||||
}
|
||||
lines[i] = line
|
||||
}
|
||||
_ = os.WriteFile(fiFile, []byte(strings.Join(lines, "\n")), 0o644)
|
||||
}
|
||||
Reference in New Issue
Block a user