如何设置PreProcessorDefinitions作为MSBuild任务任务属性格式(How t

2019-07-20 17:57发布

下面是从一个普通VS2010 C ++项目采取。

    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>

如果我编辑PreprocessorDefinitions我可以设置所使用的预处理器的定义。 我可以通过我的代码里发现#ifdef等。

但是,如果我用下面的

  <Target Name="NormalBuild" Condition=" '$(_InvalidConfigurationWarning)' != 'true' " DependsOnTargets="_DetermineManagedStateFromCL;CustomBeforeBuild;$(BuildDependsOn)" Returns="@(ManagedTargetPath)">
    <ItemGroup>
        <ManagedTargetPath Include="$(TargetPath)" Condition="'$(ManagedAssembly)' == 'true'" />
    </ItemGroup>
      <Message Text="PreprocessorDefinitions: $(PreprocessorDefinitions)" Importance="High" />
  </Target>

  <Target Name="TestBuild" Returns="@(ManagedTargetPath)">
    <MSBuild Projects="demo.vcxproj" Targets="NormalBuild" Properties="PreprocessorDefinitions=THISGETSSETBUTDOESNOTHING"/>
  </Target>

我还可以通过该消息看PreprocessorDefinitions包含我通过设定值Properties="PreprocessorDefinitions=THISGETSSETBUTDOESNOTHING" ,但使用我无法控制我的构建#ifdef等。如果我使用的是常规的设置,并尝试输出PreprocessorDefinitions使用<Message Text="PreprocessorDefinitions: $(PreprocessorDefinitions)"的字段实际上是空白,不包含预期<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>虽然我可以使用这些键中的任何一个使用,以控制我的生成#ifdef等。

  1. 这是为什么?
  2. 我能做些什么来传递PreprocessorDefinitions通过任务皮毛VS2010 C ++项目Properties元素?

Answer 1:

而不需要修改你不能做到这一点demo.vcxproj ,因为你需要访问PreprocessorDefinitionsCLCompile ,这不是PropertyGroup ,从而无法通过MSBuild的命令行传递。

您可以修改通过项目属性的GUI预处理器定义- >配置Propertis - > C / C ++ - >预处理器 ,或直接编辑XML:

  <ClCompile>
    ....
    <PreprocessorDefinitions>$(MyMacro);%(PreprocessorDefinitions)</PreprocessorDefinitions>
  </ClCompile>

在您的MSBuild项目:

  <Target Name="TestBuild" Returns="@(ManagedTargetPath)">
    <MSBuild Projects="demo.vcxproj" Targets="NormalBuild" Properties="MyMacro=THISGETSSETBUTDOESNOTHING"/>
  </Target>

这相当于运行MSBuild.exe为:

  MSBuild demo.vcxproj /p:MyMacro=THISGETSSETBUTDOESNOTHING


Answer 2:

这可以在不改变原有的项目来完成:在做的第一件事Microsoft.Cpp.Targets ,通常是在一个普通的C ++项目进口的最后一件事,是检查是否有一个属性调用ForceImportBeforeCppTargets如果有的话,导入它。

因此,假设您要添加ADDITIONAL到你创建一个文件“override.props”像这样的(全自动化使用预处理器定义WritelinesToFile任务创建文件):

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <ItemDefinitionGroup>
    <ClCompile>
      <PreprocessorDefinitions>%(PreprocessorDefinitions);ADDITIONAL</PreprocessorDefinitions>
    </ClCompile>
  </ItemDefinitionGroup>

</Project>

和通话

<MSBuild Projects="demo.vcxproj" 
         Properties="ForceImportBeforeCppTargets=override.props"/>

或通过命令行,这将是

msbuild demo.vcxproj /p:ForceImportBeforeCppTargets=override.props

注意为richb指出的评论,如果override.props可以通过的MSBuild的查找规则中找到以上才有效。 为了确保它总是发现,只有指定的完整路径。



Answer 3:

基于@Kevin答案,你需要在的PropertySheet定义一个用户定义的宏。 然后创建它指的是用户定义的宏的预处理器。 现在,您可以在代码中使用新的预处理值。 最后,对于构建,您可以更改与用户自定义宏的值/p标志。 在这里我定义就像一个用户定义的值mymacro又像预处理值VAL 。 现在,你可以简单地编译工程/p:mymacro="\"some thing new\""

#include <iostream>


int main() {
    std::cout << VAL << std::endl;

    getchar();
}

yourproject.vcxproj

<ClCompile>
  ...
  <PreprocessorDefinitions>VAL=$(mymacro);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>

msbuild yourproject.vcxproj /p:mymacro="\"some thing new\""



文章来源: How to set PreProcessorDefinitions as a task propery for the msbuild task
标签: msbuild