Как установить PreProcessorDefinitions как свойство задачи для задачи msbuild

следующее взято из обычного проекта 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 etc.

однако, если я использую следующее

  <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 etc. Если я использую обычную настройку и пытаюсь вывести PreprocessorDefinitions используя <Message Text="PreprocessorDefinitions: $(PreprocessorDefinitions)" поле фактически пустое и не содержит ожидаемого <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> хотя я могу использовать любой из этих ключей для управления мои построения с помощью #ifdef etc.

  1. почему это?
  2. что я могу сделать, чтобы передать PreprocessorDefinitions für проект VS2010 C++ через задачи Properties элемент?

2 ответов


вы не можете сделать это без изменения demo.vcxproj потому что вам нужен доступ к PreprocessorDefinitions of CLCompile, не PropertyGroup, и, таким образом, не может быть передан через командную строку MSBuild.

вы можете изменить определения препроцессора в GUI через Свойства Проекта - > Свойства Конфигурации -> 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

это можно сделать без изменения исходного проекта: Первое, что сделано в Microsoft.Cpp.Targets, что обычно является одной из последних вещей, импортируемых в обычный проект C++, - это проверить, есть ли свойство с именем ForceImportBeforeCppTargets и если да, импортируйте его.

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