Invoking cl.exe (MSVC compiler) in Cygwin shell

前端 未结 12 2216
执念已碎
执念已碎 2020-12-04 16:50

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

相关标签:
12条回答
  • 2020-12-04 17:26

    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.

    0 讨论(0)
  • 2020-12-04 17:34

    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
    
    0 讨论(0)
  • 2020-12-04 17:37

    None of the other answers worked for me, but this did:

    1. Run "MS Build Command Prompt"

    1. dump the env vars: set > c:\temp\cl.env

    2. 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
    
    1. Modify cl.source to change TEMP and TMP to C:\Temp e.g. TEMP='C:\Temp'

    2. Now, whenever you need the cl environment, from your cygwin prompt run: source cl.source

    3. Optionally, source cl.source in your .bashrc file to run automatically when you log in

    0 讨论(0)
  • 2020-12-04 17:38

    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);
    
    0 讨论(0)
  • 2020-12-04 17:39

    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.

    0 讨论(0)
  • 2020-12-04 17:39

    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.

    0 讨论(0)
提交回复
热议问题