【发布时间】:2019-01-23 17:24:56
【问题描述】:
我运行一个 CI 服务器,用于构建自定义 linux 内核。 CI 服务器并不强大,每次构建的时间限制为 3 小时。为了在这个限制内工作,我想到了使用 ccache 缓存内核构建。我希望我可以在每个次要版本发布时创建一个缓存,并将其重用于补丁版本,例如我有一个为 4.18 制作的缓存,我想将其用于所有 4.18.x 内核。
删除构建时间戳后,这对于我正在构建的确切内核版本非常有用。对于上面提到的 4.18 内核,在 CI 上构建它会给出以下统计信息:
$ ccache -s
cache directory
primary config
secondary config (readonly) /etc/ccache.conf
stats zero time Thu Aug 16 14:36:22 2018
cache hit (direct) 17812
cache hit (preprocessed) 38
cache miss 0
cache hit rate 100.00 %
called for link 3
called for preprocessing 29039
unsupported code directive 4
no input file 2207
cleanups performed 0
files in cache 53652
cache size 1.4 GB
max cache size 5.0 GB
100% 的缓存命中率和一个小时完成构建,出色的统计数据和预期的一样。
不幸的是,当我尝试构建 4.18.1 时,我得到了
cache directory
primary config
secondary config (readonly) /etc/ccache.conf
stats zero time Thu Aug 16 10:36:22 2018
cache hit (direct) 0
cache hit (preprocessed) 233
cache miss 17658
cache hit rate 1.30 %
called for link 3
called for preprocessing 29039
unsupported code directive 4
no input file 2207
cleanups performed 0
files in cache 90418
cache size 2.4 GB
max cache size 5.0 GB
这是 1.30% 的命中率,而构建时间反映了这种糟糕的性能。即仅从单个补丁版本更改。
我预计缓存性能会随着时间的推移而下降,但不会降到这个程度,所以我唯一的想法是,除了时间戳之外,还有更多的不确定性。例如,大多数/所有源文件是否包含完整的内核版本字符串?我的理解是,这样的事情会完全破坏缓存。有没有办法让缓存按我的意愿工作,还是不可能?
【问题讨论】:
-
是的,许多文件中都包含带有版本的标题。例如,对于模块,有 CONFIG_MODVERSIONS skynet.ie/~mark/home/kernel/symbols.html。您的 233 次点击率很高 - 已报告单次点击:unix.stackexchange.com/questions/226622/…(以及来自重新生成的标题 lists.samba.org/archive/ccache/2014q1/001171.html 的零次点击)。检查某些内核对象编译的
gcc -H输出以获取标头列表,并将它们用于内核版本。 -
这基本上就是我的想法,有什么好的方法可以不为次要版本号这样做,否则会彻底崩溃
-
@osgx 你认为你可以把你的评论放在一个基本上说不可能的答案中,我会奖励你吗?
-
我认为,这个问题的好答案应该显示 version.h 的确切生成位置并包含在每个编译文件中。 Version.h 是
include/generated/uapi/linux/version.h和#define LINUX_VERSION_CODE 0x041012(对于 4.16.18),并且$KERNELVERSION是从顶部 Makefile 导出的 elixir.bootlin.com/linux/v4.16.18/source/Makefile
标签: linux linux-kernel ccache