msbuild: установить конкретный препроцессор #define в командной строке - PullRequest
18 голосов
/ 03 октября 2008

В файле C ++ у меня есть такой код:

#if ACTIVATE
#   pragma message( "Activated" )
#else
#   pragma message( "Not Activated")
#endif

Я хочу установить для этого ACTIVE определения значение 1 с помощью командной строки msbuild.

Он попробовал это, но это не работает:

msbuild /p:DefineConstants="ACTIVATE=1"

Есть идеи?

Ответы [ 11 ]

27 голосов
/ 08 января 2013

Я немного опоздал на вечеринку (всего 4 года или около того), но мне просто пришлось обойти эту проблему в проекте, и наткнулся на этот вопрос при поиске решения. Нашим решением было использование переменной среды в сочетании с полем Дополнительные параметры в Visual Studio.

  1. В Visual Studio добавьте макрос переменной среды $ (ExternalCompilerOptions) к дополнительным параметрам в параметрах проекта-> C / C ++ -> Командная строка (запомните обе конфигурации: Debug и Release)
  2. Установить переменную среды перед вызовом msbuild

    c:> set ExternalCompilerOptions = / DFOO / DBAR
    c:> msbuild

Элемент # 1 выглядит так в файле vcxproj:

<ClCompile>
  <AdditionalOptions>$(ExternalCompilerOptions) ... </AdditionalOptions>
</ClCompile>

Это работает для меня с VS 2010. Мы запускаем msbuild из различных скриптов сборки, поэтому уродство немного скрыто. Обратите внимание, что я не проверял, работает ли это, когда вам нужно установить определение на конкретное значение (/ DACTIVATE = 1). Я думаю, что это сработает, но я обеспокоен наличием нескольких '=.

H ^ 2

10 голосов
/ 03 октября 2008

C ++ проекты (и решения) еще не интегрированы в среду MSBuild. В процессе сборки вызывается задача VCBuild , которая является просто оболочкой для vcbuild.exe .

Вы могли бы:

  • создайте конкретную конфигурацию для вашего решения, в которой будет определен ACTIVATE=1, и скомпилируйте ее с помощью devenv.exe (с переключателем / ProjectConfig ).
  • создайте свой собственный целевой файл для переноса собственного вызова в задачу VCBuild (см. Параметр Override) ...
  • использовать vcbuild.exe вместо msbuild.exe. (vcbuild.exe, похоже, не имеет эквивалента параметра Override).

Обратите внимание, что ваше решение не будет работать и для проектов на C #, если вы не настроите файлы проекта немного. Для справки вот как бы я это сделал:

  • Добавьте следующий код перед звонком на <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />:
<PropertyGroup Condition=" '$(MyConstants)' != '' ">
  <DefineConstants>$(DefineConstants);$(MyConstants)</DefineConstants>
</PropertyGroup>
  • Вызовите MSBuild следующим образом:
msbuild /p:MyConstants="ACTIVATE=1"
9 голосов
/ 03 октября 2008

Я думаю, что вы хотите:

/p:DefineConstants=ACTIVATE
8 голосов
/ 01 апреля 2013

Если вам нужно определить некоторую константу (а не просто true / false), вы можете сделать это следующим образом:

В командной строке:

MSBuild /p:MyDefine=MyValue

В файле vcxproj (в разделе и / или , в зависимости от того, где он вам нужен):

<PreprocessorDefinitions>MY_DEFINE=$(MyDefine);$(PreprocessorDefinitions)</PreprocessorDefinitions>
1 голос
/ 03 апреля 2018

Используйте переменную среды CL для определения макросов препроцессора

Перед вызовом MSBUILD просто установите переменную окружения 'CL' с параметрами / D, например:

set CL=/DACTIVATE для определения ACTIVATE

Вы можете использовать символ «#» для замены знака «=»

set CL=/DACTIVATE#1 определит ACTIVATE = 1

Тогда позвоните в MSBUILD

Дополнительную документацию по переменным среды CL можно найти по адресу: https://msdn.microsoft.com/en-us/library/kezkeayy(v=vs.140).aspx

1 голос
/ 05 марта 2018

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

В соответствии с проблемой @ acemtp мое решение будет выглядеть так:

@echo off

:: it is considered that Visual Studio tools are in the PATH
if "%1"=="USE_ACTIVATE_MACRO" (
    :: if parameter USE_ACTIVATE_MACRO is passed to script
    :: the macro ACTIVATE will be defined for the project
    set CL=/DACTIVATE#1
)
call msbuild /t:Rebuild /p:Configuration=Release

UPD: я пытался использовать set CL=/DACTIVATE=1, и это также работало, но официальная документация рекомендует использовать знак номера

0 голосов
/ 23 августа 2017

Как упомянул @ bigh_29, использование переменных среды для определения или отмены определения препроцессора.

То, что он предложил, чтобы определить неопределенность препроцессора, на самом деле / U ACTIVATE.

Таким образом, любой препроцессор, соответствующий ACTIVATE, будет отменен, и компилятор не будет проходить через ваш #if ACTIVATE #endif корпус.

0 голосов
/ 03 июля 2013

Для VS2010 и выше, см. Мой ответ здесь для решения, которое не требует модификации исходного файла проекта.

0 голосов
/ 20 февраля 2009

Мне тоже нужно было это сделать - мне нужно было собрать две разные версии моего приложения, и я хотел иметь возможность создавать сценарии сборки, используя VCBUILD. В VCBUILD есть переключатель командной строки / override, но я не уверен, что его можно использовать для изменения символов #define, которые затем можно проверить с помощью условной компиляции #if.

Решение, с которым я столкнулся, состояло в том, чтобы написать простую утилиту для создания заголовочного файла, который # определял символ на основе состояния переменной среды и запускала утилиту с шага перед сборкой. Перед каждым выполнением шага VCBUILD сценарий устанавливает переменную среды и «касается» файла в приложении, чтобы гарантировать выполнение шага предварительной сборки.

Да, это безобразный хак, но это было лучшее, что я мог придумать!

0 голосов
/ 07 октября 2008

Ответ: ВЫ НЕ МОЖЕТЕ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...