Ответ 1
Ответ: ВЫ НЕ МОЖЕТЕ
В файле С++ у меня есть такой код:
#if ACTIVATE
# pragma message( "Activated" )
#else
# pragma message( "Not Activated")
#endif
Я хочу установить этот ACTIVE define в 1 с командной строкой msbuild.
Он пробовал это, но он не работает:
msbuild /p:DefineConstants="ACTIVATE=1"
Любая идея?
Ответ: ВЫ НЕ МОЖЕТЕ
Я немного опоздал на вечеринку (всего 4 года или около того), но мне просто пришлось обойти эту проблему в проекте, и наткнулся на этот вопрос в поисках решения. Наше решение состояло в том, чтобы использовать переменную окружения, в которой определены /D
в сочетании с полем Дополнительные параметры в Visual Studio.
$(ExternalCompilerOptions)
к дополнительным параметрам в проекте options-> C/C++-> Командная строка (запомните обе конфигурации: Debug и Release)/D
для определения ваших макросов c:\> set ExternalCompilerOptions=/DFOO /DBAR
c:\> msbuild
Элемент # 1 выглядит так в файле vcxproj:
<ClCompile>
<AdditionalOptions>$(ExternalCompilerOptions) ... </AdditionalOptions>
</ClCompile>
Это работает для меня с VS 2010. Мы запускаем msbuild из различных сценариев сборки, поэтому уродливость переменной среды немного скрыта. Обратите внимание, что я не проверял, работает ли это, когда вам нужно установить определение на конкретное значение (/DACTIVATE=1
). Я думаю, что это сработает, но я обеспокоен наличием множества '= там.
H ^ 2
Проекты С++ (и решения) не интегрированы в среду MSBuild (пока?). В рамках процесса сборки вызывается задача VCBuild, которая является всего лишь оберткой vcbuild.exe.
Вы можете:
ACTIVATE=1
будет определена, и скомпилируйте ее с помощью devenv.exe (с /ProjectConfig).Обратите внимание, что ваше решение не будет работать для проектов С# либо, если вы немного измените файлы проекта. Для справки, вот как я сделал бы это:
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
:<PropertyGroup Condition=" '$(MyConstants)' != '' "> <DefineConstants>$(DefineConstants);$(MyConstants)</DefineConstants> </PropertyGroup>
msbuild /p:MyConstants="ACTIVATE=1"
Я думаю, вы хотите:
/p:DefineConstants=ACTIVATE
Если вам нужно определить некоторую константу (не просто true/false), вы можете сделать это следующим образом:
В командной строке:
MSBuild /p:MyDefine=MyValue
В файле vcxproj (в разделе <ClCompile> и/или <ResourceCompile> , в зависимости от того, где он вам нужен):
<PreprocessorDefinitions>MY_DEFINE=$(MyDefine);$(PreprocessorDefinitions)</PreprocessorDefinitions>
Может быть, это плохая идея, чтобы ответить на такой старый вопрос, но недавно я погуглил похожую проблему и нашел эту тему. Я написал сценарий 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
и это тоже сработало, но официальная документация рекомендует использовать числовой знак
Используйте переменную среды 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.
Мне тоже нужно было сделать это - нужно было создать две разные версии моего приложения и захотелось иметь возможность script сборки с помощью VCBUILD. У VCBUILD есть ключ командной строки /override, но я не уверен, что его можно использовать для изменения символов #define, которые затем могут быть протестированы с использованием условной компиляции #if.
Решение, с которым я работал, заключалось в том, чтобы написать простую утилиту для создания файла заголовка, который #defined символ на основе состояния переменной окружения и запуска утилиты с этапа предварительной сборки. Перед каждым выполнением шага VCBUILD script устанавливает переменную окружения и "затрагивает" файл в приложении, чтобы убедиться, что выполняется шаг предварительной сборки.
Да, это уродливый взлом, но это было лучшее, что я мог придумать!
Для VS2010 и выше см. мой ответ здесь для решения, которое не требует модификации исходного файла проекта.
Как @bigh_29 упомянул, используя переменные среды для определения или декомпрессии препроцессора.
То, что он предложил, чтобы определить препроцессор, на самом деле /U АКТИВИРОВАТЬ.
Таким образом, любой препроцессор, соответствующий ACTIVATE, будет сбрасываться, а компилятор не будет проходить через ваш #if ACTIVATE #endif.
Вероятно, это должно быть:
#ifdef ACTIVATE
# pragma message( "Activated" )
#else
# pragma message( "Not Activated")
#endif