背景:我有几个解决方案,其中包含大约300个C ++项目,其中大多数都是共享的。我们正在使用Visual Studio 2013,并具有一个生成脚本,该脚本以正确的顺序编译所有项目,以确保提前解决依赖关系。我们的开发/工程团队通过构建脚本来构建所有代码,然后尝试使用Visual Studio 2013进行调试。
问题:Visual Studio中的“先构建然后调试”过程会告诉我们项目已过时。这源于ProjectEvaluationFingerprint属性(在Microsoft.CppBuild.targets第39行中),在输出文件中包含$(SolutionDir)
。 recommended fix from Microsoft建议从文件中删除$(SolutionDir)
。由于我们的开发人员倾向于在项目之间来回切换,因此,我不想在每个开发人员的计算机上手动更改此.targets文件(记住,他们离开项目时请改回来)。我想通过为此显式使用.targets文件来覆盖.vcxproj中的属性。
Microsoft.CppBuild.targets中的属性如下所示:
<!-- Global up-to-date check support -->
<PropertyGroup>
<ProjectEvaluationFingerprint>$(Configuration)|$(Platform)|$(SolutionDir)|$(ProjectEvaluationFingerprint)</ProjectEvaluationFingerprint>
</PropertyGroup>
通常,我一直在关注Microsoft的How to: Use the Same Target in Multiple Project Files。我创建了一个.targets文件(
test.targets
),其中包含以下代码(请注意,TEST文本是为了在构建脚本和Visual Studio中构建项目时测试该属性的评估):<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectEvaluationFingerprint>$(Configuration)|$(Platform)|TEST|$(ProjectEvaluationFingerprint)</ProjectEvaluationFingerprint>
</PropertyGroup>
然后,我在.vcxproj中使用以下行将其导入
<Import Project="..\..\Config\VSPropertySheets\test.targets" />
project.lastbuildstate文件现在显示为:
#TargetFrameworkVersion=v4.0:PlatformToolSet=v120_xp:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit
Debug|Win32|D:\views\devbranch\Products\SLN\|Debug|Win32|TEST|
它会将新的ProjectEvaluationFingerprint附加到现有的指纹上,因此它并不构成替代(我可以一定程度地理解这一点,但我不是MSBuild专家)。
问题:如何使用.targets文件覆盖此一个属性?我需要使用replaceregexp task还是更简单的选择?
最佳答案
您可以覆盖此属性,但必须注意两点:
您想要的新设置是这样的:<ProjectEvaluationFingerprint>$(Configuration)|$(Platform)|TEST/ProjectEvaluationFingerprint>
请注意删除$(ProjectEvaluationFingerprint)
,其中将包含此标记的先前值
放置导入的位置很重要:您需要将其放置在项目的最后(即Microsoft.CppBuild.targets
导入之后)。
具体来说:
use_custom_fingerprint.targets
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <ProjectEvaluationFingerprint>$(Configuration)|$(Platform)</ProjectEvaluationFingerprint> </PropertyGroup> </Project>
project.vcxproj
<Project ...> ... <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> <Import Project="use_custom_fingerprint.targets" /> </Project>
请注意,我还尝试了扩展名.props,并且效果相同。
注意:导入Microsoft.CppBuild.targets.$(Platform).user.props
之后的新导入是不够的,必须在Microsoft.CppBuild.targets
之后。
免责声明:在Visual Studio 2015中尝试过