当前位置: 首页 > news >正文

Roslyn 的确定性构建

注意到每次编译完之后,你的 dll 或者 exe 是不一样的吗?本来这并没有什么大不了的,但大家都知道数字和鹅厂的安全软件遍布在我们大(tiān)陆(cháo)地区的大量电脑上,它们的查杀策略是——凡是不认识的一律是病毒木马;于是每次不一样的编译很容易引起它们的警告——真不想每次都把编译后的样本提交给它们存档入库。


确定性编译

于是有一天意外地发现了 Roslyn 的确定性构建。

方法是在 csproj 文件中加入 <Deterministic/> 标记。

<Project>
 <PropertyGroup>
   <Deterministic>true</Deterministic>
 </PropertyGroup>
</Project>

然后重新生成 dll 或 exe,多生成几次(每次都重新生成),会发现每次验证文件的 Hash 值都是一样的。

Deterministic Hash

但是,一旦我们去掉这个标记,再验证 Hash 值,就开始改变了,而且每次都不一样。

Non-deterministic Hash

不确定的编译

是什么导致了没有加此标记时每次编译都不一样呢?最少有三个:

  • MVID:当初微软在制定 CLI 标准时就说每次编译都应该在 PE 头生成新的 Id(很多工具都直接使用了 guid)
  • PDB ID:一个跟新生成的 PDB 文件匹配的 GUID 标识符
  • 时间戳:每次编译都要把当前时间加上

当然,如果你的版本号使用了 1.0.* 这样的动态版本号,那么每次编译还会新增一个构建号。


参考资料

  • Customize your build - Visual Studio - Microsoft Docs
  • roslyn/Deterministic Inputs.md at master · dotnet/roslyn
  • Deterministic Builds in C#
  • [Umbrella] Compilers should be deterministic: same inputs generate same outputs · Issue #372 · dotnet/roslyn
  • Deterministic builds in Roslyn

相关文章:

  • 使用 MSBuild 响应文件 (rsp) 来指定 dotnet build 命令行编译时的大量参数
  • VS 编译太慢了吗?新建解决方案配置关闭一部分项目的编译
  • 流畅设计 Fluent Design System 中的光照效果 RevealBrush,WPF 也能模拟实现啦!
  • 语义版本号(Semantic Versioning)
  • 使用 GitVersion 在编译或持续构建时自动使用语义版本号(Semantic Versioning)
  • UWP 流畅设计中的光照效果(容易的 RevealBorderBrush 和不那么容易的 RevealBackgroundBrush)
  • 使用 Emit 生成 IL 代码
  • 如何快速编写和调试 Emit 生成 IL 的代码
  • 自动将 NuGet 包的引用方式从 packages.config 升级为 PackageReference
  • 冷算法:自动生成代码标识符(类名、方法名、变量名)
  • WPF/UWP 的 Grid 布局竟然有 Bug,还不止一个!了解 Grid 中那些未定义的布局规则
  • Git 更安全的强制推送,--force-with-lease
  • 项目文件中的已知 NuGet 属性(使用这些属性,创建 NuGet 包就可以不需要 nuspec 文件啦)
  • 理解 C# 项目 csproj 文件格式的本质和编译流程
  • 如何创建一个基于命令行工具的跨平台的 NuGet 工具包
  • FastReport在线报表设计器工作原理
  • Making An Indicator With Pure CSS
  • MaxCompute访问TableStore(OTS) 数据
  • Mithril.js 入门介绍
  • node 版本过低
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 关于List、List?、ListObject的区别
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 线性表及其算法(java实现)
  • 一起来学SpringBoot | 第三篇:SpringBoot日志配置
  • 运行时添加log4j2的appender
  • 白色的风信子
  • ​iOS实时查看App运行日志
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)setTimeout 和 setInterval 的区别
  • ******IT公司面试题汇总+优秀技术博客汇总
  • ***利用Ms05002溢出找“肉鸡
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .net core 客户端缓存、服务器端响应缓存、服务器内存缓存
  • .NET Core/Framework 创建委托以大幅度提高反射调用的性能
  • .Net 路由处理厉害了
  • .NET关于 跳过SSL中遇到的问题
  • @RequestMapping-占位符映射
  • @RequestParam,@RequestBody和@PathVariable 区别
  • [.net]官方水晶报表的使用以演示下载
  • [Android Studio 权威教程]断点调试和高级调试
  • [autojs]autojs开关按钮的简单使用
  • [C#]C# winform部署yolov8目标检测的openvino模型
  • [C++]命名空间等——喵喵要吃C嘎嘎
  • [IE9] GPU硬件加速到底是实用创新还是噱头
  • [IE编程] 了解Urlmon.dll和Wininet.dll
  • [iOS]-网络请求总结
  • [OCR]Python 3 下的文字识别CnOCR
  • [one_demo_16]直接插入排序的demo
  • [p4] Uncheckout other user‘s file?
  • [pdf]《软件方法》强化自测题业务建模需求分析共191页,230题
  • [PHP] 代码重用与函数