LKM Makefile, извлечение исходных файлов из исходных каталогов

У меня есть следующая структура проекта для простого модуля ядра, и я хочу иметь возможность построить ее, извлекая исходные файлы из предоставленных исходных каталогов в Makefile.

Makefile
src/
    main.c
    sub_src/
        sub_src.c
        sub_src.h

Я скоро опишу свою проблему, но сначала предоставлю код.

main.c:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

#include "sub_src/sub_src.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Unknown");
MODULE_DESCRIPTION("A Simple Hello World module");

static int __init hello_init(void)
{
    printk(KERN_INFO "Hello world!\n");
    sub_src_printk("sub_src.c\n");
    return 0;
}

static void __exit hello_cleanup(void)
{
    printk(KERN_INFO "Cleaning up module.\n");
}

module_init(hello_init);
module_exit(hello_cleanup);

sub_src.h:

#ifndef __SUB_SRC_H___
#define __SUB_SRC_H___

#include <linux/kernel.h>    // included for KERN_INFO
void  sub_src_printk( const char* );

#endif /* __SUB_SRC_H___ */

sub_src.c:

#include "sub_src.h"

void  sub_src_printk( const char* msg )
{
    printk(KERN_INFO "%s", msg);
}

Makefile:

MODULE_NAME ?= test_module
TEST        ?= 0 

INCLUDE_DIRS = -I$(src)/src/sub_src

ccflags-y := $(INCLUDE_DIRS)

ifeq ($(TEST), 1)
SRC_DIRS :=                     \
    src                         \
    src/sub_src
SRCS := $(foreach src_dir,$(SRC_DIRS),$(wildcard $(src_dir)/*.c))
else
SRCS :=                         \
    src/main.c                  \
    src/sub_src/sub_src.c       
endif
#extract required object files
OBJ_SRCS :=  $(SRCS:.c=.o)

#setup kbuild
obj-m += $(MODULE_NAME).o
$(MODULE_NAME)-y := $(OBJ_SRCS)
$(MAKE) = make
KERNEL_DIR := /lib/modules/$(shell uname -r)/build

all:
    @echo  ""
    @echo  "------- Building the LKM ($(MODULE_NAME).ko) -------"
    @echo  "INCLUDE_DIRS = $(INCLUDE_DIRS)"
    @echo  "SRCS = $(SRCS)"
    @echo  "OBJS_SRCS = $(OBJ_SRCS)"
    @echo  "ccflags-y = $(ccflags-y)"
    @echo  "obj-m = $(obj-m)"
    @echo  "test_module-y = $(test_module-y)"
    @echo  "-----------------------------------------------------"
    @echo  ""
    $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
    $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean

Идея состоит в том, что я должен быть в состоянии собрать этот модуль, предоставляя только исходные каталоги в Makefile, вызывая make как:

make all TEST=1    

Но у меня есть возможность (на данный момент) указать путь к исходным файлам, вызвав make следующим образом:

make all TEST=0

Эти два вызова в идеале должны обеспечивать один и тот же результат, то есть функциональный модуль ядра, готовый для вставки (через sudo insmod ...). Это, однако, не тот случай. (make all TEST=0 работает как задумано, а make all TEST=1 не работает)

make all TEST = 0 дает следующий вывод: (make clean вызывалось перед этой командой)

------- Building the LKM (test_module.ko) -------
INCLUDE_DIRS = -I/src/sub_src
SRCS = src/main.c src/sub_src/sub_src.c         
OBJS_SRCS = src/main.o src/sub_src/sub_src.o
ccflags-y = -I/src/sub_src
obj-m = test_module.o
test_module-y = src/main.o src/sub_src/sub_src.o
-----------------------------------------------------

make -C /lib/modules/3.19.0-59-generic/build   M=/home/henrik/Desktop/test_lkm_dev/new_test modules
make[1]: Entering directory `/usr/src/linux-headers-3.19.0-59-generic'
CC [M]  /home/henrik/Desktop/test_lkm_dev/new_test/src/main.o
CC [M]  /home/henrik/Desktop/test_lkm_dev/new_test/src/sub_src/sub_src.o
LD [M]  /home/henrik/Desktop/test_lkm_dev/new_test/test_module.o
Building modules, stage 2.
MODPOST 1 modules
CC      /home/henrik/Desktop/test_lkm_dev/new_test/test_module.mod.o
LD [M]  /home/henrik/Desktop/test_lkm_dev/new_test/test_module.ko
make[1]: Leaving directory `/usr/src/linux-headers-3.19.0-59-generic'

make all TEST=1 дает следующий вывод: (make clean вызывалось перед этой командой)

------- Building the LKM (test_module.ko) -------
INCLUDE_DIRS = -I/src/sub_src
SRCS = src/main.c src/sub_src/sub_src.c
OBJS_SRCS = src/main.o src/sub_src/sub_src.o
ccflags-y = -I/src/sub_src
obj-m = test_module.o
test_module-y = src/main.o src/sub_src/sub_src.o
-----------------------------------------------------

make -C /lib/modules/3.19.0-59-generic/build   M=/home/henrik/Desktop/test_lkm_dev/new_test modules
make[1]: Entering directory `/usr/src/linux-headers-3.19.0-59-generic'
make[2]: *** No rule to make target  `/home/henrik/Desktop/test_lkm_dev/new_test/test_module.c', needed by   `/home/henrik/Desktop/test_lkm_dev/new_test/test_module.o'.  Stop.
make[1]: *** [_module_/home/henrik/Desktop/test_lkm_dev/new_test]    Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.19.0-59-generic'
make: *** [all] Error 2

Отладочная информация показывает (насколько я вижу), что переменные в Makefile содержат одинаковые значения с разными подходами.

Но у второй альтернативы (TEST=1) почему-то создается впечатление, что должен существовать исходный файл с именем test_module.c, который не соответствует действительности.

У кого-то / кого-то есть идея, почему это происходит и как я могу это решить? (Я вырывал свои волосы последние два часа..)

Решение (Makefile):

MODULE_NAME ?= test_module
TEST        ?= 0 

INCLUDE_DIRS = -I$(src)/src/sub_src
ccflags-y := $(INCLUDE_DIRS)

ifeq ($(TEST), 1)
# Paths to source directories
SRC_DIRS :=                     \
    src                         \
    src/sub_src
SRCS := $(foreach src_dir,$(SRC_DIRS),$(wildcard $(src)/$(src_dir)/*.c))
SRCS := $(SRCS:$(src)/%=%)
else
SRCS :=                                 \
    src/main.c                          \
    src/sub_src/sub_src.c       
endif
# extract required object files
OBJ_SRCS :=  $(SRCS:.c=.o)

# setup kbuild
obj-m := $(MODULE_NAME).o
$(MODULE_NAME)-y := $(OBJ_SRCS)
$(MAKE) = make
KERNEL_DIR := /lib/modules/$(shell uname -r)/build

all:
    @echo  ""
    @echo  "------- Building the LKM ($(MODULE_NAME).ko) -------"
ifeq ($(TEST), 1)
    @echo "Compiling with TEST = 1"
else
    @echo "Compiling with TEST = 0"
endif
    @echo  ""
    $(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
    $(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean

Большое спасибо! Хенрик

0 ответов

Другие вопросы по тегам