Як включити локальні файли заголовків у модуль ядра Linux


17

Скажіть, у мене є модуль mymodіз вихідними файлами:

src / mod / mymod.c
src / inc / mymod.h

Я намагаюся включити mymod.h наступним чином

#include <mymod.h>

Мій makefile містить, EXTRA_CFLAGS= -I$(shell pwd)/../inc/але коли ядро ​​створено, я отримую помилку із зазначенням:

mymod.h не знайдено

Здається, причина полягає в тому, що при створенні модулів ядра ця команда запускається з makefile: (використовуючи makeV1):

make -C <path/to/linux/src> M=<path/to/mymod> modules

В інших роботах мої $(shell pwd)розширилися до <path/to/linux>. Це не те, що я хочу. Як я можу вказати -Iпараметр, який слід вказувати на src/incмоє mymodвихідне дерево?

Відповіді:


19

Для файлів ядра Linux використовується рамка Kbuild. Хоча вони інтерпретуються GNU make, Kbuild складається з великого набору макросів з особливими умовами використання, тому типові інструкції щодо makefile не застосовуються. Приємне в Kbuild - те, що вам потрібно дуже мало котла, враховуючи складність завдання.

Kbuild задокументовано у джерелі ядра, в Documentation/kbuild. Як автор модулів, ви повинні особливо читати modules.txt(і принаймні переглядати інші).

Те, що ви зараз робите, не працює, оскільки $(shell pwd)розширюється при використанні EXTRA_CFLAGSзмінної. Оскільки makefile запускається з дерева джерела ядра, а не з каталогу вашого модуля (це один із багатьох неочевидних аспектів Kbuild), він підбирає неправильну директорію.

Офіційна ідіома для уточнення включення каталогів у модуль поза деревом міститься в §5.3 modules.txt. srcМінлива встановлюється в каталог верхнього рівня вашого модуля. Тому:

EXTRA_CFLAGS := -I$(src)/src/inc

Зауважте, що ця декларація повинна бути у файлі, який називається Kbuildв корені дерева вашого модуля. (Ви можете вважати, що srcкаталог є коренем дерева вашого модуля; якщо так, поставте Kbuildтам і замініть значення вище на -I$(src)/inc). Можна також поставити їх під застереженням Makefile, але майте на увазі, що це визначення (якщо все інше, що застосовується лише при побудові модуля ядра), повинно знаходитися в межах умовної директиви ifeq ($(KERNELRELEASE),). Дивіться §4.1 від modules.txt.

Якщо у вас вже немає Kbuildфайлу і хочете перейти на такий, прочитайте §4.1 modules.txt. Мати окремий Kbuildфайл трохи зрозуміліше. Не ставте нічого, що стосується ядра, у вашому головному makefile, окрім правила для виклику 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

Я не зміг оновити публікацію, оскільки мені не вистачало репутації.
Ом Нарасимхан

1
@Om Narasimhan: Якщо це допомогло вам розібратися у рішенні, слід позначити відповідь як прийняту.
CVn

1

Традиційно способом до #includeфайлів із шляхами відносно каталогу поточного вихідного коду є використання лапок, а не кутових дужок:

#include <stdio.h>
#include "mygreatfunctions.h"

У цьому випадку перший #includeпосилається на пошук шляху компілятора (який у випадку gcc управляється -Iкомутатором командного рядка), тоді як другий буде шукати у каталозі, що містить вихідний файл із #include.

Такі шляхи теж можуть бути відносними. Тож у src / mod / mymod.c можна сказати:

#include "../inc/mymod.h"

і він повинен "просто працювати".

Я не знаю, чи є це звичайною практикою в дереві ядра Linux, але, безумовно, це краще, ніж спілкуватися з включенням шляху, який може мати будь-яку кількість небажаних побічних ефектів.


1
Гарна порада в цілому, проте файли ядра Linux дуже своєрідні. Вони закликають досить складний набір макросів під назвою Kbuild; Найчастіше найкраще трактувати Kbuild як мову, яка майже, але не зовсім, зовсім на відміну від make.
Жил "ТАК - перестань бути злим"

1
Зрозуміло, але поведінка компілятора C шукає <foo> в деякому налаштованому наборі каталогів, а також "bar", спочатку переглядаючи поточний каталог, а потім повертаючись до зазначеного раніше шляху, не зміниться тим, що називають химерні засоби компілятор в першу чергу.
фонбранд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.