将编译器依赖性检查移至 Kconfig
Linux 内核配置系统 Kconfig 使用一种宏语言,该语言与 make 构建工具的宏语言非常相似。 然而,也存在一些差异。 当然,make 被设计为通用构建工具,而 Kconfig 是 Linux 内核特定的。 但是,为什么内核开发者要创建一个与现有通用工具的宏语言如此相似的全新宏语言呢?
最近,当 Linus Torvalds 要求开发者向 Kconfig 语言添加一个全新的依赖性检查系统,专门用于测试 GCC 编译器的功能时,其中一个原因变得清晰起来。
这实际上是一个重要的问题。 Linux 内核希望支持尽可能多的 GCC 版本——只要这样做不会在内核代码本身中引入过多的混乱——但不同版本的 GCC 支持不同的功能。 GCC 开发者一直在调整和改进,并且 GCC 发布版本有时也会有需要解决的错误。 某些 Linux 内核功能只能使用一个或另一个版本的编译器来构建。 而且,如果某些功能可以利用仅在某些版本中存在的各种 GCC 功能,则可以构建得更好或更快。
直到今年,内核构建系统都必须手动检查所有这些编译器功能,使用了许多蹩脚的方法。 探测工具以 выяснить 它是否支持给定功能的技术可以追溯到几十年前,并且充满了疯狂。 想象一下,您发出一个您知道会失败的命令,但仍然发出它,因为失败的具体方式会告诉您未来命令需要什么才能工作。 现在想象一下 Linux 内核构建系统中数百个类似的 hack。
构建系统中存在这些蹩脚检查的部分问题在于,您只能在构建期间而不是配置期间发现它们。 但是,由于某些内核功能需要特定版本的 GCC,因此了解 GCC 版本的正确位置是在配置时。 如果用户的编译器不支持给定功能,则没有理由在配置系统中显示该功能。 它应该静默地不存在。
Linus 要求开发者将这些检查迁移到 Kconfig 系统中,并将它们规范化到宏语言本身中。 这样,具有特定 GCC 依赖性的内核功能可以识别这些依赖性,然后根据是否满足这些依赖性,在配置时显示或不显示。
这就是简单地使用 make
行不通的原因。 配置语言必须以一种友好的方式表示所有这些丑陋的 hack 的结果,以便开发者可以使用。
执行此操作的代码已添加到内核树中,Masahiro Yamada 最近发布了一些文档来解释如何使用它。 文档基本上还可以,尽管代码会随着新版本的 GCC 需要新的蹩脚探测而逐渐增长。
实际上,要知道什么应该以及什么不应该进入配置系统并不容易。 如果我们正在探测 GCC 版本,为什么不也探测硬件外围设备呢? 为什么将此留给内核在运行时完成? 这不一定清楚。 事实上,这是一个公开的辩论,最终可能会向任何一方倾斜。 将所有这些 GCC 检测代码转储到 Kconfig 中可能会使 Kconfig 更好地处理以前似乎过多的其他此类转储。 我们真正了解的唯一方法是观察内核开发者如何探测 Linus,看看他会接受什么,以及什么会太过分。
注意:如果您在上面被提及并希望在评论区上方发布回复,请将您的回复文本发送至 ljeditor@linuxjournal.com。