1

我有一个基于 Make 的项目,其中顶级目标需要多个 vmlinux 二进制文件(linux 内核)作为先决条件,所以它看起来像:

all: bigfile
bigfile: bigfile.cfg a/vmlinux b/vmlinux c/vmlinux foo bar baz
    sometool -obigfile -ibigfile.cfg # other inputs referenced from within the config

每个 linux 规则看起来或多或少像:

a/vmlinux: a/.config
    $(MAKE) -C $(A_LINUX_SRC) O=$(PWD)/a vmlinux
a/.config
    mkdir -p a
    $(MAKE) -C $(A_LINUX_SRC) O=$(PWD)/a $(A_LINUX_DEFCONFIG)

对于 b 和 c linux 内核也是如此。请注意,每个源代码树可能相同或不同,并且几乎可以肯定会有不同的 defconfigs。

这适用于干净的构建,但我真的不喜欢递归调用。根据我如何调整上述几行,我似乎最终得到以下任何一种:

  • 即使没有任何变化(什么都不做需要 7 秒),不必要的递归也会进入 linux 树
  • 如果我编辑 linux 源代码,除非我明确触摸 .config 或其他东西,否则不会重新生成内核。

理想情况下,我希望我的顶级 Makefile 能够了解每个 linux 内核的内部依赖关系图,并在所有情况下“做正确的事”。(即recursive-make-considered-harmful 论点)。

尽管我希望顶级 Linux Makefile 不会被其他人包含在内,尤其是多次使用不同的配置和 src 树!(我可以控制 baz/makefile.inc bar/makefile.inc,因此可以将它们编写为在顶层包含时播放得很好)

还是我运气不好,只需要记住触摸 .configs 以触发每个 linux 构建目录的体面?

谢谢,戴夫

编辑:在我的机器上,进入 linux 树的 7 秒无用体面看起来像这样:

$ time make
make -C /home/davidm/md/tests/linux O=/home/davidm/md/tests/linux_a vmlinux 
make[1]: Entering directory `/home/davidm/linux-2.6.38'
  Using /home/davidm/linux-2.6.38 as source for kernel
  GEN     /home/davidm/md/tests/linux_a/Makefile
  CHK     include/linux/version.h
  CHK     include/generated/utsrelease.h
make[3]: `include/generated/mach-types.h' is up to date.
  CALL    /home/davidm/md/linux-2.6.38/scripts/checksyscalls.sh
  CHK     include/generated/compile.h
make[1]: Leaving directory `/home/davidm/md/linux-2.6.38'

real    0m6.577s
user    0m2.930s
sys 0m1.360s
4

1 回答 1

2

为了使其正常工作,您确实必须在每次构建时递归到内核源目录。7 秒对于检查大量内核树中的任何文件是否已更改确实还不错...

在你的构建中包含内核makefile实际上并没有帮助,因为内核构建本身使用递归make。

也许是这样的:

a/.config
        mkdir -p a
        $(MAKE) -C $(A_LINUX_SRC) O=$(PWD)/a $(A_LINUX_DEFCONFIG)

.PHONY: kernel-a-build
kernel-a-build: a/.config
        $(MAKE) -C $(A_LINUX_SRC) O=$(PWD)/a vmlinux

bigfile: kernel-a-build

由于kernel-a-build是一个“假”目标(它不对应于物理文件),它将在每个构建中运行,从而允许内核 makefile 注意到源文件的更改。

于 2012-08-31T14:10:57.107 回答