以下内容来自常规的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
等
Properties
元素传递VS2010 C ++项目的PreprocessorDefinitions?答案 0 :(得分:32)
这可以在不修改原始项目的情况下完成:在Microsoft.Cpp.Targets
中完成的第一件事,通常是在普通C ++项目中导入的最后一件事,是检查是否有一个名为{{1的属性如果是这样,请导入它。
因此,假设您要将ForceImportBeforeCppTargets
添加到预处理器定义中,您可以像这样创建文件'override.props'(完全自动化使用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"/>
注意作为richb在注释中指出,只有在msbuild的查找规则可以找到override.props时,上述方法才有效。要确保始终找到它,只需指定完整路径。
答案 1 :(得分:8)
如果不修改demo.vcxproj
,则无法执行此操作,因为您需要访问PreprocessorDefinitions
的{{1}},而CLCompile
不是PropertyGroup
,因此无法访问 <ClCompile>
....
<PreprocessorDefinitions>$(MyMacro);%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
通过MSBuild命令行传递。
您可以通过项目属性 - &gt;修改GUI中的预处理器定义。配置属性 - &gt; C / C ++ - &gt;预处理器,或直接编辑XML:
<Target Name="TestBuild" Returns="@(ManagedTargetPath)">
<MSBuild Projects="demo.vcxproj" Targets="NormalBuild" Properties="MyMacro=THISGETSSETBUTDOESNOTHING"/>
</Target>
在您的MSBuild项目中:
MSBuild demo.vcxproj /p:MyMacro=THISGETSSETBUTDOESNOTHING
这相当于将MSBuild.exe作为:
运行{{1}}
答案 2 :(得分:1)
基于@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\""