I\'m heavily using Cygwin (with PuTTY shell). But, it\'s quite tricky to invoke cl.exe
(that is, the Visual C++ compiler toolchain) in the Cygwin Bash shell. R
I usually solve this by adding
call "%VS80COMNTOOLS%vsvars32.bat" >NUL:
to c:/cygwin/cygwin.bat. Note that the VS80COMNTOOLS variable is extremely useful, since it gives you a foolproof (hm) way of locating vsvars32.bat.
Another approach is this, which allows you to easily switch between different Studio versions:
function run_with_bat()
{
batfile=$1; shift
tmpfile="$TMP/tmp$$.bat"
echo "@echo off" > $tmpfile
echo "call \"%$batfile%vsvars32.bat\" >NUL:" >> $tmpfile
echo "bash -c \"%*\"" >> $tmpfile
cmd /c `cygpath -m "$tmpfile"` "$@"
status=$?
rm -f $tmpfile
return $status
}
function run_vs9()
{
run_with_bat VS90COMNTOOLS "$@"
}
function run_vs8()
{
run_with_bat VS80COMNTOOLS "$@"
}
You can now do:
$ run_vs8 cl
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
usage: cl [ option... ] filename... [ /link linkoption... ]
$ run_vs9 cl
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
usage: cl [ option... ] filename... [ /link linkoption... ]
Note the compiler version.
I actually used JesperE answer https://stackoverflow.com/a/374411/380247 (that allows you to switch between VS versions) but found a way not to create temporary bat file. So result is much simpler.
function run_in_vs_env
{
eval vssetup="\$$1\\vsvars32.bat"
cmd /Q /C call "$vssetup" "&&" "${@:2}"
}
function run_vs11
{
run_in_vs_env VS110COMNTOOLS "$@"
}
function run_vs10
{
run_in_vs_env VS100COMNTOOLS "$@"
}
I suggest to add these lines to your .bash_functions or something similar and export these functions there. This will allow you to use functions in your bash scripts.
export -f run_in_vs_env
export -f run_vs11
export -f run_vs10
Then you should be able to do:
run_vs11 cl
None of the other answers worked for me, but this did:
dump the env vars: set > c:\temp\cl.env
Open a cygwin command prompt and create a source
script:
awk < /cygdrive/c/temp/cl.env -F= '{ if($1 !~ ")") print "export " $1 "=\x27" $2 "\x27" }' > cl.source
Modify cl.source to change TEMP and TMP to C:\Temp e.g. TEMP='C:\Temp'
Now, whenever you need the cl environment, from your cygwin prompt run:
source cl.source
Optionally, source cl.source in your .bashrc file to run automatically when you log in
One utility I found pretty invaluable for compiling stuff with msvc from a cygwin environment is a wrapper I found in the Coin 3D library's source repository called "wrapmsvc", who's binary can be found here.
The program wraps cl.exe and converts any GCC args specified to the appropriate cl.exe arg. It also uses cygwin API to correctly translate the filepath from cygwin form (/cygdrive/c/temp/test.c) to it's actual file path (C:\temp\test.c).
The source took me a little while to find last time, but it's called "wrapmsvc.cpp", so if you need to compile it, look for that file. If you do happen to compile it and you get some depreciation warnings/errors about the use of cygwin_conv_to_posix_path or cygwin_conv_to_win32_path, make the following changes:
Change the line:
(void)cygwin_conv_to_posix_path(s.c_str(), buf);
to
(void)cygwin_conv_path(CCP_WIN_A_TO_POSIX, (const void *)s.c_str(), (void *)buf, (size_t)MAX_PATH);
and change:
(void)cygwin_conv_to_win32_path(s.c_str(), buf);
to
(void)cygwin_conv_path(CCP_POSIX_TO_WIN_A, (const void *)s.c_str(), (void *)buf, (size_t)MAX_PATH);
I find it a better strategy to use msbuild
and then at the same time, I can also use g++
of my cygwin environment. It is a more integrated approach and blends harmoniously with the your existing visual studio
development. Using the lowest level cl
and setting up environment variables is asking for trouble and going against the wind. The msbuild
can better setup things for us. Also, I can step-debug into the IDE having a full-pledge *.vcxproj
project.
ls -l ~/bin/msbuild
lrwxrwxrwx 1 johnny Domain Users 102 Sep 4 04:25 /home/johnny/bin/msbuild -> /cygdrive/c/Program Files (x86)/Microsoft Visual Studio/2017/Professional/MSBuild/15.0/Bin/MSBuild.exe
Then in your ~/.bashrc, have this function:
builddebug (){
[ $# -eq 0 ] && return 1;
msbuild /m /p:Configuration=Debug /p:Platform=Win32 "$1"
}
The feel of the development experience looks like this. At least, i'm able to use the g++
compiler and the Visual Studio 2017
compiler in a better integrated fashion. Let msbuild
do its thing. Not cl
.
My version of Igor's solution, it's briefer:
cl() {
tmpfile="/tmp/tmp$$.bat"
echo "@echo off" > $tmpfile
echo "call \"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat\" >NUL:" >> $tmpfile
echo "bash -c \"cl %*\"" >> $tmpfile
cmd /c `cygpath -m "$tmpfile"` "$@"
status=$?
rm -f $tmpfile
return $status
}
it's a pity that vcvars64.bat needs to be called repetitively.