多源文件Linux内核模块Makefile自动生成目标文件问题
多源文件Linux内核模块Makefile自动编译问题
问题描述
尝试为包含多个源文件的Linux内核模块编写Makefile,仅手动指定目标文件时编译成功,自动生成则报错。
相关文件
头文件
Fun.h
#include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> int Fun(int Arg);
simple_lkm.h
#include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include "Fun.h" #define MODULE_NAME "SimpleLKM" int __init simple_lkm_init(void); void __exit simple_lkm_exit(void);
源文件
Fun.c
#include "Fun.h" int Fun(int Arg) { return Arg + 777; }
simple_lkm.c
#include "simple_lkm.h" MODULE_LICENSE("Dual MIT/GPL"); module_init(simple_lkm_init); module_exit(simple_lkm_exit); ////////////////////////////////////////////////////////////// int __init simple_lkm_init(void) { printk("%s: simple_lkm_init called\n", MODULE_NAME); int res = Fun(0); printk("res = %d\n", res); printk("%s: simple_lkm_init completed\n", MODULE_NAME); return 0; } ////////////////////////////////////////////////////////////// void __exit simple_lkm_exit(void) { printk("%s: simple_lkm_exit called\n", MODULE_NAME); printk("%s: simple_lkm_exit completed\n", MODULE_NAME); }
当前Makefile
MODULE_NAME := SimpleLKM2 PWD := $(shell pwd) KERNEL := $(shell uname -r) SRCS := $(wildcard *.c) #OBJS := $(SRCS:.c=.o) OBJS := simple_lkm.o Fun.o obj-m := $(MODULE_NAME).o $(MODULE_NAME)-y := $(OBJS) all: make -C /lib/modules/$(KERNEL)/build M=$(PWD) modules clean: make -C /lib/modules/$(KERNEL)/build M=$(PWD) clean .PHONY: all clean
编译报错信息
make -C /lib/modules/6.11.0-21-generic/build M=/home/dev/LKM/SimpleLKM modules make[1]: Entering directory '/usr/src/linux-headers-6.11.0-21-generic' warning: the compiler differs from the one used to build the kernel The kernel was built by: x86_64-linux-gnu-gcc-13 (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0 You are using: gcc-13 (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0 make[3]: *** No rule to make target '/home/dev/LKM/SimpleLKM/SimpleLKM2.o', needed by '/home/dev/LKM/SimpleLKM/'. Stop. make[2]: *** [/usr/src/linux-headers-6.11.0-21-generic/Makefile:1932: /home/dev/LKM/SimpleLKM] Error 2 make[1]: *** [Makefile:224: __sub-make] Error 2 make[1]: Leaving directory '/usr/src/linux-headers-6.11.0-21-generic' make: *** [Makefile:15: all] Error 2
解决方案
报错核心原因:内核构建系统会默认寻找与模块名同名的.o文件(即SimpleLKM2.o),但我们的目录中没有对应的SimpleLKM2.c,自动生成OBJS时未排除这个不存在的目标,导致构建规则失效。
修正后的Makefile:
MODULE_NAME := SimpleLKM2 PWD := $(shell pwd) KERNEL := $(shell uname -r) # 自动获取所有.c源文件,排除模块同名的.c文件(避免构建系统寻找不存在的同名.o) SRCS := $(filter-out $(MODULE_NAME).c, $(wildcard *.c)) # 将源文件转换为对应的.o目标文件 OBJS := $(SRCS:.c=.o) obj-m := $(MODULE_NAME).o # 明确指定模块由哪些.o文件链接而成 $(MODULE_NAME)-y := $(OBJS) all: make -C /lib/modules/$(KERNEL)/build M=$(PWD) modules clean: make -C /lib/modules/$(KERNEL)/build M=$(PWD) clean .PHONY: all clean
关键说明
filter-out $(MODULE_NAME).c, $(wildcard *.c):如果目录中存在与模块同名的.c文件,会被自动排除;若不存在,该规则不影响结果,确保OBJS只包含实际存在的源文件对应的目标。- 内核模块构建逻辑中,
obj-m := foo.o表示要生成foo.ko模块,foo-y := bar.o baz.o则明确该模块由bar.o和baz.o链接而成,不需要存在foo.o文件,修正后完全符合这个逻辑,解决了自动编译的问题。
内容的提问来源于stack exchange,提问作者Krnl Developer
相关产品推荐
相关产品推荐

