msbuild:在命令行中设置一个特定的预处理器#define

时间:2008-10-03 11:47:25

标签: c++ visual-studio msbuild

在C ++文件中,我有一个这样的代码:

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

我想使用msbuild命令行将此ACTIVE定义设置为1。

尝试了这个但是它不起作用:

msbuild /p:DefineConstants="ACTIVATE=1"

有什么想法吗?

11 个答案:

答案 0 :(得分:27)

我参加派对有点晚了(仅仅4年左右),但我只是在一个项目上解决了这个问题,并在搜索解决方案时偶然发现了这个问题。我们的解决方案是使用环境变量和visual studio中的Additional Options框。

  1. 在Visual Studio中,将环境变量宏$(ExternalCompilerOptions)添加到项目选项下的其他选项 - > C / C ++ - >命令行(记住调试和发布配置)
  2. 在调用msbuild之前设置环境变量

    C:GT;设置ExternalCompilerOptions = / DFOO / DBAR
    C:GT;的msbuild

  3. 项目#1在vcxproj文件中看起来像这样:

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

    这适用于VS 2010.我们从各种构建脚本驱动msbuild,因此丑陋隐藏了一点。请注意,当您需要将define设置为特定值(/ DACTIVATE = 1)时,我还没有测试它是否有效。我认为它会起作用,但我担心在那里有多个'='。

    H ^ 2

答案 1 :(得分:10)

C ++项目(和解决方案)还没有(还有?)集成在MSBuild环境中。作为构建过程的一部分,调用VCBuild task,它只是vcbuild.exe的包装。

你可以:

  • 为您的解决方案创建一个特定的配置,其中ACTIVATE=1将被定义,并使用devenv.exe(使用/ProjectConfig开关)进行编译。
  • 创建您自己的目标文件以将您自己的调用包装到VCBuild task(请参阅覆盖参数)...
  • 使用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"

答案 2 :(得分:9)

我想你想要:

/p:DefineConstants=ACTIVATE

答案 3 :(得分:8)

如果你需要定义一些常量(不仅仅是真/假),你可以通过以下方式实现:

在命令行上:

MSBuild /p:MyDefine=MyValue

在vcxproj文件中(在&lt; ClCompile&gt;和/或&lt; ResourceCompile&gt;部分中,取决于您需要的位置):

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

答案 4 :(得分:1)

回答这个老问题也许是一个坏主意,但最近我搜索了一个类似的问题并找到了这个话题。我为一些构建系统编写了一个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并且它也有效,但official documentation建议使用数字符号

答案 5 :(得分:1)

使用CL环境变量定义预处理器宏

在致电MSBUILD之前,只需设置环境变量&#39; CL&#39;用&#39; / D&#39;像这样的选项:

set CL=/DACTIVATE定义ACTIVATE

您可以使用&#39;#&#39;要替换的符号&#39; =&#39;登录

set CL=/DACTIVATE#1将定义ACTIVATE = 1

然后拨打MSBUILD

有关CL环境变量的更多文档,请访问: https://msdn.microsoft.com/en-us/library/kezkeayy(v=vs.140).aspx

答案 6 :(得分:0)

我也需要这样做 - 需要能够构建我的应用程序的两个不同版本,并希望能够使用VCBUILD编写脚本。 VCBUILD确实有/ override命令行开关,但我不确定它是否可用于修改#define符号,然后可以使用#if条件编译进行测试。

我提出的解决方案是编写一个简单的实用程序来创建一个头文件,该头文件根据环境变量的状态定义符号,并从预构建步骤运行该实用程序。在每次执行VCBUILD步骤之前,脚本设置环境变量并“触摸”应用程序中的文件以确保执行预构建步骤。

是的,这是一个丑陋的黑客,但这是我能想到的最好的!

答案 7 :(得分:0)

对于VS2010及更高版本,请参阅我的回答here以获取不需要修改原始项目文件的解决方案。

答案 8 :(得分:0)

正如@ bigh_29所提到的,使用环境变量来定义或取消定义预处理器。

他建议取消定义预处理器的方法实际上是 / U ACTIVATE。

这样,任何匹配ACTIVATE的预处理器都将被否定,编译器不会通过你的#if ACTIVATE #endif附件。

答案 9 :(得分:-1)

应该是:

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

答案 10 :(得分:-2)

答案是:你不能