几周前,苹果发布了Xcode和命令行工具的新版本。由于习惯了开发环境常因操作系统或工具更新而被破坏,作者迅速进行了更新。一方面,已习惯这种情况;另一方面,通常不会造成太大影响,且管理依赖意味着要应对不可避免的麻烦,越早发现越好(更多关于管理依赖的方法见这里)。
供应商提供的工具链是重要依赖,作者接受了命令行工具更新,却花了两周时间修复世界上最大的持续集成系统之一在最受欢迎的平台之一上的问题。运行pkg_rolling-replace -suv
重建过时内容时,情况很糟。
本文用“我们”是因为 pkgsrc 在 macOS 上的持续稳定运行反映了许多开发者的贡献,作者只是碰巧先到现场,大家一起讨论问题和潜在解决方法,作者的提交也相应调整。
几周前他们正努力为昨天的季度发布稳定化,若不尽快解决 macOS 用户的问题,就得处理复杂情况,但若在其他平台贸然行动则更糟。通常提议基础设施变更的反馈机制是比较变更前后的完整批量构建,但没时间这么做。
幸运的是,故事的结局很平淡:如往常一样,pkgsrc 2024Q1 稳定分支支持 macOS 及其开发工具,包括最新版本。(当然 -current pkgsrc 也支持,如果这是你需要的。)
好奇他们是如何做到的?继续阅读。
更严格的clang
默认值
上游Clang 16和GCC 14默认将一些警告提升为错误,苹果的 Clang 15 也跟进了。Gentoo 已为打包者记录了这一点。这些变化是有意且良好的,促使维护者发布更可靠的代码,但 pkgsrc 的工作是构建近 30,000 个未维护的代码库,更严格的编译器默认值会破坏很多构建。
在 pkgsrc 中,包声明构建所需的编程语言,编译器框架选择合适的编译器并放置在包的构建环境中,关键是拦截编译器调用并进行重写。2020 年 9 月 Xcode 12 发布时也有类似情况,通过在 macOS 上传递-Wno-error=implicit-function-declaration
将错误降级为警告来解决。苹果 Clang 15 的新规定无法以同样方式观察到,所以通过同样的机制传递参数来处理。
缺失的m4
和yacc
此混乱的回归仅在命令行工具 15.3.0.0.1.1708646388 更新中出现,不在相应的完整 Xcode 15.3 更新中,可能是无意的。在 macOS 中,/usr/bin 中的一些常用 Unix 工具是存根,调用时会执行相应安装的程序或提示安装命令行工具。此更新卸载了/Library/Developer 中的m4
和yacc
,但/usr/bin 中的存根仍存在,导致运行m4
或yacc
会弹出安装窗口,浪费时间。
在 pkgsrc 中,有控制构建期间调用的非编译器工具的框架,包声明所需工具,工具框架选择并放置。此次需要处理一些新情况:对 macOS 上的m4
和yacc
检测进行特殊处理,进行存根目标的存在检查;对未声明m4
和yacc
的包在 macOS 上特殊处理,将其放置在构建环境中作为空操作;调整工具框架以根据flex
声明推断gm4
,使/usr/bin/flex
恢复正常工作状态。
更广泛的xcrun
搜索
已经依赖xcrun
做一些事情,新的工具检测特殊情况有时会得到意外结果,因为xcrun
不再仅在苹果控制的位置查找,还会查询环境的$PATH
,通过传递空PATH
和--no-cache
来获得可控可预测的工具检测。
结论
在约束条件下,尽可能少地改变,尽可能安全地改变,尽可能与之前 proven 的变化相似,避免新的构造或任何不可预见的后果。如果没有已有的良好抽象,无法做到如此安全和彻底的工作。pkgsrc 基础设施代码更改的总行数少于 100 行。2024Q1 发布后,有空间进行重构。这些 15.3 更新还包括一个全新的链接器,目前还没有带来麻烦,如果有变化,猜猜是否有一个地方可以处理它?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。