mirror of
https://github.com/Cheviiot/Vintner.git
synced 2026-08-03 15:57:24 +00:00
Rewrite README prose: cut repeated self-assurance, tighten sentences
The old version restated "independently implemented"/"original to this project" in three separate places, which reads as protesting too much rather than as confidence. Credits the msvc-wine inspiration once, plainly, and drops the rest. Also split several overlong comma-chained sentences, fixed the WDK section (a sentence was cut in half by its own code block), and cleaned up the license paragraph's phrasing. Content is unchanged - verified the two claims most worth double-checking (the clang-cl/lld-link path, and that `stplr install nivora/vintner` actually resolves) rather than just rewording them.
This commit is contained in:
@@ -4,17 +4,16 @@
|
|||||||
[](https://github.com/Cheviiot/vintner/releases/latest)
|
[](https://github.com/Cheviiot/vintner/releases/latest)
|
||||||
[](LICENSE.txt)
|
[](LICENSE.txt)
|
||||||
|
|
||||||
**vintner** cross compiles with the real MSVC toolchain on Linux, using Wine —
|
vintner cross-compiles with the real MSVC toolchain on Linux, using Wine.
|
||||||
a single Go binary, inspired by [mstorsjo/msvc-wine](https://github.com/mstorsjo/msvc-wine)'s
|
One Go binary drops in as `cl`, `link`, `lib`, `rc`, `midl`, `mc`, `mt`,
|
||||||
approach (download the actual MSVC/WinSDK, wrap the compiler under Wine) and
|
`dumpbin`, `msbuild`, `nmake`, `ml`, `ml64`, `armasm`, `armasm64`, plus
|
||||||
implemented independently.
|
`cmd`/`findstr` shims, so once installed you invoke the real Microsoft
|
||||||
|
tools exactly like on Windows. It handles full MSBuild projects, and with
|
||||||
Once installed, you invoke the real Microsoft toolchain exactly like on
|
|
||||||
Windows: `cl`, `link`, `lib`, `rc`, `midl`, `mc`, `mt`, `dumpbin`, `msbuild`,
|
|
||||||
`nmake`, `ml`, `ml64`, `armasm`, `armasm64`, plus trivial `cmd`/`findstr`
|
|
||||||
shims, all work from your `PATH` — including full MSBuild projects and, with
|
|
||||||
`--with-wdk`, real KMDF/UMDF Windows drivers.
|
`--with-wdk`, real KMDF/UMDF Windows drivers.
|
||||||
|
|
||||||
|
Inspired by [mstorsjo/msvc-wine](https://github.com/mstorsjo/msvc-wine)'s
|
||||||
|
approach: download the real MSVC/WinSDK, wrap the compiler under Wine.
|
||||||
|
|
||||||
## Contents
|
## Contents
|
||||||
|
|
||||||
- [How it works](#how-it-works)
|
- [How it works](#how-it-works)
|
||||||
@@ -25,35 +24,37 @@ shims, all work from your `PATH` — including full MSBuild projects and, with
|
|||||||
- [Language](#language)
|
- [Language](#language)
|
||||||
- [Shell completion](#shell-completion)
|
- [Shell completion](#shell-completion)
|
||||||
- [Using clang-cl/lld-link instead of Wine](#using-clang-cllld-link-instead-of-wine)
|
- [Using clang-cl/lld-link instead of Wine](#using-clang-cllld-link-instead-of-wine)
|
||||||
|
- [toolrelay.exe](#toolrelayexe)
|
||||||
|
- [Compatibility patches](#compatibility-patches)
|
||||||
- [Building from source](#building-from-source)
|
- [Building from source](#building-from-source)
|
||||||
- [How the pieces fit together](#how-the-pieces-fit-together)
|
|
||||||
- [License](#license)
|
- [License](#license)
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
`vintner` is one Go binary that behaves differently depending on the name
|
vintner is a multi-call binary, like busybox: it behaves differently
|
||||||
it's invoked as (a "multi-call binary", like busybox):
|
depending on the name it's invoked as.
|
||||||
|
|
||||||
- Invoked as `cl`, `link`, `lib`, ... → it loads a small per-architecture
|
- As `cl`, `link`, `lib`, and the rest: it loads a per-architecture
|
||||||
`env.json`, builds the `INCLUDE`/`LIB`/`WINEPATH` environment Wine needs,
|
`env.json`, sets `INCLUDE`/`LIB`/`WINEPATH`, and rewrites absolute Unix
|
||||||
rewrites absolute unix paths in the arguments into Wine's `z:\...` form
|
paths in the arguments to Wine's `z:\...` form (Wine and cl.exe
|
||||||
(working around [a Wine/cl.exe include-path bug](https://bugs.winehq.org/show_bug.cgi?id=55200)),
|
otherwise mishandle relative includes — see
|
||||||
runs the real `.exe` under `wine`/`wine64`, and rewrites the tool's output
|
[winehq bug 55200](https://bugs.winehq.org/show_bug.cgi?id=55200)). It
|
||||||
back from `z:\...` paths to plain unix paths so your build system's error
|
then runs the real `.exe` under `wine`/`wine64`, and rewrites `z:\...`
|
||||||
|
paths back to Unix paths in the output, so your build system's error
|
||||||
parsing keeps working.
|
parsing keeps working.
|
||||||
- Invoked as `vintner` → it exposes the `download`, `install`, `env` and
|
- As `vintner`: it exposes the `download`, `install`, `env`, `version`
|
||||||
`version` management subcommands described below (short aliases: `dl`,
|
and `completion` subcommands below (short aliases: `dl`, `i`, `e`, `v`;
|
||||||
`i`, `e`, `v`; `help`/`h` prints usage).
|
`help`/`h` prints usage).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
**On ALT Linux, via [Nivora](https://github.com/Cheviiot/Nivora):**
|
On ALT Linux, via [Nivora](https://github.com/Cheviiot/Nivora):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
stplr install nivora/vintner
|
stplr install nivora/vintner
|
||||||
```
|
```
|
||||||
|
|
||||||
**Prebuilt binary**, from the [latest release](https://github.com/Cheviiot/vintner/releases/latest):
|
Prebuilt binary, from the [latest release](https://github.com/Cheviiot/vintner/releases/latest):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fLo vintner "https://github.com/Cheviiot/vintner/releases/latest/download/vintner-linux-$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')"
|
curl -fLo vintner "https://github.com/Cheviiot/vintner/releases/latest/download/vintner-linux-$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')"
|
||||||
@@ -61,18 +62,18 @@ chmod +x vintner
|
|||||||
sudo install vintner /usr/local/bin/vintner
|
sudo install vintner /usr/local/bin/vintner
|
||||||
```
|
```
|
||||||
|
|
||||||
**From source** — see [Building from source](#building-from-source).
|
From source: see [Building from source](#building-from-source).
|
||||||
|
|
||||||
Either way, `wine`/`wine64`, `msitools` (for `msiextract`) and `git` need to
|
Either way, `wine`/`wine64`, `msitools` (for `msiextract`) and `git` need
|
||||||
be on `PATH` at run time (see [Prerequisites](#prerequisites) below); Nivora
|
to be on `PATH` at run time. Nivora installs pull these in automatically
|
||||||
installs already pull these in as package dependencies.
|
as package dependencies.
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- `wine` (or `wine64`) — runs the real `cl.exe`/`link.exe`/etc.
|
- `wine` (or `wine64`) — runs the real `cl.exe`/`link.exe`/etc.
|
||||||
- `msitools` (`msiextract`) — unpacks the `.msi` payloads MSVC/WinSDK ship as.
|
- `msitools` (`msiextract`) — unpacks the `.msi` payloads MSVC/WinSDK ship as.
|
||||||
- `git` — used to apply the small compatibility patches bundled with
|
- `git` — applies the compatibility patches bundled with `download` (see
|
||||||
`download` (see [Compatibility patches](#compatibility-patches) below).
|
[Compatibility patches](#compatibility-patches)).
|
||||||
|
|
||||||
On ALT Linux:
|
On ALT Linux:
|
||||||
|
|
||||||
@@ -83,9 +84,9 @@ pkcon install wine msitools git
|
|||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Download and unpack MSVC + Windows SDK into ~/.vintner (requires
|
# 1. Download and unpack MSVC + Windows SDK into ~/.vintner (accepts
|
||||||
# accepting Microsoft's Visual Studio Build Tools license). Pass
|
# Microsoft's Visual Studio Build Tools license). Pass --dest <dir>
|
||||||
# --dest <dir> for a different location.
|
# for a different location.
|
||||||
vintner download --accept-license
|
vintner download --accept-license
|
||||||
|
|
||||||
# 2. Wire up the tool wrappers
|
# 2. Wire up the tool wrappers
|
||||||
@@ -119,38 +120,40 @@ vintner completion bash|zsh print a shell
|
|||||||
`vintner download -h` for the full list with descriptions.
|
`vintner download -h` for the full list with descriptions.
|
||||||
|
|
||||||
`--list-workloads`/`--list-components` print every workload/component id
|
`--list-workloads`/`--list-components` print every workload/component id
|
||||||
(with its human-readable title) available in the fetched manifest and exit
|
and its human-readable title from the fetched manifest, then exit
|
||||||
without downloading anything — useful for discovering what to pass as a bare
|
without downloading anything. Useful for finding what to pass as a bare
|
||||||
package id or via `--with-*`. `--print-deps-tree` prints the dependency tree
|
package id or through `--with-*`. `--print-deps-tree` prints the
|
||||||
of whatever would actually be selected (honoring every other flag), also
|
dependency tree of whatever would actually be selected — honoring every
|
||||||
without downloading.
|
other flag — without downloading anything.
|
||||||
|
|
||||||
## Building drivers (WDK)
|
## Building drivers (WDK)
|
||||||
|
|
||||||
|
`--with-wdk` also fetches the Windows Driver Kit: headers, import libs,
|
||||||
|
and the MSBuild `WindowsKernelModeDriver10.0`/`WindowsUserModeDriver10.0`
|
||||||
|
PlatformToolsets.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
vintner download --accept-license --with-wdk
|
vintner download --accept-license --with-wdk
|
||||||
```
|
```
|
||||||
|
|
||||||
additionally fetches the Windows Driver Kit (headers, import libs, and the
|
With it, `msbuild` builds real KMDF/UMDF drivers — compiling, linking,
|
||||||
MSBuild `WindowsKernelModeDriver10.0`/`WindowsUserModeDriver10.0`
|
INF stamping, and the `Inf2Cat` signability check (`SignMode=off`) all
|
||||||
PlatformToolsets) so `msbuild` can build real KMDF/UMDF drivers —
|
work under Wine. Tested against a real sample driver from
|
||||||
compiling, linking, INF stamping and the `Inf2Cat` signability check (with
|
|
||||||
`SignMode=off`) all work under Wine. Verified end-to-end against a real
|
|
||||||
sample driver from
|
|
||||||
[microsoft/Windows-driver-samples](https://github.com/microsoft/Windows-driver-samples).
|
[microsoft/Windows-driver-samples](https://github.com/microsoft/Windows-driver-samples).
|
||||||
Only x64 and arm64 targets have a WDK package upstream (no x86/arm).
|
Only x64 and arm64 targets have a WDK package upstream; there's no x86 or
|
||||||
|
arm one.
|
||||||
|
|
||||||
## Language
|
## Language
|
||||||
|
|
||||||
CLI messages (usage text, progress lines, prompts) default to English. Set
|
CLI text (usage, progress lines, prompts) defaults to English. Set
|
||||||
`VINTNER_LANG=ru` (or have a `ru`-prefixed `LC_ALL`/`LC_MESSAGES`/`LANG`,
|
`VINTNER_LANG=ru` (or a `ru`-prefixed `LC_ALL`/`LC_MESSAGES`/`LANG`, e.g.
|
||||||
e.g. `ru_RU.UTF-8`) for Russian:
|
`ru_RU.UTF-8`) for Russian:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
VINTNER_LANG=ru vintner help
|
VINTNER_LANG=ru vintner help
|
||||||
```
|
```
|
||||||
|
|
||||||
Deeper error text bubbled up from internal packages stays in English.
|
Error text from internal packages stays in English regardless.
|
||||||
|
|
||||||
## Shell completion
|
## Shell completion
|
||||||
|
|
||||||
@@ -159,13 +162,13 @@ source <(vintner completion bash) # or add to ~/.bashrc
|
|||||||
source <(vintner completion zsh) # or add to ~/.zshrc
|
source <(vintner completion zsh) # or add to ~/.zshrc
|
||||||
```
|
```
|
||||||
|
|
||||||
Completes subcommands (including the short aliases), `download`'s flags,
|
Completes subcommands, including the short aliases, `download`'s flags,
|
||||||
and directory arguments for `install`/`env --bin`.
|
and directory arguments for `install`/`env --bin`.
|
||||||
|
|
||||||
## Using clang-cl/lld-link instead of Wine
|
## Using clang-cl/lld-link instead of Wine
|
||||||
|
|
||||||
You don't need Wine at all if you drive the (nonredistributable) MSVC/WinSDK
|
The MSVC/WinSDK headers and libraries work directly with Clang/LLD in
|
||||||
headers and libraries with Clang/LLD in MSVC-compatible mode:
|
MSVC-compatible mode. No Wine needed:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
eval "$(vintner env --bin ~/.vintner/bin/x64)"
|
eval "$(vintner env --bin ~/.vintner/bin/x64)"
|
||||||
@@ -173,55 +176,44 @@ clang-cl -c hello.c
|
|||||||
lld-link hello.obj -out:hello.exe
|
lld-link hello.obj -out:hello.exe
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## toolrelay.exe
|
||||||
|
|
||||||
|
`install` compiles `assets/vendor/toolrelay.cpp`, a small native Windows
|
||||||
|
launcher, with the freshly-installed host-arch `cl.exe`. This is
|
||||||
|
best-effort: if `wine` isn't available yet, or the compile fails, install
|
||||||
|
still succeeds, and tool invocations just skip it. When present, every
|
||||||
|
non-MSBuild tool call is routed through it via two named FIFOs.
|
||||||
|
|
||||||
|
That's what lets `mt.exe`'s CMake-compatibility exit code
|
||||||
|
(`0x41020001` → `0xbb`) survive Wine's own exit-code truncation: a native
|
||||||
|
Windows process can read the real 32-bit exit code via
|
||||||
|
`GetExitCodeProcess()` before Wine collapses it to a single byte on the
|
||||||
|
way back to Unix.
|
||||||
|
|
||||||
|
## Compatibility patches
|
||||||
|
|
||||||
|
`download` applies a few small patches (`assets/patches`) to the
|
||||||
|
downloaded MSVC/WinSDK tree, so `VsDevCmd.bat` and MSBuild's
|
||||||
|
SDK-detection props work without a Windows Registry, which doesn't exist
|
||||||
|
under Wine. They look up the SDK directly under the VS install root
|
||||||
|
instead of querying the registry, skip telemetry, and don't fail devcmd
|
||||||
|
setup when an optional component (ConnectionManagerExe, bundled
|
||||||
|
CMake/Ninja) is missing.
|
||||||
|
|
||||||
## Building from source
|
## Building from source
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go build -o vintner ./cmd/vintner
|
go build -o vintner ./cmd/vintner
|
||||||
```
|
|
||||||
|
|
||||||
Go 1.23+ is all you need to build it; `wine`/`msitools` are only needed at
|
|
||||||
run time (`install`/tool invocation and `download` respectively).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go vet ./...
|
go vet ./...
|
||||||
go test ./...
|
go test ./...
|
||||||
```
|
```
|
||||||
|
|
||||||
## How the pieces fit together
|
Go 1.23+ builds it. `wine`/`msitools` are only needed at run time, for
|
||||||
|
`install`/tool invocation and `download` respectively.
|
||||||
<details>
|
|
||||||
<summary><strong>toolrelay.exe</strong> — surviving Wine's exit-code truncation</summary>
|
|
||||||
|
|
||||||
`install` compiles `assets/vendor/toolrelay.cpp` (a small native Windows
|
|
||||||
launcher, original to this project) with the freshly-installed host-arch
|
|
||||||
`cl.exe` (best-effort: if `wine` isn't present yet, or the compile fails,
|
|
||||||
install still succeeds and the wrapper runtime just falls back to invoking
|
|
||||||
tools directly through wine). When present, every non-MSBuild tool
|
|
||||||
invocation is routed through it via two named FIFOs. This is what lets
|
|
||||||
`mt.exe`'s CMake-compatibility exit-code translation (`0x41020001` → `0xbb`)
|
|
||||||
survive Wine's own exit-code truncation: only a native Windows process
|
|
||||||
observing the untranslated code via `GetExitCodeProcess()` can catch it
|
|
||||||
before Wine marshals the process exit back to Unix and drops everything but
|
|
||||||
the low byte.
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><strong>Compatibility patches</strong> — making MSBuild work without a Windows Registry</summary>
|
|
||||||
|
|
||||||
`download` applies a handful of small patches (`assets/patches`) to the
|
|
||||||
downloaded MSVC/WinSDK tree — independently written for this project — that
|
|
||||||
make `VsDevCmd.bat` and MSBuild's SDK-detection props work without a
|
|
||||||
Windows Registry (which doesn't exist under Wine): they check the SDK
|
|
||||||
directly under the VS install root instead of querying the registry, skip
|
|
||||||
telemetry, and don't hard-fail devcmd setup when an optional component
|
|
||||||
(ConnectionManagerExe, bundled CMake/Ninja) wasn't downloaded.
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT, see [LICENSE.txt](LICENSE.txt) — covers vintner's own source only. The
|
MIT (see [LICENSE.txt](LICENSE.txt)) for vintner's own source. The MSVC
|
||||||
MSVC Build Tools / Windows SDK / WDK that `download` fetches remain governed
|
Build Tools, Windows SDK, and WDK that `download` fetches stay under
|
||||||
by Microsoft's own license (accepted via `--accept-license`), same as with
|
Microsoft's own license (accepted via `--accept-license`), same as with
|
||||||
any other way of obtaining them.
|
any other way of obtaining them.
|
||||||
|
|||||||
Reference in New Issue
Block a user