Как создать Make-файлы, где цель зависит от нескольких сборок Linux
У меня есть проект на основе 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)
Аналогично для ядер Linux и b. Обратите внимание, что у каждого могут быть одинаковые или разные исходные деревья, и почти наверняка они будут иметь разные defconfigs.
Это работает для чистых сборок, но мне не очень нравится делать рекурсивный вызов. В зависимости от того, как я настраиваю вышеупомянутые несколько строк, я, кажется, заканчиваю одним из:
- ненужные рекурсивные преобразования в деревья linux, даже когда ничего не меняется (на это требуется 7 секунд, чтобы ничего не делать)
- если я редактирую исходные коды linux, ядра не восстанавливаются, если я не коснусь явно.config или чего-то еще.
В идеале я хотел бы, чтобы мой Makefile верхнего уровня знал о графике внутренней зависимости каждого ядра Linux и "делал все правильно" при любых обстоятельствах. (то есть рекурсивный аргумент "сделай считай вредным").
Хотя я ожидаю, что Linux Makefile верхнего уровня не будет рад, если кто-то еще включит его, особенно несколько раз с разными конфигами и деревьями src! (У меня есть контроль над базой /makefile.inc bar/makefile.inc, поэтому они могут быть написаны так, чтобы они хорошо играли, когда включены верхним уровнем)
Или мне не повезло, и мне просто нужно помнить о прикосновении к.configs, чтобы вызвать достойное включение в каждый каталог сборки Linux?
Спасибо дэйв
РЕДАКТИРОВАТЬ: 7-секундный бесполезный приличный в дерево Linux выглядит так на моем махине:
$ 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
1 ответ
Для того, чтобы это работало правильно, вам действительно нужно заходить в исходные каталоги ядра при каждой сборке. 7 секунд действительно неплохо для проверки того, изменился ли какой-либо файл в массивном дереве ядра...
Включение make-файла ядра в вашу сборку как-то не поможет, потому что сама сборка ядра использует рекурсивное 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
является "фальшивой" целью (она не соответствует физическому файлу), она будет запускаться при каждой сборке, позволяя make-файлу ядра замечать изменения в исходных файлах.