最近,我开始学习MSBuild,以便为本地和服务器构建(CI,Nightly,Weekly)灵活构建脚本。根据我的经验,我知道构建脚本可能非常尴尬。即使在我公司的某些指导下,了解所有目标以及它们如何协同工作也是一件痛苦的事。当然,这是一个长期的过程:你需要一些东西,你没有足够的时间,你开始变得懒散和凌乱。但我问自己,我怎么能构建一个MSBuild脚本以便于扩展和可读性?特别是目标 DependsOnTargets,BeforeTargets,AfterTargets 之间的三种关系对于射击自己很有用。
答案 0 :(得分:7)
在我的MSBuild Book中,我有一个基于如何在MSBuild中创建可重用元素的部分,如果您感兴趣的话。我会在这里给出一些评论。这个内容与书的内容不同。
创建MSBuild文件时,应小心隔离 与 的。为了解释这一点,让我们来看看托管VS项目如何开箱即用(这是一个可重用元素的伟大模型)。
当你创建一个C#/ VB项目时,你会得到一个.csproj文件,这个.csproj文件主要包含Properties和Items。您将无法在该文件中找到单个目标。这些文件包含将构建(以及与构建相关的一些设置)。在项目文件的底部,您将找到一个import语句。此导入带来如何项目的构建。
导入的文件包括:
在这种情况下,Microsoft.common.targets定义了所有托管语言的整体构建过程。然后,Microsoft.CSharp.targets(或其他一个特定的.targets文件之一)填补了如何调用特定语言特定工具的空白。
在上面的回答中,你说“我建议避免使用DependsOnTargets,除非真的有必要,例如两个”。我不同意这一点。以下是我对DependsOnTargets与Before / AfterTargets的比较。
时使用DependsOnTargets
在
时使用Before / AfterTargets梳理一下这个差异,考虑一下网络项目。对于Web项目,.csproj / .vbproj有两个工作流程:
如果我想在Build目标之前将目标添加到要执行的目标列表中,我可以仅为发布方案动态更新BuildDependsOn属性。你不能用Before / AfterTargets做到这一点。
在理想世界中,每个目标都有以下wrt DependsOnTargets。
例如
<MyTargetDependsOn>
$(MyTargetDependsOn);
Target1;
Target2
</MyTargetDependsOn>
不幸的是,很多目标并没有遵循这种模式,所以DependsOnTargets在很多情况下已经死了。
当我创作MSBuild脚本时我总是使用DependsOnTargets,除非有充分理由说明我应该选择使用Before / AfterTargets 。我觉得(我对设计的真正原因没有任何见解,因为我当时没有与微软合作)真正创建了Before / AfterTargets以允许用户注入要在/之前执行的目标在他们没有拥有的目标之后,创作者没有使用上面的模式。
答案 1 :(得分:0)
好吧,正如我已经说过的,我有自己的经历:)
所以这些是我的规则。我将不胜感激任何意见或补充!