我已经定制了一个MSBuild项目,因此默认目标是一个名为“BuildWithExternalReference”的新目标。这个新目标调用另外两个目标;第一个是自定义目标,称为“BuildExternalReference”,它使用外部工具构建DLL。构建的DLL是主项目的引用,它是使用普通的“Build”目标构建的。我已经为'BuildExternalReference'目标设置了Inputs和Outputs属性,因此Inputs引用源文件,输出引用生成的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”),然后调用默认的Build目标。
自定义ExternalTool目标会写出一些消息以确保它正常工作,并且还会通过MSBuildIssueExample \ ExternalTool \ Output.txt文件复制MSBuildIssueExample \ ExternalTool \ Input.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都会按预期工作。
答案 0 :(得分:11)
Microsoft的反馈回答了这个问题:
&#34;这是由于VS 2012的变化,C#/ VB项目现在进行了快速的最新检查&#34;这允许他们跳过构建,而不是一直强制构建。然而,一个缺点是快速的最新检查没有考虑自定义目标,这就是未检测到增量更改的原因。如果您希望禁用&#34;快速最新检查&#34;请设置&#34; DISABLEFASTUPTODATECHECK&#34;无论是作为项目文件中的MSBuild属性还是作为环境变量,您都可以从中启动VS.&#34;
所以基本上这是Visual Studio 2012中的一个重大变化,遗憾的是,它似乎没有很好地记录下来。
答案 1 :(得分:4)
这是一个老问题,但仍然相关。非常感谢你在这里提出它。
我想提供我的研究结果。
您共享的示例显示了在Visual Studio GUI内部构建时和devenv命令行(devenv .\MSBuildIssueExample.sln /build
)
但是,如果使用以下内容替换csproj文件:
<强> MSBuildIssueExample.csproj 强>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{4EA8847D-262C-4937-8536-E526E9BAB1C7}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MSBuildIssueExample</RootNamespace>
<AssemblyName>MSBuildIssueExample</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="Custom.Targets" />
</Project>
<强> Custom.Targets 强>
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CompileDependsOn>ExternalTool;$(CompileDependsOn)</CompileDependsOn>
<CleanDependsOn>CleanOutput;$(CleanDependsOn)</CleanDependsOn>
</PropertyGroup>
<ItemGroup>
<ExternalToolInputs Include="ExternalTool\Input.txt">
<InProject>false</InProject>
</ExternalToolInputs>
<ExternalToolOutputs Include="ExternalTool\Output.txt">
<InProject>false</InProject>
</ExternalToolOutputs>
</ItemGroup>
<Target Name="ExternalTool" Inputs="@(ExternalToolInputs)" Outputs="@(ExternalToolOutputs)">
<Message Text="ExternalTool target start, copying input file over output..." />
<Copy SourceFiles="@(ExternalToolInputs)" DestinationFiles="@(ExternalToolOutputs)" />
<Message Text="ExternalTool target end, copy successful" />
</Target>
<Target Name="CleanOutput">
<Delete Files="@(ExternalToolOutputs)" ContinueOnError="true" />
</Target>
</Project>
然后行为不同!
Visual Studio GUI继续行为不端,但是,使用devenv构建的命令行确实识别输入中的更改!
另请注意,在命令行上运行msbuild
而不是devenv
在两个版本中都能正常运行。虽然msbuild还有其他问题......
修改强>
GUI构建有一个解决方案,仅在外部文件数量较少时才适用。您可以将它们作为链接添加到项目中,并确保Build Action
为None
。然后它在GUI中工作正常。
虽然,我只检查了Custom.Targets
,但我很确定它也适用于原始版本。
答案 2 :(得分:0)
要扩展标记的修改,以及var
myArr1 = [
{any: 1, some: 1},
{any: 2, some: 2},
{any: 3, some: 3}
],
myArr2 = [
{other: 1},
{other: 2}
],
mergedObjectList = myArr1.reduce(function (collector, item_1, idx) {
var
item_2 = collector[idx],
merger = Object.assign({}, item_1, item_2);
// or whatever one wants to do to `merger` with `myNewAttribute`
collector[idx] = merger;
return collector;
}, Array.from(myArr2));
console.log("myArr1 : ", myArr1);
console.log("myArr2 : ", myArr2);
console.log("mergedObjectList : ", mergedObjectList);
- 项目对我不起作用,这里是我可以在其他项目中导入的自定义目标文件的示例,将文本文件读入属性(我可以在None
属性中使用),并将文本文件标记为DefineConstants
目标的输入:
CoreCompile
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CommonDefines>$([System.IO.File]::ReadAllText('$(SolutionDir)\_meta\definesFlags.txt'));$(CommonDefines)</CommonDefines>
</PropertyGroup>
<ItemGroup>
<CustomAdditionalCompileInputs Include="$(SolutionDir)\_meta\definesFlags.txt" />
</ItemGroup>
</Project>
- 项目被CustomAdditionalCompileInputs
视为输入。