在Cygwin shell中调用cl.exe(MSVC编译器)

时间:2008-12-14 20:12:52

标签: visual-c++ cygwin

我大量使用Cygwin(PuTTY shell)。但是,在Cygwin Bash shell中调用cl.exe(即Visual C ++编译器工具链)非常棘手。在Bash shell中运行vcvars*.bat显然不起作用。我试图将VC ++的环境变量迁移到Cygwin,但这并不容易。

如何在Cygwin的Bash shell中运行VC ++编译器?

12 个答案:

答案 0 :(得分:25)

我通常通过添加

来解决这个问题
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... ]

请注意编译器版本。

答案 1 :(得分:12)

根据其他答案中的建议,我使用和不使用MSVC变量进行了bash“set”结果的差异,并提出了以下脚本来重现它们以安装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"

答案 2 :(得分:11)

据我所知,您的问题是将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脚本来设置环境变量。

答案 3 :(得分:6)

我实际上使用了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

答案 4 :(得分:2)

我已将vsvars32.bat文件转换为visual_studio.env文件。当我需要使用命令行Visual Studio的环境时,我只是做了这个文件的来源。

sh shell环境中,我无法注册Windows路径(\;sh冲突) 在我使用cygpath -aucygpath -aup commands对其进行翻译之前,我会将其写入我的.env文件,并使用cygpath -awcygpath -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

我希望这可以帮到你。

答案 5 :(得分:2)

另一种方法是打开vcvars32.bat(或vsvars32.bat,它在最近的Visual Studio版本中完成工作),查看它的功能,并在相应的shell脚本中复制它。

它并不是特别复杂 - 它只是设置了一堆环境变量。

答案 6 :(得分:1)

我发现使用msbuild是更好的策略,然后同时我也可以在我的cygwin环境中使用g++。它是一种更加集成的方法,可以与您现有的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"
}

开发经验的感觉就像this。至少,我能够以更好的集成方式使用g++编译器和Visual Studio 2017编译器。让msbuild做它的事情。不是cl

答案 7 :(得分:0)

我无法向Diomidis's reply添加评论:(因此必须发布答案。 我同意他的回答,但做“打开命令提示符”,运行Visual Studio / vcvars32.bat然后运行Bash将会很繁琐。如果您不打扰混乱环境,最好的选择是修改Cygwin.bat并将其修改为如下所示:

@echo off
D:
chdir D:\cygwin\bin
"%VS71COMNTOOLS%\vsvars32.bat" && bash --login -i

用你机器上适当的东西替换环境变量VS71COMNTOOLS。

无需打开命令提示符并手动运行Bash。我很喜欢这个解决方案:)。我无法给这个黑客的真正作者提供信用,因为我找不到回复他的文章的链接,抱歉这个!

答案 8 :(得分:0)

没有其他答案对我有用,但这确实做到了:

  1. 运行“ MS Build命令提示符”

enter image description here

  1. 转储环境变量:set > c:\temp\cl.env

  2. 打开cygwin命令提示符并创建一个source脚本:

awk < /cygdrive/c/temp/cl.env -F= '{ if($1 !~ ")") print "export " $1 "=\x27" $2 "\x27" }' > cl.source
  1. 修改cl.source以将TEMP和TMP更改为C:\ Temp例如TEMP='C:\Temp'

  2. 现在,每当需要cl环境时,从cygwin提示符运行: source cl.source

  3. (可选),您的 .bashrc 文件中的源cl.source在您登录时自动运行

答案 9 :(得分:0)

对我来说,.bash_profile中的以下内容有效:

"`cygpath -ua "$VS80COMNTOOLS/vsvars32.bat"`" > NUL

答案 10 :(得分:0)

我发现在cygwin环境中用msvc编译东西非常宝贵的一个实用程序是我在Coin 3D库的源代码库中找到的名为“wrapmsvc”的包装器,可以找到谁的二进制文件here。 / p>

程序包装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);

答案 11 :(得分:0)

我的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。