背景:我有几个解决方案,其中包含大约300个C ++项目,其中大多数是共享的。我们正在使用Visual Studio 2013,并且有一个构建脚本,它以正确的顺序编译所有项目,确保依赖关系得到提前解决。我们的开发/工程团队通过构建脚本构建所有代码,然后尝试使用Visual Studio 2013进行调试。
问题:"构建然后调试" Visual Studio中的进程结果告诉我们项目已过期。这源于ProjectEvaluationFingerprint属性(在第39行Microsoft.CppBuild.targets中),包括输出文件中的$(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>
一般来说,我一直关注微软的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还是我有更简单的选择?
答案 0 :(得分:3)
您可以覆盖此属性,但必须注意两件事:
<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中尝试过
答案 1 :(得分:0)
我有同样的问题。我能够比你更进一步,但我仍然没有完整的解决方案。
您现在将旧指纹附加到没有解决方案目录的新指纹的原因是您的行
<ProjectEvaluationFingerprint>$(Configuration)|$(Platform)|TEST|$(ProjectEvaluationFingerprint)</ProjectEvaluationFingerprint>
$(ProjectEvaluationFingerprint)
保留旧指纹,因此只需从ProjectEvaluationFingerprint的值中删除此部分,您的lastbuildstate将具有所需的值。
可悲的是,现在(至少对我而言)Visual Studio总是认为指纹是错误的,并且会在每次编译时重新链接项目,而不仅仅是在切换sln文件时。
我从道具表中删除了该行,只要解决方案目录没有更改,我就会按预期再次运行最新检查。然后我直接修改了Microsoft.CppBuild.targets,这样就可以了:即使切换解决方案目录,也不再需要“不是最新的”项目。