Проблемы с использованием подстановочного знака в Makefile при сборке.ko из объектов в каталоге
Я организовал модули ядра как разные подкомпоненты, так что я могу легко вставить / удалить существующий подмодуль, чтобы попробовать или интегрировать вещи.
Структура каталога показана ниже:
foo --+-- Makefile
|
+-- main.c
|
+-- include --+-- foo1.h
| |
| +-- ... (other headers)
|
|
+-- src ------+-- foo1.c
|
+-- ... (other sources)
Вот мой Makefile,
MODULE_NAME = foo
obj-m += $(MODULE_NAME).o
# [approach 1-1]
# SRCS := main.c src/foo1.c
# [approach 1-2]
SRCS := main.c $(wildcard src/*.c)
$(MODULE_NAME)-objs += main.o $(SRCS:.c=.o)
all:
# [2] echo to check if foo-objs values changes
echo $($(MODULE_NAME)-objs)
KCFLAGS="-I$(PWD)/include" \
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Я получил предупреждение, показанное ниже, когда я попытался заменить подход [1-1] на [1-2] в моем Makefile выше.
WARNING: "InitFoo1" [.../foo/foo.ko] undefined!
WARNING: "CleanuptFoo1" [.../foo/foo.ko] undefined!
Из вывода консоли я не вижу src/foo1.c
был скомпилирован так, как будто я использую подход [1-1] в Makefile.
# [2] echo to check if foo-objs values changes
echo main.o main.o src/foo1.o
main.o main.o src/foo1.o
KCFLAGS="-I/home/cyng93/experiment/issues/so_kbuild_wildcard/include" \
make -C /lib/modules/4.4.23-PT-ProbeOn-AuditOn+/build M=/home/cyng93/experiment/issues/so_kbuild_wildcard modules
make[1]: Entering directory '/linux'
CC [M] /home/cyng93/experiment/issues/so_kbuild_wildcard/main.o
LD [M] /home/cyng93/experiment/issues/so_kbuild_wildcard/foo.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "InitFoo1" [/home/cyng93/experiment/issues/so_kbuild_wildcard/foo.ko] undefined!
WARNING: "CleanupFoo1" [/home/cyng93/experiment/issues/so_kbuild_wildcard/foo.ko] undefined!
CC /home/cyng93/experiment/issues/so_kbuild_wildcard/foo.mod.o
LD [M] /home/cyng93/experiment/issues/so_kbuild_wildcard/foo.ko
make[1]: Leaving directory '/linux'
Я пытаюсь эхо foo-objs
(отметьте [2] в Makefile) и выясните, что значения одинаковы для обоих подходов [1-1] и [1-2].
Кто-нибудь на SO придумал подобные проблемы, может помочь затенить свет?
(Я предпочитаю [1-2], потому что это может спасти мои усилия от обновления Makefile при добавлении нового подкомпонента)
Ниже я также приложил исходный код main.c
, foo1.c
& foo1.h
, Вы также можете проверить репозиторий github для этой проблемы, чтобы упростить доступ к этому коду.
main.c
#include <linux/module.h>
#include "foo1.h"
static int myinit(void)
{
printk("Module inserted!\n");
InitFoo1();
return 0;
}
static void myexit(void)
{
CleanupFoo1();
printk("Module removed!\n");
}
module_init(myinit);
module_exit(myexit);
MODULE_LICENSE("GPL v2");
Вот, foo1
является подкомпонентом, где просто распечатывает некоторые вещи во время его инициализации и очистки:
./include/foo1.h
#ifndef FOO1_H
#define FOO1_H
int InitFoo1(void);
void CleanupFoo1(void);
#endif
./src/foo1.c
#include <linux/module.h>
#include "foo1.h"
int InitFoo1(void)
{
printk("Init Foo1\n");
return 0;
}
void CleanupTest(void)
{
printk("Cleanup Foo1\n");
}
update_2018 / 01/15
Согласно ответу Цыварева ниже, можно исправить Makefile, изменив Makefile, как показано ниже:
MODULE_NAME = foo
obj-m += $(MODULE_NAME).o
# [approach 1-1]
# SRCS := main.c src/foo1.c
# [approach 1-2 (not working)]
# SRCS := main.c $(wildcard src/*.c)
# [approach 1-2 (working)]
MISC := $($(src)/wildcard src/*.c)
SRCS := main.c $(MISC:$(src)%/=%)
$(MODULE_NAME)-objs += main.o $(SRCS:.c=.o)
all:
# [2] echo to check if foo-objs values changes
echo $($(MODULE_NAME)-objs)
KCFLAGS="-I$(PWD)/include" \
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
1 ответ
При сборке модуля ядра ваш Makefile
обрабатывается дважды:
- Когда вы печатаете
make
из каталога вашего модуля. - Внутри процесса Kbuild, потому что вы проходите
M=$(PWD)
вариант к нему.
Первый раз Makefile обрабатывается с текущим каталогом, равным каталогу модуля. Таким образом, подстановочный знак работает, как и ожидалось, что подтверждается печатью из all
чек.
Но во второй раз Makefile обрабатывается с текущим каталогом, равным каталогу сборки ядра (/lib/modules/4.4.23-PT-ProbeOn-AuditOn+/build
в твоем случае). В этом режиме
$(wildcard src/*.c)
пытается найти файл в каталоге сборки ядра, что явно не удается.
Во время второй обработки можно обратиться к каталогу сборки модуля с помощью $(src)
,
Так можно использовать wildcard()
для сбора источников модуля. Но обратите внимание, что система сборки ядра ожидает, что путь к исходному файлу (точнее, к объектному файлу) будет относительно каталога сборки модуля. Итак, нужно раздеть $(src)
компонент каждого файла, полученного с wildcard()
,