如何单独编译内核模块.c文件为.o并生成.ko?编译报错求助
解决内核模块编译时找不到
linux/printk.h的问题 你的问题出在Makefile的Kbuild语法错误,导致make没有使用内核构建系统来编译,而是 fallback 到了系统默认的cc命令,自然找不到内核专属的头文件。下面是修正方案:
正确的Makefile写法
如果你的目标是先生成myfile.o,后续再链接成.ko(或者直接通过Kbuild生成.ko),可以使用以下Makefile:
# 告诉Kbuild要构建依赖myfile.o的模块 obj-m += myfile.o # 构建目标:调用内核构建系统编译模块(会自动生成myfile.o) all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules # 清理编译产物 clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
如果你只需要单独生成myfile.o(不直接生成.ko),可以把all目标改成:
all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) myfile.o
为什么你的原有写法会失败
- Kbuild语法错误:你写的
obj-m: myfile.o是错误的,Kbuild需要用赋值运算符(+=或:=)来声明模块目标,正确写法是obj-m += myfile.o,这样内核构建系统才会识别到要处理这个模块的编译。 - 目标命令错误:你在
all目标里写的make -C ... myfile.o,结合错误的obj-m声明,导致make没有触发内核构建流程,而是直接用系统默认的cc命令编译,这个命令没有包含内核头文件路径、也没有设置内核编译必需的宏和编译选项,所以找不到linux/printk.h这个内核专属头文件。
验证效果
运行修正后的make命令,你会看到内核构建系统输出类似这样的编译命令:
gcc -DMODULE -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -mpreferred-stack-boundary=2 -march=i686 -I/lib/modules/$(uname -r)/build/include -c -o myfile.o myfile.c
这里明确包含了内核头文件的路径,自然能找到linux/printk.h,编译也就不会报错了。
内容的提问来源于stack exchange,提问作者Artium
相关产品推荐
相关产品推荐

