mirror of
https://github.com/Cheviiot/Vintner.git
synced 2026-08-03 15:57:24 +00:00
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.
47 lines
1.4 KiB
Go
47 lines
1.4 KiB
Go
// Package wineenv computes the environment (INCLUDE/LIB/WINEPATH/...) needed
|
|
// to run a Wine-hosted MSVC tool.
|
|
package wineenv
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// ConfigFileName is the per-architecture config dropped next to the tool
|
|
// symlinks by `msvc-go-wine install`.
|
|
const ConfigFileName = "env.json"
|
|
|
|
// Config is the per-architecture info generated at install time.
|
|
type Config struct {
|
|
Arch string `json:"arch"` // x86, x64, arm, arm64 (target arch)
|
|
Host string `json:"host"` // x64 or arm64 (Host<Host> bin dir suffix)
|
|
DotnetHost string `json:"dotnet_host"` // amd64 or arm64 (.NET tool host dir suffix)
|
|
MSVCVer string `json:"msvc_ver"`
|
|
SDKVer string `json:"sdk_ver"`
|
|
}
|
|
|
|
// Load reads env.json from dir (the directory the running binary was
|
|
// invoked from, i.e. <dest>/bin/<arch>).
|
|
func Load(dir string) (*Config, error) {
|
|
data, err := os.ReadFile(filepath.Join(dir, ConfigFileName))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("reading %s: %w", ConfigFileName, err)
|
|
}
|
|
var c Config
|
|
if err := json.Unmarshal(data, &c); err != nil {
|
|
return nil, fmt.Errorf("parsing %s: %w", ConfigFileName, err)
|
|
}
|
|
return &c, nil
|
|
}
|
|
|
|
// Save writes env.json into dir.
|
|
func (c *Config) Save(dir string) error {
|
|
data, err := json.MarshalIndent(c, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return os.WriteFile(filepath.Join(dir, ConfigFileName), data, 0o644)
|
|
}
|