我已经自定义了一个 MSBuild 项目,因此默认目标是一个类似于“BuildWithExternalReference”的新目标。这个新目标调用了另外两个目标;第一个是一个名为“BuildExternalReference”的自定义目标,它使用外部工具构建 DLL。构建的 DLL 是对主项目的引用,它是使用普通的“构建”目标构建的。我已经为“BuildExternalReference”目标设置了输入和输出属性,因此输入引用源文件,输出引用生成的 DLL。
在 Visual Studio 2012 和 Visual Studio 2010 中,构建在第一次被调用时可以正常工作。但是,在后续构建中,如果我更改外部源文件(由“BuildExternalReference”目标输入属性引用),那么 Visual Studio 2012 只会报告“构建:0 成功,0 失败,1 最新,0 跳过”。Visual Studio 2010 继续完美运行。此外,使用 MSBuild.exe 从命令行构建可以完美运行。
我知道 Visual Studio 2012 中的构建系统已更改,但我找不到有关更改执行增量构建方式的信息。
Visual Studio 2012 中是否有任何更改导致增量构建发生更改?
这是我正在使用的 csproj 文件的精简版本:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="BuildWithExternalTool" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ExternalSourceFiles Include="..\ExternalSourceFiles\\*\*.cs" />
<ExternalDll Include="..\ExternalSource\External.dll" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Target Name="BuildExternalTool" Inputs="@(ExternalSourceFiles);" Outputs="@(ExternalDll)">
<Exec Command="C:\External\Path\To\Tool.exe" />
</Target>
<Target Name="BuildWithExternalTool">
<CallTarget Targets="BuildExternalTool" />
<CallTarget Targets="Build" />
</Target>
</Project>
2012 年 11 月 1 日更新
这是一个完整的自包含示例,它重现了该问题:
https://skydrive.live.com/redir?resid=EA1DD6ACA92F9EFF!155&authkey=!ANhuqF_rrCgxpLE
这是一个项目的解决方案。MSBuildIssueExample\MSBuildIssueExample.csproj 文件已自定义,因此有一个自定义默认目标。此默认目标调用自定义目标(称为“ExternalTool”),然后调用默认构建目标。
自定义 ExternalTool 目标写出一些消息以确保其正常工作,并且还将 MSBuildIssueExample\ExternalTool\Input.txt 文件的内容复制到 MSBuildIssueExample\ExternalTool\Output.txt 文件上。
Input.txt 文件是 ExternalTool 目标的输入,Output.txt 是输出。
要重新创建问题,请执行以下步骤:
1)在指定版本的Visual Studio中打开解决方案
2) 构建一次解决方案,以确保输出相对于输入是最新的
3) 修改 MSBuildIssueExample\ExternalTool\Input.txt 使其内容与 Output.txt 不匹配
4) 再次构建
当您在 Visual Studio 2010 中完成此过程时,将再次调用 ExternalTool 目标,并且 Input.txt 文件将被复制到 Output.txt 上。
在 Visual Studio 2012 中执行此过程时,不会调用 ExternalTool 目标,即使输入比输出新,因此 Input.txt 的内容不会写入 Output.txt。
但是,如果您执行 Rebuild(而不仅仅是 Build),那么 Visual Studio 的两个版本都可以按预期工作。