How to configure PreProcessor Definitions as a task property for the msbuild task

advertisements

The following is taken from a regular VS2010 C++ project.

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

If i edit PreprocessorDefinitions i can set a definition that is used by the preprocessor. I can see this in my code via #ifdef etc.

However if i use the following

  <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>

i can also see via the message that PreprocessorDefinitions contains the value i set via Properties="PreprocessorDefinitions=THISGETSSETBUTDOESNOTHING" but i can not control my build using #ifdef etc. If i use a regular setup and try to output PreprocessorDefinitions using <Message Text="PreprocessorDefinitions: $(PreprocessorDefinitions)" the field is actually blank and does not contain the expected <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> although i can use any one of those keys to control my build using #ifdef etc.

  1. Why is that?
  2. What can i do to pass PreprocessorDefinitions für a VS2010 C++ Project via the tasks Properties element?

You can't do this without modifying demo.vcxproj because you need access to the PreprocessorDefinitions of CLCompile, which is not a PropertyGroup, and thus can't be passed via the MSBuild command line.

You can modify the preprocessor definitions in the GUI via Project Properties -> Configuration Propertis -> C/C++ -> Preprocessor, or edit the XML directly:

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

In your MSBuild project:

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

This is equivalent to running MSBuild.exe as:

  MSBuild demo.vcxproj /p:MyMacro=THISGETSSETBUTDOESNOTHING