From 8f52e5861a12e4c04848a78359fd720298dcb417 Mon Sep 17 00:00:00 2001 From: Cheviiot <153805936+Cheviiot@users.noreply.github.com> Date: Sat, 25 Jul 2026 01:38:47 +1000 Subject: [PATCH] Default download/install to ~/.msvc-go-wine when no dir is given --dest (download) and the positional dir (install) were previously required, forcing every user to pick and remember a location. Both now default to a single hidden ~/.msvc-go-wine, matching the convention most CLI tools use for their own data dir - still overridable for anyone who wants a different location. --- README.md | 23 +++++++++++++---------- cmd/msvc-go-wine/download.go | 11 ++++++++--- cmd/msvc-go-wine/install.go | 18 +++++++++++++++--- cmd/msvc-go-wine/main.go | 7 +++++-- cmd/msvc-go-wine/paths.go | 17 +++++++++++++++++ 5 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 cmd/msvc-go-wine/paths.go diff --git a/README.md b/README.md index 28ac894..05cbf5f 100644 --- a/README.md +++ b/README.md @@ -27,15 +27,16 @@ name it's invoked as (a "multi-call binary", like busybox): ## Quick start ```bash -# 1. Download and unpack MSVC + Windows SDK (requires accepting Microsoft's -# Visual Studio Build Tools license, and msitools for unpacking .msi payloads) -msvc-go-wine download --accept-license --dest ~/my_msvc +# 1. Download and unpack MSVC + Windows SDK into ~/.msvc-go-wine (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 # 2. Wire up the tool wrappers -msvc-go-wine install ~/my_msvc +msvc-go-wine install # 3. Add the toolchain to PATH and build -export PATH=~/my_msvc/bin/x64:$PATH +export PATH=~/.msvc-go-wine/bin/x64:$PATH cl /nologo /EHsc hello.cpp ``` @@ -55,12 +56,14 @@ pkcon install wine msitools ## Commands ``` -msvc-go-wine download --dest [options] fetch and unpack MSVC/WinSDK -msvc-go-wine install 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 +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 ``` +`--dest`/`[dir]` both default to `~/.msvc-go-wine` when omitted. + `download` supports `--msvc-version`, `--sdk-version`, `--architecture`, `--host-arch`, `--with-*` component toggles, `--ignore`, `--only-download`, `--only-unpack`, `--keep-unpack`, `--cache`, `--language`, @@ -73,7 +76,7 @@ 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 ~/my_msvc/bin/x64)" +eval "$(msvc-go-wine env --bin ~/.msvc-go-wine/bin/x64)" clang-cl -c hello.c lld-link hello.obj -out:hello.exe ``` diff --git a/cmd/msvc-go-wine/download.go b/cmd/msvc-go-wine/download.go index 1597981..35ceb79 100644 --- a/cmd/msvc-go-wine/download.go +++ b/cmd/msvc-go-wine/download.go @@ -13,7 +13,7 @@ import ( func runDownload(args []string) int { fs := flag.NewFlagSet("download", flag.ContinueOnError) - dest := fs.String("dest", "", "directory to install into (required unless --only-download)") + dest := fs.String("dest", "", "directory to install into (default: ~/.msvc-go-wine)") cacheDir := fs.String("cache", "", "directory to use as a persistent download cache (default: a temp dir, removed afterwards)") major := fs.Int("major", 18, "the major VS version to download") preview := fs.Bool("preview", false, "download the preview/insiders channel instead of release/stable") @@ -122,8 +122,13 @@ func runDownload(args []string) int { } if !*onlyDownload && *dest == "" { - fmt.Fprintln(os.Stderr, "msvc-go-wine download: --dest is required unless --only-download is set") - return 1 + def, err := defaultToolchainDir() + if err != nil { + fmt.Fprintln(os.Stderr, "msvc-go-wine download:", err) + return 1 + } + *dest = def + fmt.Println("--dest not set, using default:", *dest) } if err := download.FetchPayloads(selected, cache, *onlyDownload); err != nil { diff --git a/cmd/msvc-go-wine/install.go b/cmd/msvc-go-wine/install.go index 6d864ba..5a19e71 100644 --- a/cmd/msvc-go-wine/install.go +++ b/cmd/msvc-go-wine/install.go @@ -8,11 +8,23 @@ import ( ) func runInstall(args []string) int { - if len(args) != 1 || args[0] == "-h" || args[0] == "--help" { - fmt.Fprintln(os.Stderr, "usage: msvc-go-wine install ") + if len(args) > 1 || (len(args) == 1 && (args[0] == "-h" || args[0] == "--help")) { + fmt.Fprintln(os.Stderr, "usage: msvc-go-wine install [dest] (default: ~/.msvc-go-wine)") return 1 } - dest := args[0] + + var dest string + if len(args) == 1 { + dest = args[0] + } else { + def, err := defaultToolchainDir() + if err != nil { + fmt.Fprintln(os.Stderr, "msvc-go-wine install:", err) + return 1 + } + dest = def + fmt.Println("No directory given, using default:", dest) + } self, err := os.Executable() if err != nil { diff --git a/cmd/msvc-go-wine/main.go b/cmd/msvc-go-wine/main.go index abbc8d5..ffbb4a2 100644 --- a/cmd/msvc-go-wine/main.go +++ b/cmd/msvc-go-wine/main.go @@ -63,11 +63,14 @@ func printUsage() { fmt.Fprint(os.Stderr, `msvc-go-wine - cross compile with MSVC on Linux via Wine Usage: - msvc-go-wine download --dest [options] fetch and unpack MSVC/WinSDK - msvc-go-wine install wire up wrappers for a downloaded MSVC + 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 print INCLUDE/LIB for native clang-cl/lld-link use msvc-go-wine version print the version +--dest/[dir] default to ~/.msvc-go-wine if omitted. + Once installed, add /bin/ to PATH and invoke the tools directly: cl, link, lib, ml, ml64, mc, midl, mt, rc, dumpbin, msbuild, nmake, armasm, armasm64, cmd, findstr `) diff --git a/cmd/msvc-go-wine/paths.go b/cmd/msvc-go-wine/paths.go new file mode 100644 index 0000000..981dd73 --- /dev/null +++ b/cmd/msvc-go-wine/paths.go @@ -0,0 +1,17 @@ +package main + +import ( + "os" + "path/filepath" +) + +// defaultToolchainDir is where `download`/`install` operate when the user +// doesn't specify a directory: a hidden ~/.msvc-go-wine, so it doesn't +// clutter a plain `ls ~`. +func defaultToolchainDir() (string, error) { + home, err := os.UserHomeDir() + if err != nil { + return "", err + } + return filepath.Join(home, ".msvc-go-wine"), nil +}