Msbuild: установить в командной строке определенный препроцессор #define

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

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

Я хочу установить этот ACTIVE define в 1 с командной строкой msbuild.

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

msbuild /p:DefineConstants="ACTIVATE=1"

Любая идея?

Ответы

Ответ 1

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

Ответ 2

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

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

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

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

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

H ^ 2

Ответ 3

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

Вы можете:

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

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

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

Ответ 4

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

/p:DefineConstants=ACTIVATE

Ответ 5

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

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

MSBuild /p:MyDefine=MyValue

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

<PreprocessorDefinitions>MY_DEFINE=$(MyDefine);$(PreprocessorDefinitions)</PreprocessorDefinitions>

Ответ 6

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

Ответ 7

Используйте переменную среды 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.

Ответ 8

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

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

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

Ответ 9

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

Ответ 10

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

То, что он предложил, чтобы определить препроцессор, на самом деле /U АКТИВИРОВАТЬ.

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

Ответ 11

Вероятно, это должно быть:

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