我应该如何构建我的MSBuild脚本(How should I structure my MSBuild script)

编程入门 行业动态 更新时间:2024-10-27 06:20:55
我应该如何构建我的MSBuild脚本(How should I structure my MSBuild script)

最近,我开始学习MSBuild,以便为本地以及服务器构建(CI,Nightly,Weekly)提供灵活的构建脚本。 根据我的经验,我知道构建脚本可能非常尴尬。 即使在我的公司有一些指导,但要了解所有目标以及他们如何一起工作是一件痛苦的事情。 当然,这是一个长期的过程:你需要的东西,你没有足够的时间,你开始懒惰和凌乱。 但我问自己,我如何构建一个MSBuild脚本以实现易扩展性和可读性? 特别是目标DependsOnTargets,BeforeTargets,AfterTargets之间的三种关系对于在脚下拍摄自己非常有用。

Recently, I started to learn MSBuild in order to flexible build scripts for local as well as server builds (CI, Nightly, Weekly). Based on my experience I knew that build scripts can be very awkward. Even at my company with some guidance it was a pain to get to know all targets and how they work together. For sure, it was a long-term process: you need something, you don't have enough time, you start being lazy and messy. But I asked myself, how could I structure a MSBuild script for easy extensibility and readability? Especially the three relationships between targets DependsOnTargets, BeforeTargets, AfterTargets were useful to shoot myself in the foot.

最满意答案

在我的MSBuild Book中,如果您有兴趣,我将介绍如何在MSBuild中创建可重用元素。 我会在这里给出一些评论。 这些内容与本书有所不同。

在创建MSBuild文件时,您应该小心地隔离什么如何 。 为了解释这一点,我们来看看托管的VS项目如何开箱即用( 这是可重用元素的一个很好的模型 )。

当你创建一个C#/ VB项目时你会得到一个.csproj文件,这个.csproj文件主要包含属性和项目。 您将无法在该文件中找到单个目标。 这些文件包含将构建的内容(以及与构建有关的一些设置)。 在项目文件的底部你会找到一个导入语句。 此导入会引入项目的构建方式。

导入的文件包括:

Microsoft.CSharp / VisualBasic中/ FSharp.targets Microsoft.common.targets

在这种情况下,Microsoft.common.targets定义了所有托管语言的整体构建过程。 然后,Microsoft.CSharp.targets( 或其他lang特定的.targets文件之一 )填补了如何调用特定语言特定工具的空白。

取决于OnTargets与Before / AfterTargets之间的关系

在上面的回答中,你陈述“ 我建议避免DependsOnTargets,除非它确实是必要的,例如,如果两个 ”。 我不同意这一点。 这是我对DependsOnTargets与Before / AfterTargets的看法。

使用DependsOnTargets时

当您尝试创建要执行的目标工作流程时 如果没有首先执行其他目标,目标将无法运行 当您需要根据所需操作在特定步骤注入不同目标时

在之前使用Before / AfterTargets时

如果您不拥有目标所在的文件,并且没有可以扩展的DependsOnTargets属性 无论执行何时执行,您都希望目标在特定目标之前/之后执行

为了梳理差异,有点考虑网络项目。 对于Web项目,有两个.csproj / .vbproj需要处理的工作流程:

建立 发布

如果我想将目标添加到构建目标之前要执行的目标列表,我只能动态更新发布方案的BuildDependsOn属性。 你不能用Before / AfterTargets来做到这一点。

在理想的世界中,每个目标都将具有以下重要目标:

所有目标都有属性提供的DependsOnTargets属性 每个DependsOnTargets总是将属性定义的现有值预先设置

例如

<MyTargetDependsOn> $(MyTargetDependsOn); Target1; Target2 </MyTargetDependsOn>

不幸的是,许多目标并不遵循这种模式,所以DependsOnTargets在许多情况下在水中死亡。

当我编写MSBuild脚本时, 我总是使用DependsOnTargets,除非有一个坚实的理由,我应该选择使用Before / AfterTargets 。 我觉得( 我没有洞察设计的真正原因,因为我当时不在微软 )Before / AfterTargets是真正创建的,它允许用户在目标之前/之后注入要执行的目标自己的,而创作者并没有使用上面的模式。

Well, as I already said, I had my own experiences :)

Every target goes into a single file, just like in object-oriented programming :) Also common property and item groups should remain in their own file (e.g., Projects.conf with all projects to build; Environment.conf with all paths to tools and extension packs). As you'll see, this is very handy for different build sets (like local and server build). Define ALL paths, files, and properties you need. Don't follow the DRY principle. This is hard stuff, but from my experience it is difficult to construct new values based on already defined ones. So if you have a project with a .csproj and a .nuspec file, don't bother to declare them both explicitly. Declare a Init target. Explanation follows. Declare some main targets that have to be processed during the build, like Clean, Build, Test, Package, Deploy, Archive and so on. Make them depending (DependsOnTargets) on each other. Test and Package are depending on the Build target for instance. They should all be depending on the Init target. Sanity checks are exceptions for rule 1. They belong into the same file where they are required. For instance, the PackageCheck target will watch for the .nuspec files to be present and will also declare Init as AfterTargets. This allows to fast-fail the build. All other targets will be ordered by using BeforeTargets, AfterTargets. I recommend to avoid DependsOnTargets unless it is really really necessary, for instance if two targets must be processed before Build, but also do have a order between each other. In server and local build scripts do just import everything you need and what should be a public API. As I told, every target goes into a single file (1). Now if you have a UpdateAssemblyVersion target, that should declare Build in AfterTargets (5). You can activate/deactivate that target by simply adding/removing the import. Make use of the MSBuildExtensionPack. They can be really helpful! But also don't be afraid of writing your own task!

So these are my rules. I would appreciate any comments or supplements!

更多推荐

MSBuild,构建,脚本,电脑培训,计算机培训,IT培训"/> <meta name="description&quo

本文发布于:2023-08-06 02:31:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1442076.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:脚本   MSBuild   script   structure

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!