diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index e0b2955..40621a0 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -48,17 +48,17 @@ jobs:
tag="${{ inputs.tag || github.ref_name }}"
version="${tag#v}"
go build -trimpath -ldflags="-s -w -X main.version=${version}" \
- -o "msvc-go-wine-linux-${{ matrix.goarch }}" ./cmd/msvc-go-wine
+ -o "vintner-linux-${{ matrix.goarch }}" ./cmd/vintner
- name: Verify it runs
if: matrix.goarch == 'amd64'
- run: ./msvc-go-wine-linux-amd64 version
+ run: ./vintner-linux-amd64 version
- name: Upload artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
- name: msvc-go-wine-linux-${{ matrix.goarch }}
- path: msvc-go-wine-linux-${{ matrix.goarch }}
+ name: vintner-linux-${{ matrix.goarch }}
+ path: vintner-linux-${{ matrix.goarch }}
if-no-files-found: error
retention-days: 14
@@ -71,11 +71,11 @@ jobs:
- name: Download all architectures
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
- pattern: msvc-go-wine-linux-*
+ pattern: vintner-linux-*
merge-multiple: true
- name: Checksums
- run: sha256sum msvc-go-wine-linux-* > SHA256SUMS
+ run: sha256sum vintner-linux-* > SHA256SUMS
- name: Create or update GitHub Release
env:
@@ -85,10 +85,10 @@ jobs:
tag="${{ inputs.tag || github.ref_name }}"
if ! gh release view "$tag" >/dev/null 2>&1; then
gh release create "$tag" \
- --title "msvc-go-wine $tag" \
+ --title "vintner $tag" \
--notes "Linux amd64/arm64 binaries built by CI from this tag. See README.md for install instructions."
fi
gh release upload "$tag" \
- msvc-go-wine-linux-* \
+ vintner-linux-* \
SHA256SUMS \
--clobber
diff --git a/.gitignore b/.gitignore
index 18451b6..0dab7c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
-/msvc-go-wine
+/vintner
*.test
.claude/
diff --git a/LICENSE.txt b/LICENSE.txt
index d8ad75f..334c752 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -20,6 +20,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-This license covers msvc-go-wine's own source code. It does not cover the
-Microsoft Visual C++ Build Tools / Windows SDK that `msvc-go-wine download`
+This license covers vintner's own source code. It does not cover the
+Microsoft Visual C++ Build Tools / Windows SDK that `vintner download`
fetches and unpacks, which remain governed by Microsoft's own license terms.
diff --git a/README.md b/README.md
index 3b24526..670ce7e 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# msvc-go-wine
+# vintner
Cross compile with MSVC on Linux, using Wine — a single-binary Go tool
inspired by [mstorsjo/msvc-wine](https://github.com/mstorsjo/msvc-wine)'s
@@ -6,13 +6,14 @@ approach (download the real MSVC/WinSDK, wrap the compiler under Wine),
implemented independently.
Once installed, you invoke the real Microsoft toolchain exactly like on
-Windows: `cl`, `link`, `lib`, `rc`, `midl`, `mt`, `dumpbin`, `msbuild`,
-`nmake`, `ml`, `ml64`, `armasm`, `armasm64` all just work from your `PATH`.
+Windows: `cl`, `link`, `lib`, `rc`, `midl`, `mc`, `mt`, `dumpbin`, `msbuild`,
+`nmake`, `ml`, `ml64`, `armasm`, `armasm64`, plus trivial `cmd`/`findstr`
+shims, all just work from your `PATH`.
## How it works
-`msvc-go-wine` is one Go binary that behaves differently depending on the
-name it's invoked as (a "multi-call binary", like busybox):
+`vintner` is one Go binary that behaves differently depending on the name
+it's invoked as (a "multi-call binary", like busybox):
- Invoked as `cl`, `link`, `lib`, ... → it loads a small per-architecture
`env.json`, builds the `INCLUDE`/`LIB`/`WINEPATH` environment Wine needs,
@@ -21,22 +22,23 @@ name it's invoked as (a "multi-call binary", like busybox):
runs the real `.exe` under `wine`/`wine64`, and rewrites the tool's output
back from `z:\...` paths to plain unix paths so your build system's error
parsing keeps working.
-- Invoked as `msvc-go-wine` → it exposes the `download`, `install`, `env` and
- `version` management subcommands described below.
+- Invoked as `vintner` → it exposes the `download`, `install`, `env` and
+ `version` management subcommands described below (each also has a short
+ alias: `dl`, `i`, `e`, `v`; `help`/`h` prints usage).
## Quick start
```bash
-# 1. Download and unpack MSVC + Windows SDK into ~/.msvc-go-wine (requires
+# 1. Download and unpack MSVC + Windows SDK into ~/.vintner (requires
# accepting Microsoft's Visual Studio Build Tools license, and msitools
# for unpacking .msi payloads). Pass --dest
for a different location.
-msvc-go-wine download --accept-license
+vintner download --accept-license
# 2. Wire up the tool wrappers
-msvc-go-wine install
+vintner install
# 3. Add the toolchain to PATH and build
-export PATH=~/.msvc-go-wine/bin/x64:$PATH
+export PATH=~/.vintner/bin/x64:$PATH
cl /nologo /EHsc hello.cpp
```
@@ -56,20 +58,23 @@ pkcon install wine msitools
## Commands
```
-msvc-go-wine download --accept-license [--dest ] [options] fetch and unpack MSVC/WinSDK
-msvc-go-wine install [dir] wire up wrappers for a downloaded MSVC
-msvc-go-wine env --bin /bin/ print INCLUDE/LIB for native clang-cl/lld-link use
-msvc-go-wine version print the version
+vintner download (dl) --accept-license [--dest ] [options] fetch and unpack MSVC/WinSDK/WDK
+vintner install (i) [dir] wire up wrappers for a downloaded MSVC
+vintner env (e) --bin /bin/ print INCLUDE/LIB for native clang-cl/lld-link use
+vintner version (v) print the version
+vintner help (h) print usage
```
-`--dest`/`[dir]` both default to `~/.msvc-go-wine` when omitted.
+`--dest`/`[dir]` both default to `~/.vintner` when omitted.
-`download` supports `--msvc-version`, `--sdk-version`, `--architecture`,
-`--host-arch`, `--with-*` component toggles, `--ignore`, `--only-download`,
-`--only-unpack`, `--keep-unpack`, `--cache`, `--language`,
-`--include-optional`, `--skip-recommended`, `--major`, `--preview`,
-`--manifest`, `--list-workloads`, `--list-components`, `--print-deps-tree`.
-Run `msvc-go-wine download -h` for the full list.
+`download`'s main options: `--msvc-version`, `--sdk-version`,
+`--architecture`, `--host-arch`, `--only-host`, `--with-wdk` (also fetch the
+Windows Driver Kit, for building KMDF/UMDF drivers), `--ignore`,
+`--only-download`, `--only-unpack`, `--keep-unpack`, `--skip-patch`,
+`--cache`, `--language`, `--include-optional`, `--skip-recommended`,
+`--major`, `--preview`, `--manifest`, `--list-workloads`,
+`--list-components`, `--print-deps-tree`. Run `vintner download -h` for the
+full list with descriptions.
`--list-workloads`/`--list-components` print every workload/component id
(with its human-readable title) available in the fetched manifest and exit
@@ -78,13 +83,31 @@ package id or via `--with-*`. `--print-deps-tree` prints the dependency tree
of whatever would actually be selected (honoring every other flag), also
without downloading.
+### Building drivers (WDK)
+
+`vintner download --with-wdk` additionally fetches the Windows Driver Kit
+(headers, import libs, and the MSBuild `WindowsKernelModeDriver10.0`/
+`WindowsUserModeDriver10.0` PlatformToolsets) so `msbuild` can build real
+KMDF/UMDF drivers - 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).
+Only x64 and arm64 targets have a WDK package upstream (no x86/arm).
+
+### Language
+
+CLI messages (usage text, progress lines, prompts) are in English by
+default. Set `VINTNER_LANG=ru` (or have a `ru`-prefixed `LC_ALL`/
+`LC_MESSAGES`/`LANG`, e.g. `ru_RU.UTF-8`) for Russian. Deeper error text
+bubbled up from internal packages stays in English.
+
### Using clang-cl/lld-link instead of Wine
You don't need Wine at all if you drive the (nonredistributable) MSVC/WinSDK
headers and libraries with Clang/LLD in MSVC-compatible mode:
```bash
-eval "$(msvc-go-wine env --bin ~/.msvc-go-wine/bin/x64)"
+eval "$(vintner env --bin ~/.vintner/bin/x64)"
clang-cl -c hello.c
lld-link hello.obj -out:hello.exe
```
@@ -92,7 +115,7 @@ lld-link hello.obj -out:hello.exe
## Building from source
```bash
-go build -o msvc-go-wine ./cmd/msvc-go-wine
+go build -o vintner ./cmd/vintner
```
Go 1.23+ is all you need to build it; `wine`/`msitools` are only needed at
@@ -124,14 +147,14 @@ telemetry, and don't hard-fail devcmd setup when an optional component
## Known gaps
-- `download` doesn't yet support installing the Windows Driver Kit via
- `--with-wdk-installers`; the core selection/download/unpack/install
- pipeline, dependency tree printing, and workload/component listing are all
- fully implemented.
+None currently tracked. Download/select/unpack/install, general MSBuild
+projects, WDK driver builds, dependency-tree printing, and
+workload/component listing are all implemented and verified against real
+projects.
## License
-MIT, see [LICENSE.txt](LICENSE.txt) - covers msvc-go-wine's own source only.
-The MSVC Build Tools / Windows SDK that `download` fetches remain governed
+MIT, see [LICENSE.txt](LICENSE.txt) - covers vintner's own source only. The
+MSVC Build Tools / Windows SDK / WDK that `download` fetches remain governed
by Microsoft's own license (accepted via `--accept-license`), same as with
any other way of obtaining them.
diff --git a/assets/patches/Common7/Tools/VsDevCmd.bat.patch b/assets/patches/Common7/Tools/VsDevCmd.bat.patch
index 8ac84a9..873d0e8 100644
--- a/assets/patches/Common7/Tools/VsDevCmd.bat.patch
+++ b/assets/patches/Common7/Tools/VsDevCmd.bat.patch
@@ -1,4 +1,4 @@
-msvc-go-wine: skip VsDevCmd's telemetry upload.
+vintner: 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
diff --git a/assets/patches/Common7/Tools/vsdevcmd/core/vsdevcmd_start.bat.patch b/assets/patches/Common7/Tools/vsdevcmd/core/vsdevcmd_start.bat.patch
index 43d0e29..b699822 100644
--- a/assets/patches/Common7/Tools/vsdevcmd/core/vsdevcmd_start.bat.patch
+++ b/assets/patches/Common7/Tools/vsdevcmd/core/vsdevcmd_start.bat.patch
@@ -1,4 +1,4 @@
-msvc-go-wine: always record the starting directory.
+vintner: 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
diff --git a/assets/patches/Common7/Tools/vsdevcmd/core/winsdk.bat.patch b/assets/patches/Common7/Tools/vsdevcmd/core/winsdk.bat.patch
index 3fc976a..89843ca 100644
--- a/assets/patches/Common7/Tools/vsdevcmd/core/winsdk.bat.patch
+++ b/assets/patches/Common7/Tools/vsdevcmd/core/winsdk.bat.patch
@@ -1,4 +1,4 @@
-msvc-go-wine: find the Windows SDK/UCRT dirs on disk before trying the registry.
+vintner: 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
diff --git a/assets/patches/Common7/Tools/vsdevcmd/ext/ConnectionManagerExe.bat.patch b/assets/patches/Common7/Tools/vsdevcmd/ext/ConnectionManagerExe.bat.patch
index 7eb7d49..2caff0f 100644
--- a/assets/patches/Common7/Tools/vsdevcmd/ext/ConnectionManagerExe.bat.patch
+++ b/assets/patches/Common7/Tools/vsdevcmd/ext/ConnectionManagerExe.bat.patch
@@ -1,4 +1,4 @@
-msvc-go-wine: don't hard-fail devcmd setup when ConnectionManagerExe is missing.
+vintner: 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
diff --git a/assets/patches/Common7/Tools/vsdevcmd/ext/cmake.bat.patch b/assets/patches/Common7/Tools/vsdevcmd/ext/cmake.bat.patch
index 11e53a3..1967ad7 100644
--- a/assets/patches/Common7/Tools/vsdevcmd/ext/cmake.bat.patch
+++ b/assets/patches/Common7/Tools/vsdevcmd/ext/cmake.bat.patch
@@ -1,4 +1,4 @@
-msvc-go-wine: don't hard-fail devcmd setup when the bundled CMake/Ninja is missing.
+vintner: 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/assets/patches/MSBuild/Microsoft/VC/v180/ImportBefore/Default/msvc-go-wine.props.remove b/assets/patches/MSBuild/Microsoft/VC/v180/ImportBefore/Default/msvc-go-wine.props.remove
new file mode 100644
index 0000000..e69de29
diff --git a/assets/patches/MSBuild/Microsoft/VC/v180/ImportBefore/Default/msvc-go-wine.props b/assets/patches/MSBuild/Microsoft/VC/v180/ImportBefore/Default/vintner.props
similarity index 94%
rename from assets/patches/MSBuild/Microsoft/VC/v180/ImportBefore/Default/msvc-go-wine.props
rename to assets/patches/MSBuild/Microsoft/VC/v180/ImportBefore/Default/vintner.props
index e01cfa7..05d3f0a 100644
--- a/assets/patches/MSBuild/Microsoft/VC/v180/ImportBefore/Default/msvc-go-wine.props
+++ b/assets/patches/MSBuild/Microsoft/VC/v180/ImportBefore/Default/vintner.props
@@ -1,5 +1,5 @@