抑制AfterBuild目标时的csproj尚未建成 [英] Suppressing AfterBuild targets when a csproj has not been built

查看:298
本文介绍了抑制AfterBuild目标时的csproj尚未建成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MSBuild的生成后,目标复制一些生成输出。

I have a post-build target in MSBuild to copy some build outputs.

这是挂在作为一个依赖于 AfterBuild 目标(由 Microsoft.CSharp.targets ):

This is linked in as a dependency to the AfterBuild target (exposed by Microsoft.CSharp.targets):

<Target Name="AfterBuild" DependsOnTargets="InstallUtil;CopyPostBuildFiles" />



有没有办法避免,如果构建实际上并没有重新建立被复制的文件?

Is there any way to avoid the files being copied if the build didn't actually re-build?

例如,当MSBuild的相关性分析称,该项目并不需要建立,因为没有它的源文件都被更新,它不建立,但仍执行我的复制目标。有什么办法防止这种情况?

For example, when the MSBuild dependency analysis asserts that the project doesn't need to be built because none of its source files have been updated, it doesn't build, but still executes my copy target. Is there any way to prevent this?

推荐答案

由于要覆盖AfterBuild目标构建后的情况会一直执行。这是一个重建或建立正常的情况下。如果你想执行后重建(不建立)的一些动作,那么你应该延长的重建目标的依赖项属性。所以你的情况注入目标的重建时您的项目文件后,看起来应该是这样的:

Since you are overriding the AfterBuild target it will always execute after the build occurs. This is the case for a rebuild or a normal build. If you want to perform some actions after the rebuild (and not build) then you should extend the dependency property for the Rebuild target. So in your case to inject the targets after a rebuild occurs your project file should look something like:

<Project ...>
   <!-- some content here -->

   <Import Project="... Microsoft.Csharp.targets" />


    <PropertyGroup>
        <RebuildDependsOn>
            $(RebuildDependsOn);
            InstallUtil;
            CopyPostBuildFiles
        </RebuildDependsOn>
    </PropertyGroup>
</Project>

这方法扩展其重建目标使用声明一下针对这取决于财产。我的文章里面的MSBuild 中详细介绍这一点,见扩展构建过程

This method extends the property which the Rebuild targets uses to declare what targets it depends on. I've detailed this in the article Inside MSBuild, see section Extending the build process.

另外你正在尝试完成可由AfterBuild靶acheived如果你可以指定哪些文件会的触发的发生的最新情况。换句话说,你可以指定一组投入到目标和一组产出,这是这两个文件的。如果所有的输出随后所有输入后创建的目标将被considerd最新和跳过。这个概念被称为增量大厦和我在文章 MSBuild的最佳实践coverd它第2部分。此外,我在我的书中详细介绍这一点,微软建立发动机内部:使用的MSBuild和团队基础构建

Also what you are trying to accomplish may be acheived by the AfterBuild target if you can specify what what files would "trigger" an update to occur. In other words you can specify a set of "inputs" into the target and a set of "outputs" which are both files. If all outputs were created after all inputs then the target would be considerd up to date and skipped. this concept is known as Incremental Building and I've coverd it in the article MSBuild Best Practices Part 2. Also I have detailed this in my book, Inside the Microsoft Build Engine: Using MSBuild and Team Foundation Build.

编辑:添加BuildDependsOn例如

如果你想要的目标当文件实际上构建,而不是执行重建目标只是时只执行。然后,你应该创建你的项目是这样的:

If you want the target to only execute when the files are actually built and not just when the Rebuild target is executed. Then you should create your project to be like the following:

<Project ...>
   <!-- some content here -->

   <Import Project="... Microsoft.Csharp.targets" />


    <PropertyGroup>
        <BuildDependsOn>
            $(BuildDependsOn);
            CustomAfterBuild;
        </BuildDependsOn>
    </PropertyGroup>
   <Target Name="CustomAfterBuild" Inputs="$(MSBuildAllProjects);
            @(Compile);                               
            @(_CoreCompileResourceInputs);
            $(ApplicationIcon);
            $(AssemblyOriginatorKeyFile);
            @(ReferencePath);
            @(CompiledLicenseFile);
            @(EmbeddedDocumentation); 
            $(Win32Resource);
            $(Win32Manifest);
            @(CustomAdditionalCompileInputs)"
    Outputs="@(DocFileItem);
             @(IntermediateAssembly);
             @(_DebugSymbolsIntermediatePath);                 
             $(NonExistentFile);
             @(CustomAdditionalCompileOutputs)">

   <!-- Content here -->

    </Target>

</Project>



我刚才复制的输入和输出的 CoreCompile 目标Microsoft内部.CSharp.targets(我假设你在这里使用C#的),并粘贴在这里了。这意味着,每当执行 CoreCompile 目标对象将被跳过。此外,由于我延长了BuildDependsOn我们知道的MSBuild将尝试并执行它时,该项目建成。

I just copied the inputs and outputs from the CoreCompile target inside of Microsoft.CSharp.targets (I'm assuming your are using C# here) and pasted it here. What this means is that the target will be skipped whenever the CoreCompile target is executed. Also since I extended the BuildDependsOn we know that MSBuild will try and execute it whenever the project is built.

这篇关于抑制AfterBuild目标时的csproj尚未建成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆