Skip to content

Instantly share code, notes, and snippets.

@BeErikk
Last active August 18, 2022 18:55
Show Gist options
  • Save BeErikk/225d8b7188f3b21348c8d17fe0046455 to your computer and use it in GitHub Desktop.
Save BeErikk/225d8b7188f3b21348c8d17fe0046455 to your computer and use it in GitHub Desktop.
WSL user .profile file to enable the MS compiler in the WSL shell
# shellcheck shell=bash
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.
# this file is symlinked to /home/<user>/.profile
# Jerker Bäck 2017
# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
export TMPDIR="/mnt/c/TEMP/apptemp/unixtmp"
export TMP=$TMPDIR # override
vswhere='/mnt/c/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe'
vsinstalldir=$(wslpath "$("$vswhere" -latest -property installationPath 2>/dev/null | sed 's:\\:/:g' | tr -d '\r\n')")
vctoolsversion=$(head -n 1 "${vsinstalldir}/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt" | tr -d '\r\n')
export VCToolsInstallDir="$vsinstalldir/VC/Tools/MSVC/$vctoolsversion" # used by clang
kitskey='HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots'
kitsroot10="$(wslpath "$(/mnt/c/Windows/System32/reg.exe query "$kitskey" -f 'KitsRoot10' 2>/dev/null | sed -n 's:.*REG_SZ *\([[:print:]]*\).*:\1:p' | sed 's:\\:/:g')")"
kitsversion=$(sed -n -e '/PlatformIdentity/ s:.*Version\=*::p' "${kitsroot10}SDKManifest.xml" | sed 's:"[[:space:]]*::g')
export kitsroot10
export kitsversion
#export INCLUDE="$VCToolsInstallDir/include:${kitsroot10}Include/$kitsversion/ucrt:${kitsroot10}Include/$kitsversion/um:${kitsroot10}Include/$kitsversion/shared:$VCToolsInstallDir/atlmfc/include:/mnt/f/libraries/include"
#export LIB="$VCToolsInstallDir/lib/x64:${kitsroot10}Lib/$kitsversion/ucrt/x64:${kitsroot10}Lib/$kitsversion/um/x64:${kitsroot10}Lib/$kitsversion/shared/x64:/mnt/f/libraries/lib/x64"
export INCLUDE="$VCToolsInstallDir/include;${kitsroot10}Include/$kitsversion/ucrt;${kitsroot10}Include/$kitsversion/um;${kitsroot10}Include/$kitsversion/shared;$VCToolsInstallDir/atlmfc/include;/mnt/f/libraries/include"
export LIB="$VCToolsInstallDir/lib/x64;${kitsroot10}Lib/$kitsversion/ucrt/x64;${kitsroot10}Lib/$kitsversion/um/x64;${kitsroot10}Lib/$kitsversion/shared/x64;/mnt/f/libraries/lib/x64"
export CL="-O1 -Oi -EHsc -std:c++17 -W4 -MD"
export _CL_="-link -subsystem:console -machine:x64"
#export CFLAGS="--target=x86_64-pc-windows-msvc -std=c++20 -isystem"$VCToolsInstallDir/include" -isystem"${kitsroot10}Include/$kitsversion/ucrt" -isystem"${kitsroot10}Include/$kitsversion/um" -isystem"${kitsroot10}Include/$kitsversion/shared" -isystem"$VCToolsInstallDir/atlmfc/include" -isystem"/mnt/f/libraries/include""
export WSLENV=$WSLENV:INCLUDE/l:LIB/l:CL:_CL_:TMPDIR/p:TMP/p
# strip path to Ubuntu system to avoid pollution of Windows versions of tools
wslsys="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/mnt/c/Windows/System32:/mnt/c/Windows:/mnt/c/Windows/System32/WindowsPowerShell/v1.0"
export PATH="$VCToolsInstallDir/bin/Hostx64/x64:${kitsroot10}bin/$kitsversion/x64:/mnt/c/develop/vscode/bin:$wslsys"
unset vswhere vsinstalldir vctoolsversion kitskey wslsys
@BeErikk
Copy link
Author

BeErikk commented Apr 24, 2021

This file is symlinked to WSL /home/<user>/.profile
The tools must be invoked with exe-extension cl.exe link.exe mt.exe etc
The CL and _CL_ are set for compatibility in automatic compiles by scripts etc and should normally be redefined
Note the WSLENV which automagically translate the environment paths between UNIX and Windows

I have these settings for my login shell and the delay isn't noticeable. I think the tools are unlikely to interfere with anything in a UNIX environment due to the need for the exec extension. So a cl script is not the same as cl.exe.

@BeErikk
Copy link
Author

BeErikk commented Apr 24, 2021

To install:
$ cd ~
$ mv .profile .profile.save
$ ln -sf /mnt/d/devapps/wsl/profile.sh .profile

/mnt/d/devapps/wsl/ being whatever path where the file has been cloned

@BeErikk
Copy link
Author

BeErikk commented Apr 24, 2021

Problem is how to get WSL clang to use the settings, that is using WSL clang to compile for Windows.

@BeErikk
Copy link
Author

BeErikk commented Apr 25, 2021

I finally understood why clang couldn't parse the INCLUDE and LIB environment variables. The parser expects a semicolon ; instead of a colon : even in UNIX environments. I therefore added INCLUDEtmp and LIBtmp with semicolon delimiters. To let clang compile successfully using INCLUDE and LIB, do:

$ cl.exe test.cpp
$ export INCLUDE=$INCLUDEtmp
$ clang -target x86_64-pc-windows-msvc -std=c++17 -Wall -pedantic -Wextra -save-temps=obj -v test.cpp

The compile will then use WSL clang using INCLUDE with UNIX paths and semicolons and Windows link.exe using LIB and WSLENV.

See WSLENV for an explanation. Share Environment Vars between WSL and Windows. Test the effect by running cmd.exe env from WSL.

The cl.exe compile will use CL and _CL_ which expands to:
cl.exe -O1 -Oi -EHsc -std:c++17 -W4 -MD test.cpp -link -subsystem:console -machine:x64

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