Сборочные файлы ядра Linux используют фреймворк Kbuild. Хотя они интерпретируются GNU make, Kbuild состоит из большого набора макросов с особыми соглашениями об использовании, поэтому типичные рекомендации для make-файлов не применяются. Приятной особенностью Kbuild является то, что вам нужно очень мало шаблонов, учитывая сложность задачи.
Kbuild документирован в исходном коде ядра, в Documentation/kbuild
. Как писатель модулей, вы должны особенно читать modules.txt
(и хотя бы пролистывать остальные).
То, что вы делаете сейчас, не работает, потому что $(shell pwd)
раскрывается при использовании EXTRA_CFLAGS
переменной. Поскольку make-файл запускается из дерева исходных текстов ядра, а не из каталога вашего модуля (это один из многих неочевидных аспектов Kbuild), он выбирает неправильный каталог.
Официальная идиома для указания включаемых каталогов в модуле вне дерева - в §5.3 modules.txt
. src
Переменная устанавливается в каталог верхнего уровня вашего модуля. Следовательно:
EXTRA_CFLAGS := -I$(src)/src/inc
Обратите внимание, что это объявление должно быть в файле, который вызывается Kbuild
в корне дерева вашего модуля. (Возможно, вы захотите считать src
каталог корнем дерева модулей; если это так, поместите Kbuild
его и замените указанное выше значение на -I$(src)/inc
). Также возможно поместить их в a Makefile
, но имейте в виду, что это определение (при условии, что все остальное, что применяется только при сборке модуля ядра) должно быть в условной директиве ifeq ($(KERNELRELEASE),)
. Смотрите §4.1 modules.txt
.
Если у вас еще нет Kbuild
файла и вы хотите перейти на него, прочитайте §4.1 из modules.txt
. Наличие отдельного Kbuild
файла немного понятнее. Не помещайте ничего, что относится к ядру, в ваш основной make-файл, кроме правила вызова make -C $(KERNELDIR) M=$(pwd)
. В Kbuild
действительности, минимум, который вам нужен, это список создаваемых вами модулей (часто только один) и список файлов, которые нужно включить в ваш модуль, плюс объявление зависимости:
EXTRA_CFLAGS := -I$(src)/inc
obj-m := mymod.o
mymod-y := $(src)/mod/mymod.o
$(src)/mod/mymod.o: $(src)/inc/mymod.h
Традиционно путь к
#include
файлам с путями относительно каталога текущего исходного кода заключается в использовании кавычек, а не угловых скобок:В этом случае первый
#include
будет ссылаться на путь поиска включения компилятора (который, в случае gcc, управляется-I
переключателем командной строки), тогда как второй будет искать в каталоге, который содержит исходный файл, с помощью#include
.Такие пути тоже могут быть относительными. Итак, в src / mod / mymod.c вы можете сказать:
и это должно "просто работать".
Я не знаю, является ли это обычной практикой в дереве ядра Linux, но, конечно, это лучше, чем копаться в пути включения, который может иметь любое количество непреднамеренных побочных эффектов.
источник