Вызов cl.exe (компилятор MSVC) в оболочке Cygwin

Я активно использую Cygwin (с оболочкой PuTTY ). Но довольно сложно вызвать cl.exe(то есть, набор инструментов компилятора Visual C ++) в оболочке Cygwin Bash. Запуск vcvars*.batв оболочке Bash, очевидно, не работает. Я пытался перенести переменные окружения VC ++ в Cygwin, но это не так просто.

Как запустить компилятор VC ++ в оболочке Cygwin Bash?

14.12.2008 20:12:52
Ted 5.06.2009 15:37:10
Моя программа wrapmsvc [ code.google.com/p/wrapmsvc ] может оказаться полезной. Это обертка для вызова cl.exe и других инструментов MS из Linux через Wine; он переводит пути в стиле Unix в пути Wine в стиле Windows и запускает реальный инструмент через Wine. Это означает, что вы можете вызывать компилятор с путями Unix, не путая реальный компилятор. Конечно, это не сработает в Cygwin, потому что там нет Wine, но вы можете изменить его так, чтобы он не использовал Wine и вместо этого выполнял преобразование пути другим способом.
Ambroz Bizjak 23.04.2012 11:41:50
12 ОТВЕТОВ

Я понимаю, что ваша проблема заключается в преобразовании vcvars32.bat в сценарий оболочки.

Один из способов решения этой проблемы основан на идее, что переменные среды наследуются, когда один процесс запускает другой. Таким образом, вы можете просто запустить vcvars32 под cmd, а затем запустить 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... ]

Либо запустите set до и после вызова vcvars32 в cmd, а затем создайте сценарий оболочки для установки переменных среды.

13
14.12.2008 20:18:55
Если вы не хотите всегда использовать определенную версию MSC при запуске Cygwin или не хотите использовать ее каждый раз, когда этот простой вариант является лучшим.
Simon Sobisch 8.11.2016 09:12:25

Другая альтернатива - открыть vcvars32.bat (или vsvars32.bat, который реально работает в последней версии Visual Studio), посмотреть, что он делает, и скопировать его в соответствующий сценарий оболочки.

Это не особенно сложно - все, что он делает, это устанавливает кучу переменных среды.

2
14.12.2008 20:44:06

Я преобразовал свой vsvars32.batфайл с моим visual_studio.envфайлом. Когда мне нужно использовать среду командной строки Visual Studio, я просто делаю источник этого файла.

В 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

Я надеюсь это тебе поможет.

2
23.04.2012 11:33:24

Я обычно решаю это, добавляя

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... ]

Обратите внимание на версию компилятора.

25
17.12.2008 12:35:51
Для Visual Studio 2008 - вызов "% VS90COMNTOOLS% vsvars32.bat"
Tim Ring 28.06.2012 10:47:42
Я должен был изменить ваш «echo call ...» на это, echo "call \"%$batfile%..\\..\\VC\\vcvarsall.bat\" amd64 >NUL:" >> $tmpfileчтобы подобрать правильную версию компилятора для сборки кода x64.
DigitalEye 18.07.2014 22:33:25
Я изменил функцию run_with_bat только на первую строку, и это: cmd /c call "${!batfile}vsvars32.bat" \&\& bash -c "$*"которая прекрасно работает для меня без временных файлов. Оригинальная версия доставляла мне проблемы с пробелами в «Program Files (x86)».
contero 9.01.2015 06:52:10
Смотрите ответ Игоря ниже для лучшего варианта второго варианта.
Simon Sobisch 8.11.2016 09:13:09

Я не мог добавить комментарии к ответу Диомидиса :(, поэтому пришлось публиковать ответ. Я согласен с его ответом, но было бы утомительно делать «открыть командную строку», запустить Visual Studio /, vcvars32.batа затем запустить Bash. Если Вы не беспокоитесь о том, чтобы загромождать свою среду, лучшая альтернатива - изменить Cygwin.batи модифицировать ее, чтобы она выглядела примерно так:

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

Замените переменную среды VS71COMNTOOLS на что-то подходящее на вашей машине.

Нет необходимости открывать командную строку и запускать Bash вручную. Мне очень нравится это решение :). Я не мог отдать должное настоящему автору этого взлома, так как не смог найти ссылку на его статью, извините за это!

0
23.05.2017 12:25:15

Для меня следующее в .bash_profile работает:

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

0
8.07.2009 10:05:12
Это не сработало для меня. Хотя он работает нормально, переменные среды, которые он устанавливает, похоже, не распространяются обратно в оболочку.
Brooks Moses 17.07.2010 15:55:58

Следуя предложениям, приведенным в других ответах, я проверил результаты своего «набора» bash с переменными MSVC и без них и предложил следующий сценарий, чтобы воспроизвести их для моей установки 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"
12
18.07.2010 05:44:51
К сожалению, это лучшее решение, которое я нашел.
Mark Beckwith 9.05.2012 17:54:08

Одна утилита, которую я нашел довольно неоценимой для компиляции msvc из среды cygwin, - это обертка, которую я нашел в исходном репозитории Coin 3D- библиотеки под названием «wrapmsvc», бинарный файл которого можно найти здесь .

Программа упаковывает файл cl.exe и преобразует все указанные аргументы GCC в соответствующий аргумент cl.exe. Он также использует 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);
0
10.01.2012 01:10:06

Я фактически использовал ответ 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
6
23.10.2019 11:11:14
очень аккуратное решение действительно!
malat 23.05.2014 12:18:02
Вызов cmd / Q / C "C: \ Program Files (x86) \ Microsoft Visual Studio \ 2019 \ Community \ VC \ Auxiliary \ Build \ vcvars64.bat" && $ {@: 2} Я запустил это, выполнил нормально, все еще cl .exe не может найти включить PATH :(
ericcurtin 23.10.2019 09:03:01
@ericcurtin: он должен называться так run_vs11 cl. Строка с cmdиспользует аргументы run_in_vs_envфункции. Аргументы ${@:2}- это просто ваша команда для выполнения. Попробуйте заменить ${@:2}на ваш clзвонок или как хотите, и он должен работать нормально.
Igor Mikushkin 23.10.2019 11:07:26
Тем временем я разобрался, спасибо Игорю
ericcurtin 23.10.2019 11:09:09

Я считаю, что это лучшая стратегия для использования, msbuildи в то же время я также могу использовать g++свою среду Cygwin. Это более комплексный подход, который гармонично сочетается с существующими visual studioразработками. Использование самого низкого уровня clи установка переменных окружения порождает проблемы и идет против ветра. msbuildМожет лучше настройки вещи для нас. Кроме того, я могу выполнить пошаговую отладку в интегрированной среде разработки, имеющей полный *.vcxprojпроект.

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.

1
10.11.2018 07:27:30

Ни один из других ответов не работал для меня, но это сделало:

  1. Запустите «Командная строка компоновки MS»

введите описание изображения здесь

  1. сбросить env vars: 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. При желании, источник cl.source в вашем файле .bashrc будет запускаться автоматически при входе в систему.

0
3.12.2019 03:29:01

Моя версия решения Игоря, она короче

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 нужно вызывать многократно.

0
23.10.2019 09:18:52