You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多源文件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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 15:06:19