我大量使用 Cygwin(带有PuTTY shell)。但是,cl.exe
在 Cygwin Bash shell 中调用(即 Visual C++ 编译器工具链)非常棘手。在 Bash shell 中运行vcvars*.bat
显然不起作用。我尝试将 VC++ 的环境变量迁移到 Cygwin,但这并不容易。
如何在 Cygwin 的 Bash shell 中运行 VC++ 编译器?
我大量使用 Cygwin(带有PuTTY shell)。但是,cl.exe
在 Cygwin Bash shell 中调用(即 Visual C++ 编译器工具链)非常棘手。在 Bash shell 中运行vcvars*.bat
显然不起作用。我尝试将 VC++ 的环境变量迁移到 Cygwin,但这并不容易。
如何在 Cygwin 的 Bash shell 中运行 VC++ 编译器?
我通常通过添加来解决这个问题
call "%VS80COMNTOOLS%vsvars32.bat" >NUL:
到 c:/cygwin/cygwin.bat。请注意,VS80COMNTOOLS 变量非常有用,因为它为您提供了一种万无一失的 (hm) 方法来定位 vsvars32.bat。
另一种方法是这样,它允许您在不同的 Studio 版本之间轻松切换:
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 "$@"
}
您现在可以执行以下操作:
$ 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... ]
注意编译器版本。
我了解您的问题是将 vcvars32.bat 转换为 shell 脚本。
解决该问题的一种方法是基于当一个进程启动另一个进程时继承环境变量的想法。所以你可以简单地在cmd下运行vcvars32,然后运行bash。这在我的机器上运行良好:
sh-3.2$ 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... ]
或者,在cmd下调用vcvars32前后运行set,然后创建一个shell脚本来设置环境变量。
根据其他答案中的建议,我对带有和不带有 MSVC 变量的 bash“设置”结果进行了比较,并提出了以下脚本来重现它们以用于安装 Microsoft Visual C++ 2010 Express。我已经对其进行了一些重构,将所有与安装相关的部分放在了顶部,因此希望这对其他人有用。
# These lines will be installation-dependent.
export VSINSTALLDIR='C:\Program Files\Microsoft Visual Studio 10.0\'
export WindowsSdkDir='C:\Program Files\Microsoft SDKs\Windows\v7.0A\'
export FrameworkDir='C:\WINDOWS\Microsoft.NET\Framework\'
export FrameworkVersion=v4.0.30319
export Framework35Version=v3.5
# The following should be largely installation-independent.
export VCINSTALLDIR="$VSINSTALLDIR"'VC\'
export DevEnvDir="$VSINSTALLDIR"'Common7\IDE\'
export FrameworkDIR32="$FrameworkDir"
export FrameworkVersion32="$FrameworkVersion"
export INCLUDE="${VCINSTALLDIR}INCLUDE;${WindowsSdkDir}include;"
export LIB="${VCINSTALLDIR}LIB;${WindowsSdkDir}lib;"
export LIBPATH="${FrameworkDir}${FrameworkVersion};"
export LIBPATH="${LIBPATH}${FrameworkDir}${Framework35Version};"
export LIBPATH="${LIBPATH}${VCINSTALLDIR}LIB;"
c_VSINSTALLDIR=`cygpath -ua "$VSINSTALLDIR\\\\"`
c_WindowsSdkDir=`cygpath -ua "$WindowsSdkDir\\\\"`
c_FrameworkDir=`cygpath -ua "$FrameworkDir\\\\"`
export PATH="${c_WindowsSdkDir}bin:$PATH"
export PATH="${c_WindowsSdkDir}bin/NETFX 4.0 Tools:$PATH"
export PATH="${c_VSINSTALLDIR}VC/VCPackages:$PATH"
export PATH="${c_FrameworkDir}${Framework35Version}:$PATH"
export PATH="${c_FrameworkDir}${FrameworkVersion}:$PATH"
export PATH="${c_VSINSTALLDIR}Common7/Tools:$PATH"
export PATH="${c_VSINSTALLDIR}VC/BIN:$PATH"
export PATH="${c_VSINSTALLDIR}Common7/IDE/:$PATH"
我实际上使用了 JesperE 答案https://stackoverflow.com/a/374411/380247(允许您在 VS 版本之间切换),但找到了一种不创建临时 bat 文件的方法。所以结果要简单得多。
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 "$@"
}
我建议将这些行添加到您的 .bash_functions 或类似的东西中,并在那里导出这些函数。这将允许您在 bash 脚本中使用函数。
export -f run_in_vs_env
export -f run_vs11
export -f run_vs10
然后你应该能够做到:
run_vs11 cl
我已经用我的vsvars32.bat
文件转换了我的文件visual_studio.env
文件。当我需要使用命令行 Visual Studio 的环境时,我只是做一个这个文件的来源。
在shell环境中,我sh
无法注册 Windows路径(\
并;
与sh
cygpath -au
cygpath -aup commands
.env
cygpath -aw
cygpath -aup commands
我的visual_studio.env
文件如下所示:
VS80COMNTOOLS=$(cygpath -aw '/cygdrive/c/Programmi/Microsoft Visual Studio 8/Common7/Tools/'); export VS80COMNTOOLS
VSINSTALLDIR=$(cygpath -aw '/cygdrive/c/Programmi/Microsoft Visual Studio 8'); export VSINSTALLDIR
VCINSTALLDIR=$(cygpath -aw '/cygdrive/c/Programmi/Microsoft Visual Studio 8/VC'); export VCINSTALLDIR
FrameworkDir=$(cygpath -aw '/cygdrive/c/WINDOWS/Microsoft.NET/Framework'); export FrameworkDir
FrameworkVersion='v2.0.50727'; export FrameworkVersion
FrameworkSDKDir=$(cygpath -aw '/cygdrive/c/Programmi/Microsoft Visual Studio 8/SDK/v2.0'); export FrameworkSDKDir
echo Setting environment for using Microsoft Visual Studio 2005 x86 tools.
DevEnvDir=$(cygpath -aw '/cygdrive/c/Programmi/Microsoft Visual Studio 8/Common7/IDE'); export DevEnvDir
PATH='/cygdrive/c/Programmi/Microsoft Visual Studio 8/Common7/IDE:/cygdrive/c/Programmi/Microsoft Visual Studio 8/VC/BIN:/cygdrive/c/Programmi/Microsoft Visual Studio 8/Common7/Tools:/cygdrive/c/Programmi/Microsoft Visual Studio 8/Common7/Tools/bin:/cygdrive/c/Programmi/Microsoft Visual Studio 8/VC/PlatformSDK/bin:/cygdrive/c/Programmi/Microsoft Visual Studio 8/SDK/v2.0/bin:/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727:/cygdrive/c/Programmi/Microsoft Visual Studio 8/VC/VCPackages':$PATH
INCLUDE=$(cygpath -awp '/cygdrive/c/Programmi/Microsoft Visual Studio 8/VC/ATLMFC/INCLUDE:/cygdrive/c/Programmi/Microsoft Visual Studio 8/VC/INCLUDE:/cygdrive/c/Programmi/Microsoft Visual Studio 8/VC/PlatformSDK/include:/cygdrive/c/Programmi/Microsoft Visual Studio 8/SDK/v2.0/include'); export INCLUDE
LIB=$(cygpath -awp '/cygdrive/c/Programmi/Microsoft Visual Studio 8/VC/ATLMFC/LIB:/cygdrive/c/Programmi/Microsoft Visual Studio 8/VC/LIB:/cygdrive/c/Programmi/Microsoft Visual Studio 8/VC/PlatformSDK/lib:/cygdrive/c/Programmi/Microsoft Visual Studio 8/SDK/v2.0/lib'); export LIB
LIBPATH=$(cygpath -awp '/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727:/cygdrive/c/Programmi/Microsoft Visual Studio 8/VC/ATLMFC/LIB'); export LIBPATH
我希望这可以帮助你。
另一种选择是打开 vcvars32.bat(或 vsvars32.bat,它在最新版本的 Visual Studio 中执行实际工作),查看它的作用,然后在适当的 shell 脚本中复制它。
它并不是特别复杂——它所做的只是设置了一堆环境变量。
我发现使用它是一个更好的策略,msbuild
同时我也可以使用g++
我的 cygwin 环境。这是一种更加综合的方法,并且与您现有的visual studio
开发和谐地融合在一起。使用最低级别cl
并设置环境变量是自找麻烦和逆风。msbuild
可以更好地为我们设置东西。此外,我可以逐步调试到具有完整*.vcxproj
项目的 IDE。
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
然后在你的 ~/.bashrc 中,有这个功能:
builddebug (){
[ $# -eq 0 ] && return 1;
msbuild /m /p:Configuration=Debug /p:Platform=Win32 "$1"
}
开发体验的感觉是这样的。至少,我能够以更好的集成方式使用g++
编译器和编译器。Visual Studio 2017
让我们msbuild
做它的事。不是cl
。
我无法在Diomidis 的回复中添加评论:(,所以不得不发布一个答案。我同意他的回答,但是“打开命令提示符”,运行 Visual Studio/vcvars32.bat
然后运行 Bash 会很乏味。如果您不必为弄乱环境而烦恼,最好的选择是对其进行修改Cygwin.bat
和修改,使其看起来像这样:
@echo off
D:
chdir D:\cygwin\bin
"%VS71COMNTOOLS%\vsvars32.bat" && bash --login -i
将环境变量 VS71COMNTOOLS 替换为您机器上合适的内容。
无需打开命令提示符并手动运行 Bash。我非常喜欢这个解决方案:)。我无法将功劳归于这个黑客的真正作者,因为我找不到返回他文章的链接,对此感到抱歉!
对我来说, .bash_profile 中的以下内容有效:
"`cygpath -ua "$VS80COMNTOOLS/vsvars32.bat"`" > NUL
我发现在 cygwin 环境中使用 msvc 编译东西非常有用的一个实用程序是我在Coin 3D库的源存储库中找到的一个包装器,称为“wrapmsvc”,它的二进制文件可以在这里找到。
该程序包装 cl.exe 并将任何指定的 GCC args 转换为适当的 cl.exe arg。它还使用 cygwin API 将文件路径从 cygwin 形式 (/cygdrive/c/temp/test.c) 正确转换为它的实际文件路径 (C:\temp\test.c)。
上次找了好久才找到源,不过它叫“wrapmsvc.cpp”,所以如果你需要编译它,找那个文件。如果您碰巧编译了它,并且收到了一些关于使用 cygwin_conv_to_posix_path 或 cygwin_conv_to_win32_path 的折旧警告/错误,请进行以下更改:
换行:
(void)cygwin_conv_to_posix_path(s.c_str(), buf);
至
(void)cygwin_conv_path(CCP_WIN_A_TO_POSIX, (const void *)s.c_str(), (void *)buf, (size_t)MAX_PATH);
并改变:
(void)cygwin_conv_to_win32_path(s.c_str(), buf);
至
(void)cygwin_conv_path(CCP_POSIX_TO_WIN_A, (const void *)s.c_str(), (void *)buf, (size_t)MAX_PATH);
我的 Igor 解决方案版本更简洁:
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
}
可惜vcvars64.bat需要反复调用。
其他答案都不适合我,但这确实:
转储环境变量:set > c:\temp\cl.env
打开 cygwin 命令提示符并创建一个source
脚本:
awk < /cygdrive/c/temp/cl.env -F= '{ if($1 !~ ")") print "export " $1 "=\x27" $2 "\x27" }' > cl.source
修改 cl.source 以将 TEMP 和 TMP 更改为 C:\Temp 例如TEMP='C:\Temp'
现在,无论何时需要 cl 环境,从 cygwin 提示符运行:
source cl.source
(可选)您的.bashrc文件中的源 cl.source 以在您登录时自动运行