Skip to content

Instantly share code, notes, and snippets.

@mmozeiko
Last active May 31, 2023 04:08
Embed
What would you like to do?
Download MSVC compiler/linker & Windows SDK without installing full Visual Studio

This downloads standalone 64-bit MSVC compiler, linker & other tools, also headers/libraries from Windows SDK into portable folder, without installing Visual Studio. Has bare minimum components - no UWP/Store/WindowsRT stuff, just files & tools for 64-bit native desktop app development.

Run python.exe portable-msvc.py and it will download output into msvc folder. By default it will download latest available MSVC & Windows SDK - currently v14.32.17.2 and v10.0.22621.0.

You can list available versions with python.exe portable-msvc.py --show-versions and then pass versions you want with --msvc-version and --sdk-version arguments.

To use cl.exe/link.exe from output folder, first run setup.bat - after that PATH/INCLUDE/LIB env variables will be setup to use all the tools as usual. You can also use clang-cl.exe with these includes & libraries.

To use clang-cl.exe without running setup.bat, pass extra /winsysroot msvc argument (msvc is folder name where output is stored).

#!/usr/bin/env python3
import io
import os
import sys
import json
import shutil
import hashlib
import zipfile
import tempfile
import argparse
import subprocess
import urllib.request
from pathlib import Path
OUTPUT = Path("msvc") # output folder
# other architectures may work or may not - not really tested
HOST = "x64" # or x86
TARGET = "x64" # or x86, arm, arm64
MANIFEST_URL = "https://aka.ms/vs/17/release/channel"
def download(url):
with urllib.request.urlopen(url) as res:
return res.read()
def download_progress(url, check, name, f):
data = io.BytesIO()
with urllib.request.urlopen(url) as res:
total = int(res.headers["Content-Length"])
size = 0
while True:
block = res.read(1<<20)
if not block:
break
f.write(block)
data.write(block)
size += len(block)
perc = size * 100 // total
print(f"\r{name} ... {perc}%", end="")
print()
data = data.getvalue()
digest = hashlib.sha256(data).hexdigest()
if check.lower() != digest:
exit(f"Hash mismatch for f{pkg}")
return data
# super crappy msi format parser just to find required .cab files
def get_msi_cabs(msi):
index = 0
while True:
index = msi.find(b".cab", index+4)
if index < 0:
return
yield msi[index-32:index+4].decode("ascii")
def first(items, cond):
return next(item for item in items if cond(item))
### parse command-line arguments
ap = argparse.ArgumentParser()
ap.add_argument("--show-versions", const=True, action="store_const", help="Show available MSVC and Windows SDK versions")
ap.add_argument("--accept-license", const=True, action="store_const", help="Automatically accept license")
ap.add_argument("--msvc-version", help="Get specific MSVC version")
ap.add_argument("--sdk-version", help="Get specific Windows SDK version")
args = ap.parse_args()
### get main manifest
manifest = json.loads(download(MANIFEST_URL))
### download VS manifest
vs = first(manifest["channelItems"], lambda x: x["id"] == "Microsoft.VisualStudio.Manifests.VisualStudio")
payload = vs["payloads"][0]["url"]
vsmanifest = json.loads(download(payload))
### find MSVC & WinSDK versions
packages = {}
for p in vsmanifest["packages"]:
packages.setdefault(p["id"].lower(), []).append(p)
msvc = {}
sdk = {}
for pid,p in packages.items():
if pid.startswith("Microsoft.VisualStudio.Component.VC.".lower()) and pid.endswith(".x86.x64".lower()):
pver = ".".join(pid.split(".")[4:6])
if pver[0].isnumeric():
msvc[pver] = pid
elif pid.startswith("Microsoft.VisualStudio.Component.Windows10SDK.".lower()) or \
pid.startswith("Microsoft.VisualStudio.Component.Windows11SDK.".lower()):
pver = pid.split(".")[-1]
if pver.isnumeric():
sdk[pver] = pid
if args.show_versions:
print("MSVC versions:", " ".join(sorted(msvc.keys())))
print("Windows SDK versions:", " ".join(sorted(sdk.keys())))
exit(0)
msvc_ver = args.msvc_version or max(sorted(msvc.keys()))
sdk_ver = args.sdk_version or max(sorted(sdk.keys()))
if msvc_ver in msvc:
msvc_pid = msvc[msvc_ver]
msvc_ver = ".".join(msvc_pid.split(".")[4:-2])
else:
exit(f"Unknown MSVC version: f{args.msvc_version}")
if sdk_ver in sdk:
sdk_pid = sdk[sdk_ver]
else:
exit(f"Unknown Windows SDK version: f{args.sdk_version}")
print(f"Downloading MSVC v{msvc_ver} and Windows SDK v{sdk_ver}")
### agree to license
tools = first(manifest["channelItems"], lambda x: x["id"] == "Microsoft.VisualStudio.Product.BuildTools")
resource = first(tools["localizedResources"], lambda x: x["language"] == "en-us")
license = resource["license"]
if not args.accept_license:
accept = input(f"Do you accept Visual Studio license at {license} [Y/N] ? ")
if not accept or accept[0].lower() != "y":
exit(0)
OUTPUT.mkdir(exist_ok=True)
total_download = 0
### download MSVC
msvc_packages = [
# MSVC binaries
f"microsoft.vc.{msvc_ver}.tools.host{HOST}.target{TARGET}.base",
f"microsoft.vc.{msvc_ver}.tools.host{HOST}.target{TARGET}.res.base",
# MSVC headers
f"microsoft.vc.{msvc_ver}.crt.headers.base",
# MSVC libs
f"microsoft.vc.{msvc_ver}.crt.{TARGET}.desktop.base",
f"microsoft.vc.{msvc_ver}.crt.{TARGET}.store.base",
# MSVC runtime source
f"microsoft.vc.{msvc_ver}.crt.source.base",
# ASAN
f"microsoft.vc.{msvc_ver}.asan.headers.base",
f"microsoft.vc.{msvc_ver}.asan.{TARGET}.base",
# MSVC redist
#f"microsoft.vc.{msvc_ver}.crt.redist.x64.base",
]
for pkg in msvc_packages:
p = first(packages[pkg], lambda p: p.get("language") in (None, "en-US"))
for payload in p["payloads"]:
with tempfile.TemporaryFile() as f:
data = download_progress(payload["url"], payload["sha256"], pkg, f)
total_download += len(data)
with zipfile.ZipFile(f) as z:
for name in z.namelist():
if name.startswith("Contents/"):
out = OUTPUT / Path(name).relative_to("Contents")
out.parent.mkdir(parents=True, exist_ok=True)
out.write_bytes(z.read(name))
### download Windows SDK
sdk_packages = [
# Windows SDK tools (like rc.exe & mt.exe)
f"Windows SDK for Windows Store Apps Tools-x86_en-us.msi",
# Windows SDK headers
f"Windows SDK for Windows Store Apps Headers-x86_en-us.msi",
f"Windows SDK Desktop Headers x86-x86_en-us.msi",
# Windows SDK libs
f"Windows SDK for Windows Store Apps Libs-x86_en-us.msi",
f"Windows SDK Desktop Libs {TARGET}-x86_en-us.msi",
# CRT headers & libs
f"Universal CRT Headers Libraries and Sources-x86_en-us.msi",
# CRT redist
#"Universal CRT Redistributable-x86_en-us.msi",
]
with tempfile.TemporaryDirectory() as d:
dst = Path(d)
sdk_pkg = packages[sdk_pid][0]
sdk_pkg = packages[first(sdk_pkg["dependencies"], lambda x: True).lower()][0]
msi = []
cabs = []
# download msi files
for pkg in sdk_packages:
payload = first(sdk_pkg["payloads"], lambda p: p["fileName"] == f"Installers\\{pkg}")
msi.append(dst / pkg)
with open(dst / pkg, "wb") as f:
data = download_progress(payload["url"], payload["sha256"], pkg, f)
total_download += len(data)
cabs += list(get_msi_cabs(data))
# download .cab files
for pkg in cabs:
payload = first(sdk_pkg["payloads"], lambda p: p["fileName"] == f"Installers\\{pkg}")
with open(dst / pkg, "wb") as f:
download_progress(payload["url"], payload["sha256"], pkg, f)
print("Unpacking msi files...")
# run msi installers
for m in msi:
subprocess.check_call(["msiexec.exe", "/a", m, "/quiet", "/qn", f"TARGETDIR={OUTPUT.resolve()}"])
### versions
msvcv = list((OUTPUT / "VC/Tools/MSVC").glob("*"))[0].name
sdkv = list((OUTPUT / "Windows Kits/10/bin").glob("*"))[0].name
# place debug CRT runtime into MSVC folder (not what real Visual Studio installer does... but is reasonable)
dst = str(OUTPUT / "VC/Tools/MSVC" / msvcv / f"bin/Host{HOST}/{TARGET}")
pkg = "microsoft.visualcpp.runtimedebug.14"
dbg = packages[pkg][0]
payload = first(dbg["payloads"], lambda p: p["fileName"] == "cab1.cab")
try:
with tempfile.TemporaryFile(suffix=".cab", delete=False) as f:
data = download_progress(payload["url"], payload["sha256"], pkg, f)
total_download += len(data)
subprocess.check_call(["expand.exe", f.name, "-F:*", dst], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
finally:
os.unlink(f.name)
### cleanup
shutil.rmtree(OUTPUT / "Common7", ignore_errors=True)
for f in ["Auxiliary", f"lib/{TARGET}/store", f"lib/{TARGET}/uwp"]:
shutil.rmtree(OUTPUT / "VC/Tools/MSVC" / msvcv / f)
for f in OUTPUT.glob("*.msi"):
f.unlink()
for f in ["Catalogs", "DesignTime", f"bin/{sdkv}/chpe", f"Lib/{sdkv}/ucrt_enclave"]:
shutil.rmtree(OUTPUT / "Windows Kits/10" / f, ignore_errors=True)
for arch in ["x86", "x64", "arm", "arm64"]:
if arch != TARGET:
shutil.rmtree(OUTPUT / "VC/Tools/MSVC" / msvcv / f"bin/Host{arch}", ignore_errors=True)
shutil.rmtree(OUTPUT / "Windows Kits/10/bin" / sdkv / arch)
shutil.rmtree(OUTPUT / "Windows Kits/10/Lib" / sdkv / "ucrt" / arch)
shutil.rmtree(OUTPUT / "Windows Kits/10/Lib" / sdkv / "um" / arch)
### setup.bat
SETUP = f"""@echo off
set ROOT=%~dp0
set MSVC_VERSION={msvcv}
set MSVC_HOST=Host{HOST}
set MSVC_ARCH={TARGET}
set SDK_VERSION={sdkv}
set SDK_ARCH={TARGET}
set MSVC_ROOT=%ROOT%VC\\Tools\\MSVC\\%MSVC_VERSION%
set SDK_INCLUDE=%ROOT%Windows Kits\\10\\Include\\%SDK_VERSION%
set SDK_LIBS=%ROOT%Windows Kits\\10\\Lib\\%SDK_VERSION%
set VCToolsInstallDir=%MSVC_ROOT%\\
set PATH=%MSVC_ROOT%\\bin\\%MSVC_HOST%\\%MSVC_ARCH%;%ROOT%Windows Kits\\10\\bin\\%SDK_VERSION%\\%SDK_ARCH%;%ROOT%Windows Kits\\10\\bin\\%SDK_VERSION%\\%SDK_ARCH%\\ucrt;%PATH%
set INCLUDE=%MSVC_ROOT%\\include;%SDK_INCLUDE%\\ucrt;%SDK_INCLUDE%\\shared;%SDK_INCLUDE%\\um;%SDK_INCLUDE%\\winrt;%SDK_INCLUDE%\\cppwinrt
set LIB=%MSVC_ROOT%\\lib\\%MSVC_ARCH%;%SDK_LIBS%\\ucrt\\%SDK_ARCH%;%SDK_LIBS%\\um\\%SDK_ARCH%
"""
(OUTPUT / "setup.bat").write_text(SETUP)
print(f"Total downloaded: {total_download>>20} MB")
print("Done!")
@Doy-lee
Copy link

Doy-lee commented May 13, 2022

I also added
%ROOT%\Windows Kits\10\bin\%SDK_VERSION%\%SDK_ARCH% to the PATH so that rc.exe and friends are available. Having it available makes CMake work out of the box, otherwise it'll fail in the configure step.

So I modified the setup.bat step in the python script to.

set PATH=%MSVC_ROOT%\\bin\\%MSVC_HOST%\\%MSVC_ARCH%;%ROOT%Windows Kits\\10\\bin\\%SDK_VERSION%\\%SDK_ARCH%;%MSVC_ROOT%\\Windows Kits\\10\\bin\\%SDK_VERSION%\\%SDK_ARCH%\\ucrt;%PATH%

@mmozeiko
Copy link
Author

Oh, yeah that makes sense. I think I had it there but at some point accidentally deleted it. I'll update code to put it back.

@bogez57
Copy link

bogez57 commented Jul 21, 2022

When running the python script on my Windows 10 pro (10.0.19044 build) the process runs for a bit then gets to a point where a Windows Installer window pops up for which I can only select the "OK" button at the bottom. When I do I get this error message:

...........
beb5360d2daaa3167dea7ad16c28f996.cab ... 100%
eca0aa33de85194cd50ed6e0aae0156f.cab ... 100%
f9ff50431335056fb4fbac05b8268204.cab ... 100%
Unpacking msi files...
Traceback (most recent call last):
  File "C:\Program Files Jason\msvc_compiler_build_tools\portable-msvc.py", line 221, in <module>
    subprocess.check_call(["msiexec.exe", "/a", m, "/quiet", "/qn", f"TARGETDIR={OUTPUT.resolve()}"])
  File "C:\Users\Jason\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 369, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['msiexec.exe', '/a', WindowsPath('C:/Users/Jason/AppData/Local/Temp/tmpwzjvccp7/Windows SDK for Windows Store Apps Tools-x86_en-us.msi'), '/quiet', '/qn', 'TARGETDIR=C:\\Program Files Jason\\msvc_compiler_build_tools\\msvc']' returned non-zero exit status 1639.

@lerno
Copy link

lerno commented Oct 10, 2022

Could you clarify the license of this gist @mmozeiko, since someone was bugging me about using a modified version of the above gist (while incorrectly assuming it was written by @Doy-lee: c3lang/c3c#622)

@carlosedubarreto
Copy link

When running the python script on my Windows 10 pro (10.0.19044 build) the process runs for a bit then gets to a point where a Windows Installer window pops up for which I can only select the "OK" button at the bottom. When I do I get this error message:

...........
beb5360d2daaa3167dea7ad16c28f996.cab ... 100%
eca0aa33de85194cd50ed6e0aae0156f.cab ... 100%
f9ff50431335056fb4fbac05b8268204.cab ... 100%
Unpacking msi files...
Traceback (most recent call last):
  File "C:\Program Files Jason\msvc_compiler_build_tools\portable-msvc.py", line 221, in <module>
    subprocess.check_call(["msiexec.exe", "/a", m, "/quiet", "/qn", f"TARGETDIR={OUTPUT.resolve()}"])
  File "C:\Users\Jason\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 369, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['msiexec.exe', '/a', WindowsPath('C:/Users/Jason/AppData/Local/Temp/tmpwzjvccp7/Windows SDK for Windows Store Apps Tools-x86_en-us.msi'), '/quiet', '/qn', 'TARGETDIR=C:\\Program Files Jason\\msvc_compiler_build_tools\\msvc']' returned non-zero exit status 1639.

@bogez57
Remove the space from the folder you are running the python script and it might work.

@cedric-h
Copy link

cedric-h commented Nov 21, 2022

should one prefer to use Git Bash rather than cmd.exe, they may source setup.sh in place of running setup.bat from cmd.

ASSUMES msvc is stored at e.g. "C:/Users/ced/msvc" where ced is your username. Adjust first line accordingly.

setup.sh:

export MY_ROOT="${USERPROFILE}/msvc/"

export MSVC_VERSION=14.34.31933
export MSVC_HOST=Hostx64
export MSVC_ARCH=x64
export SDK_VERSION=10.0.22621.0
export SDK_ARCH=x64

export MSVC_ROOT="${MY_ROOT}VC/Tools/MSVC/${MSVC_VERSION}"
export SDK_INCLUDE="${MY_ROOT}Windows Kits/10/Include/${SDK_VERSION}"
export SDK_LIBS="${MY_ROOT}Windows Kits/10/Lib/${SDK_VERSION}"

export VCToolsInstallDir="${MSVC_ROOT}/"
export PATH="${MSVC_ROOT}/bin/${MSVC_HOST}/${MSVC_ARCH};${MY_ROOT}Windows Kits/10/bin/${SDK_VERSION}/${SDK_ARCH};${MY_ROOT}Windows Kits/10/bin/${SDK_VERSION}/${SDK_ARCH}/ucrt;${PATH}"
export INCLUDE="${MSVC_ROOT}/include;${SDK_INCLUDE}/ucrt;${SDK_INCLUDE}/shared;${SDK_INCLUDE}/um;${SDK_INCLUDE}/winrt;${SDK_INCLUDE}/cppwinrt"
export LIB="${MSVC_ROOT}/lib/${MSVC_ARCH};${SDK_LIBS}/ucrt/${SDK_ARCH};${SDK_LIBS}/um/${SDK_ARCH}"

@bogez57
Copy link

bogez57 commented Dec 26, 2022

On my laptop, I noticed the script does not execute "Windows SDK Desktop Headers x86-x86_en-us.msi" which seems to leave out headers like windowsx.h. On my desktop top everything gets downloaded. This is the log from the laptop:

Downloading MSVC v14.34.17.4 and Windows SDK v22621
Do you accept Visual Studio license at https://go.microsoft.com/fwlink/?LinkId=2179911 [Y/N] ? y
microsoft.vc.14.34.17.4.tools.hostx64.targetx64.base ... 100%
microsoft.vc.14.34.17.4.tools.hostx64.targetx64.res.base ... 100%
microsoft.vc.14.34.17.4.crt.headers.base ... 100%
microsoft.vc.14.34.17.4.crt.x64.desktop.base ... 100%
microsoft.vc.14.34.17.4.crt.x64.store.base ... 100%
microsoft.vc.14.34.17.4.crt.source.base ... 100%
microsoft.vc.14.34.17.4.asan.headers.base ... 100%
microsoft.vc.14.34.17.4.asan.x64.base ... 100%
Windows SDK for Windows Store Apps Tools-x86_en-us.msi ... 100%
Windows SDK for Windows Store Apps Headers-x86_en-us.msi ... 100%
Windows SDK for Windows Store Apps Libs-x86_en-us.msi ... 100%
Windows SDK Desktop Libs x64-x86_en-us.msi ... 100%
Universal CRT Headers Libraries and Sources-x86_en-us.msi ... 100%
15bc5316e373960d82abc253bceaa25d.cab ... 100%
2630bae9681db6a9f6722366f47d055c.cab ... 100%
26ea25236f12b23db661acf268a70cfa.cab ... 100%
2a30b5d1115d515c6ddd8cd6b5173835.cab ... 100%
4a4c678668584fc994ead5b99ccf7f03.cab ... 100%
61d57a7a82309cd161a854a6f4619e52.cab ... 100%
68de71e3e2fb9941ee5b7c77500c0508.cab ... 100%
69661e20556b3ca9456b946c2c881ddd.cab ... 100%
b82881a61b7477bd4eb5de2cd5037fe2.cab ... 100%
dcfb1aa345e349091a44e86ce1766566.cab ... 100%
e072b3b3d3164e26b63338dce51862a7.cab ... 100%
e3d1b35aecfccda1b4af6fe5988ac4be.cab ... 100%
766c0ffd568bbb31bf7fb6793383e24a.cab ... 100%
8125ee239710f33ea485965f76fae646.cab ... 100%
c0aa6d435b0851bf34365aadabd0c20f.cab ... 100%
c1c7e442409c0adbf81ae43aa0e4351f.cab ... 100%
05047a45609f311645eebcac2739fc4c.cab ... 100%
0b2a4987421d95d0cb37640889aa9e9b.cab ... 100%
13d68b8a7b6678a368e2d13ff4027521.cab ... 100%
463ad1b0783ebda908fd6c16a4abfe93.cab ... 100%
5a22e5cde814b041749fb271547f4dd5.cab ... 100%
ba60f891debd633ae9c26e1372703e3c.cab ... 100%
e10768bb6e9d0ea730280336b697da66.cab ... 100%
f9b24c8280986c0683fbceca5326d806.cab ... 100%
58314d0646d7e1a25e97c902166c3155.cab ... 100%
16ab2ea2187acffa6435e334796c8c89.cab ... 100%
2868a02217691d527e42fe0520627bfa.cab ... 100%
6ee7bbee8435130a869cf971694fd9e2.cab ... 100%
78fa3c824c2c48bd4a49ab5969adaaf7.cab ... 100%
7afc7b670accd8e3cc94cfffd516f5cb.cab ... 100%
80dcdb79b8a5960a384abe5a217a7e3a.cab ... 100%
96076045170fe5db6d5dcf14b6f6688e.cab ... 100%
a1e2a83aa8a71c48c742eeaff6e71928.cab ... 100%
b2f03f34ff83ec013b9e45c7cd8e8a73.cab ... 100%
beb5360d2daaa3167dea7ad16c28f996.cab ... 100%
eca0aa33de85194cd50ed6e0aae0156f.cab ... 100%
f9ff50431335056fb4fbac05b8268204.cab ... 100%
Unpacking msi files...
microsoft.visualcpp.runtimedebug.14 ... 100%
Total downloaded: 191 MB
Done!

@mmozeiko
Copy link
Author

Did you use latest code? Few months ago I updated it to have correct name for Desktop Headers msi file. If the latest code does not work, then you'll need to check what's in packages dict to understand why this msi name is not found there. Either print packages dict, or use debugger to check it on line 163.

@bogez57
Copy link

bogez57 commented Dec 26, 2022

Ahhh, sorry. Ya, I didn't even realize there was an update right after I downloaded it initially. I just copy and pasted the latest code and it seems to be working.

@ApexSim
Copy link

ApexSim commented Feb 9, 2023

Good Job! and, how to setup for vcpkg to use the download MSVC compiler?

@mmozeiko
Copy link
Author

mmozeiko commented Feb 9, 2023

You'll need to figure out that yourself. I have no idea how vcpkg works, I do not use it.

@properchopsticks
Copy link

hi, i made a change to line 221, apparently when running OUTPUT.resolve() at some point it adds quotes around the whole f"" argument and it makes it looks something like "TARGETDIR=C:\my\path with spaces\" instead of TARGETDIR="C:\my\path with spaces\" which causes subprocess.CalledProcessError.

the line that worked for me was:
subprocess.check_call(f"msiexec.exe /a \"{m}\" /quiet /qn TARGETDIR=\"{OUTPUT.resolve()}\"")

also awesome script, it's so convenient to finally have a portable msvc compiler.

@nmsobri
Copy link

nmsobri commented Apr 18, 2023

why i got Windows Sdk not found when i tried to run hello world program? I thought running the bat file will set the env vars

@AlisterH
Copy link

I was hoping that using this I could install modules with python pip that compile stuff from source. But attempting to do so still produces this:

      error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/

Is there something else that will make it work? Perhaps this is really the same issue as @nmsobri is experiencing...?

@mmozeiko
Copy link
Author

@AlisterH Try setting set DISTUTILS_USE_SDK=1 environment variable before running pip. By default python setuptools tries to use vswhere.exe & registry information & hardcoded vcvarsall.bat bat file to find where Visual Studio is installed. But that env variable should override all of it, and simply expect cl.exe & link.exe & others be available on PATH (which is done by my setup.bat file).

See more info here: https://docs.python.org/3/distutils/apiref.html#module-distutils.msvccompiler

@AlisterH
Copy link

Great, thanks!

@OldWorldOrdr
Copy link

clang cant run the linker

clang version 16.0.4
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Users\Joey\scoop\apps\llvm\current\bin
 "link.exe" -out:a.exe -defaultlib:libcmt -defaultlib:oldnames "-libpath:C:\\Users\\Joey\\scoop\\apps\\llvm\\current\\lib\\clang\\16\\lib\\windows" -nologo hello.obj
clang: error: unable to execute command: program not executable
clang: error: linker command failed with exit code 1 (use -v to see invocation)

it is in PATH, and cl runs it fine

@mmozeiko
Copy link
Author

mmozeiko commented May 26, 2023

What happens when you run link.exe with all those arguments manually?

@OldWorldOrdr
Copy link

What happens when you run link.exe with all those arguments manually?

link.exe -out:a.exe -defaultlib:libcmt -defaultlib:oldnames -libpath:C:\Users\Joey\scoop\apps\llvm\current\lib\clang\16\lib\windows -nologo hello.obj
I think this is equivalent, it produces a working executable

@OldWorldOrdr
Copy link

doing the wierd clang quote thing works fine too
link.exe -out:a.exe -defaultlib:libcmt -defaultlib:oldnames "-libpath:C:\\Users\\Joey\\scoop\\apps\\llvm\\current\\lib\\clang\\16\\lib\\windows" -nologo hello.obj
only change to the command is renaming a.out to a.exe and not quoting link.exe

@OldWorldOrdr
Copy link

Running with -fuse-ld=lld works btw

@mmozeiko
Copy link
Author

"program not executable" is a very strange error. I don't think this is related to msvc files. Because if link.exe works when running manually then everything is fine. Instead it is something else with your scoop or clang setup. Like it's trying to execute some different link.exe, maybe you have multiple ones in path, or maybe scoop is doing some modifications to environment for something, I don't know how scoop works.

@OldWorldOrdr
Copy link

program not executable is the same error you get when link.exe isnt in PATH

@OldWorldOrdr
Copy link

building and installing from source solved the issue, strangely uninstalling the source build and then installing from scoop makes the scoop version work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment