天呐!你知道MSBuild都干了些什么
一个典型的.NET5.0项目文件是这样的,看着非常简洁:
<Project Sdk="Microsoft.NET.Sdk.Web"><PropertyGroup><TargetFramework>net5.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" /></ItemGroup></Project>
但是,当我们执行“生成”时,却可以看到输出了大量日志,完全不知道这些目标都是哪来的?
我们知道,生成操作实际是由MSBuild执行的。
那么,MSBuild到底干了什么?
查看日志
虽然,只要你在选项里设置日志级别为“诊断”,项目生成时会输出非常详细的日志记录:
但是,这样生成的文本日志量太大了,要找出需要的信息难如登天。
这时,我们可以使用“MSBuild结构化日志查看器”,以可视化的方式查看日志。
安装
查看器的安装依赖Chocolatey。
首先,以管理员身份打开命令提示符,运行下列命令安装Chocolatey:
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
然后,运行下列命令安装日志查看器:
choco install msbuild-structured-log-viewer
生成日志
打开MSBuild Structured Log Viewer
,选择“Open Project/Solution”,打开我们新建的Web API示例项目WebApplication1.sln
,点击“Build”按钮生成日志:
运行完成后,你应该可以看到如下内容:
点击项目名称左边的箭头展开后,可以看到MSBuild准备执行的所有目标,每个目标中包含多个任务:
灰色的表示跳过的目标,展开后可以看到跳过的原因。
下面,我们以bin\Debug\net5.0\Swashbuckle.AspNetCore.Swagger.dll
文件怎么输出的为例,演练如何分析日志。
分析日志
Copy任务
在左侧Search Log
窗口上方,输入bin\Debug\net5.0\Swashbuckle.AspNetCore.Swagger.dll
作为条件:
可以看到文件是由_CopyFilesMarkedCopyLocal
目标中的Copy
任务生成的,选中后在中间Log
窗口双击任务名,会在右侧窗口显示任务详情,原来任务来源于MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets文件。
Copy
任务作用是将源文件ReferenceCopyLocalPaths
复制到目标文件$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)
那么源文件和目标文件的值,又是从哪来的呢?
OutDir属性
我们可以轻易地查找到$(OutDir)
的值等于bin\Debug\net5.0
,却没看到bin\Debug\net5.0
这个值是由谁赋给它的:
通过左侧的Find In Files
窗口,原来它来自于MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets
文件,从OutputPath
赋值:
metaproj文件
OutputPath
的值来源于同一个文件,等于$(BaseOutputPath)$(Configuration)\
而BaseOutputPath
也来源于这个文件。但奇怪的是,Configuration
却来源于一个叫做WebApplication1.sln.metaproj
的文件:
项目目录下并没有这个文件啊?!
随后,我们在日志中找到这样一条消息:
已生成元项目“D:\Codes\WebApplication1\WebApplication1.sln.metaproj”。
而且,在WebApplication1.sln.metaproj
中,我们还可以找到Rebuild
目标:
而Rebuild又依赖于其他目标:
你还记得生成日志时,带的/t:Rebuild
参数吗?
现在清楚了,MSBuild启动时首先生成.metaproj文件,然后根据文件中的元数据,按照依赖关系执行目标。
DestinationSubDirectory属性
但是,%(DestinationSubDirectory)
在日志里并没有找到任何赋值的位置。
试着继续探索原始文件来源,最终定位到了ResolvePackageAssets
目标下的ResolvePackageAssets
任务:
具体参数值对应任务的输出参数RuntimeAssemblies
:
<Output TaskParameter="RuntimeAssemblies" ItemName="RuntimeCopyLocalItems" />
查看dotnet/sdk/Tasks/Microsoft.NET.Build.Tasks/ResolvePackageAssets.cs
的源码,RuntimeAssemblies
的类型是ITaskItem[]
。
ITaskItem
定义如下:
public interface ITaskItem
{string ItemSpec { get; set; }int MetadataCount { get; }ICollection MetadataNames { get; }IDictionary CloneCustomMetadata();void CopyMetadataTo(ITaskItem destinationItem);string GetMetadata(string metadataName);void RemoveMetadata(string metadataName);void SetMetadata(string metadataName, string metadataValue);
}
接着,我们找到这样一段代码:
if (!string.IsNullOrEmpty(destinationSubDirectory))
{WriteMetadata(MetadataKeys.DestinationSubDirectory, destinationSubDirectory);
}
DestinationSubDirectory原来是Metadata啊!
结论
根据上面的分析,可以梳理出bin\Debug\net5.0\Swashbuckle.AspNetCore.Swagger.dll
文件如何输出的整个流程:
MSBuild启动,根据项目文件生成
.metaproj
文件MSBuild根据
/t
参数, 从.metaproj
文件中读取目标根据目标的依赖关系,按顺序执行其他目标
其中,
ResolvePackageAssets
目标下的ResolvePackageAssets
任务获取项目所有依赖包的Metadata再由
_CopyFilesMarkedCopyLocal
目标中的Copy
任务遍历依赖包,根据Metadata复制文件到指定目录下的指定文件名
现在,你可以跟同事show一下:我知道MSBuild干了什么!
如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!
天呐!你知道MSBuild都干了些什么相关推荐
- 【一周读书】哲学家,你们都干了些什么?
书籍:<哲学家们都干了些什么> 在读这本书之前,我对哲学的印象是这样的: 哲学似乎和宗教有点关系?似乎在解决人的精神痛苦方面的问题?哲学就是一大堆难懂并且无用的理论!我要是和同学谈哲学肯定 ...
- 什么是哲学?《哲学家们都干了些什么?》读后感
<哲学家们都干了些什么?> 前言 自从听到哲学这两个字开始,其实多年来心中有个问题,对,什么是哲学,哲学有什么用,直到我读了,<哲学家们都干了些什么?>林欣浩,林欣浩 并不是什 ...
- 【哲学问题】-《哲学家们都干了些什么?》
引言 本文来源于<哲学家们都干了些什么?>这本书以及本人阅读此书之后的一些想法.这本书虽通熟易懂,但贯穿了哲学所涉及的大部分内容,我将挑出书中涉及的比较重要的内容并融入我的部分思考分几次来 ...
- 西西弗的石头----读《哲学家都干了些什么》有感
<西西弗的神话>里讲述了一个希腊神话,说西西弗被众神惩罚,把一个巨石推向山顶.但石头一到山顶又会自己滚下来,西西弗必须重复这样的苦役,直到永远.加缪用这个例子来说明我们生活的荒谬. 西西弗 ...
- 《哲学家们都干了些什么》读后感
上帝既然知道亚当和夏娃会偷吃禁果,为什么一开始不去阻止他们? 奥古斯丁的解释是,关键在于自由.上帝给了亚当和人类自由意志,所以也必须让人类拥有作恶的可能. 更具体地说,上帝是善的,而上帝的善表现在上帝 ...
- 读书:哲学家们都干了些什么
哲学本质上是人理解人.人认识人的理性活动,是对世界基本和普遍之问题研究的学科,是关于世界观的理论体系.--百度百科 这本书应该是想用不那么严肃的方式串起整个哲学史,可能有一些地方不那么详实和严谨,但对 ...
- 进华为半年我都干了些啥
楼主目前在华为云搞Java开发,22年8月份入职的.和大家分享下入职半年我都干了些什么事情. 主要分为两个方面. 第一个是业务,华为云是微服务架构,楼主是Java开发和Python开发,进入了其中一个 ...
- 哲学家们都干了些什么?
有道是,人不能闲,人一闲下来,就会胡思乱想.这不,闲得无聊读了一本<哲学家们都干了些什么?>. 谈到哲学,就是思考诸如"人为什么活着?人生的意义是什么?宇宙的本质是什么?&quo ...
- 转载:IP-Guard都干了些什么(其他如威盾等亦差不多)
##IP-Guard 整个一裹着信息安全软件外衣的超级流氓,下面来看一下它对我们的系统都干了什么. 首先是生成的文件,别看它安装程序那么小,其实生成的文件很多也一点都不小 C:\Program Fil ...
最新文章
- mac Hbuilder 无法打开的解决方案
- 前端学习总结——CSS布局方式之传统布局
- Linux第一条指令地址,arm-linux 启动代码分析——stage1 (1)
- Linux服务部署之NTP时间服务器
- 列级触发器 SQL Server
- django 1.8 官方文档翻译: 2-5-2 进行原始的sql查询
- 本模型基于Cruise软件搭建整车模型,基于Matlab/Simulink软件搭建整车控制模块,包括整车模式控制、扭矩分配
- linux打jar包命令行,windows下命令行打jar包方法
- centos7 安装最新破解(awvs12)Acunetix Vulnerability Scanner12破解和批量导入和利用python删除任务
- SnagIt - 官方网站
- 种草推荐redis客户端
- Unity资源打包(AssetBundle)
- 主流区块链浏览器导航
- 七步学习法 —— 如何高效学习一项技能
- AsPack压缩工具
- turtle画樱花树林
- OpenInfra Days China 2020大会议程已上线,快来报名参加!
- 案例分析——快手百万在线直播
- 分享一个可以免费一年的短视频平台照片去水印使用教程
- 斯坦福首席人工智能科学家:如何教计算机看懂一张图?