下面是从一个普通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
等。
- 这是为什么?
- 我能做些什么来传递PreprocessorDefinitions通过任务皮毛VS2010 C ++项目
Properties
元素?
而不需要修改你不能做到这一点demo.vcxproj
,因为你需要访问PreprocessorDefinitions
的CLCompile
,这不是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
这可以在不改变原有的项目来完成:在做的第一件事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的查找规则中找到以上才有效。 为了确保它总是发现,只有指定的完整路径。
基于@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\""