【问题标题】:How does Visual Studio 2010 hosts MSBuild for C++ projects?Visual Studio 2010 如何为 C++ 项目托管 MSBuild?
【发布时间】:2011-03-09 03:01:23
【问题描述】:

我有几个 C++ 项目的解决方案。对于某些项目,我需要一些自定义文件副本,例如将一些配置文件复制到输出目录或在构建后将一个项目的输出文件复制到特定文件夹。

在某些情况下,我不想或不能直接通过 Visual Studio IDE 将这些文件添加到项目中。我创建了简单的 .targets 文件,我可以重复使用这些文件并将其添加到需要文件复制的项目中。

这是一个用于复制配置文件的简单示例 .targets 文件:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <PropertyGroup>
 <BuildDependsOn>
  $(BuildDependsOn);
  CopyCustom
 </BuildDependsOn>
 </PropertyGroup>
 <ItemGroup>
 <CustomFiles Include="$(ProjectDir)Config\**\*.xml" />
 </ItemGroup>
 <PropertyGroup>
 <DestCustFolder>$(OutDir)Config\</DestCustFolder>
 </PropertyGroup> 
 <Target Name="CopyCustom"
 Inputs="@(CustomFiles )"
 Outputs="@(CustomFiles ->'$(DestCustFolder)%(RecursiveDir)%(FileName)%(Extension)')"> 
 <Message Text="Copy custom files..." />
 <Copy SourceFiles="@(CustomFiles )" DestinationFiles="@(CustomFiles->'$(DestCustFolder)%(RecursiveDir)%(FileName)%(Extension)')" SkipUnchangedFiles="true" />
 </Target>
</Project>

通过 Visual Studio 中的“构建自定义”对话框,我将其添加到项目中,因此它将像这样包含在项目文件的末尾:

 <ImportGroup Label="ExtensionTargets">
<Import Project="..\Targets\CopyCustom.targets" />/
 </ImportGroup>

这应该会启用我的自定义目标的增量构建。如果我只是编辑我的一个自定义文件(并且没有任何 C++ 文件)并使用

从控制台构建它
msbuild foo1.vcxproj

它实际上会检测到更改并为我的自定义目标进行增量构建。如果未进行任何更改,则跳过目标。

但是,如果我在 Visual Studio 中进行构建,它不会检测到自定义文件的更改,只会向我显示项目由数据决定的消息:

========== Build: 0 succeeded, 0 failed, 5 up-to-date, 0 skipped ==========

我必须另外更改其中一个 C++ 文件以使其再次检查所有目标并进行增量构建。

我期待 Visual Studio 只执行 MSBuild,然后将对项目进行最新检查,因此它应该与从控制台运行 MSBuild 的结果相同。我试图通过将详细级别设置为诊断来获取更多信息,但我得到的是同一行。在我看来,MSBuild 甚至没有为该项目执行,但 Visual Studio 本身确定该项目是最新的。

所以我想知道 Visual Studio 是如何实际确定何时应该为项目执行 MSBuild。

我之前在MSDN forum 上问过基本相同的问题,但无法得到明确的答案。

【问题讨论】:

  • 它仍然实现 /Gm 选项,它仍然使用 .idb 文件。有足够的证据表明依赖检查在 VS2010 中没有发生根本性的变化。
  • 我们在项目中禁用了 /Gm 选项,因为它与 /MP 选项不兼容,因此不会创建 .idb 文件。
  • 此外,MSBuild 4.0 具有新的文件跟踪器功能,用于生成 .tlog 文件并且不再使用 .idb 文件的增量构建。但这一切应该只适用于 MSBuild 中 C++ 编译目标的增量构建,而不适用于自定义目标的增量构建。
  • 您的自定义文件是否包含在 C++ 项目中?
  • 包含了一些自定义文件,但其他一些文件不应包含在 C++ 项目中。

标签: c++ visual-studio msbuild


【解决方案1】:

this suggestion on Microsoft Connect

基本上您需要将 DisableFastUpToDateCheck 属性设置为 true 以禁用快速更新检查。

只需添加到您的 vcxproj 或您的目标文件:

<PropertyGroup>  
  <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup>

【讨论】:

  • 谢谢,我有一段时间没有回来查看了。实际上,我是在 Microsoft Connect 上写建议的人 :-)
【解决方案2】:

我通过查看“Inside the Microsoft Build Engine, Second Edition”一书找到了答案。

注意:我也在MSDN forum 的问题中更新了相同的内容,但为了完整起见,我将主要在此处再次复制文本。

在第 280 页上,他们实际上说 IDE 在项目级别进行了“快速更新检查”。如果这个粗略的项目级别检查失败,它只会生成一个项目构建并对各个任务进行更细粒度的检查。

当从命令行运行 MSBuild 时,始终会对各个工具进行细粒度的最新检查。

所以 IDE 似乎只对直接添加到项目中并设置为“输入文件”类型之一的文件进行快速检查。

在我看来,这不是一个好的设计。我希望 IDE 仅用于编辑 MSBuild 项目文件,然后仅调用 MSBuild 进行最新检查。这样会更清楚。

我可以理解,在包含大量项目的解决方案中,它可以使最新检查更快,但至少应该有一个选项来禁用快速最新检查。如果有办法禁用此行为,我正在检查 IDE,但找不到任何东西。

here 建议的解决方案确实有效,我目前正在使用它。但是我为不同类型的自定义文件添加了几个自定义目标。如果我添加一个新的自定义文件,我永远不会忘记将其设置为“自定义构建工具”,否则该文件的增量构建将不起作用。

我想一个解决方案是为我的自定义文件进行完整的构建自定义,并为它们使用特定的文件扩展名,这样当我将它们添加到项目并设置正确的项目类型时,Visual Studio 会自动检测它们。

【讨论】:

  • 有一个选项可以禁用快速更新检查。请参阅下面的答案。
猜你喜欢
  • 1970-01-01
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多