Makefile --- linux 驱动 makefile 逐行解析
linux 驱动所用 Makefile 介绍
1、目标定义:目标定义就是用来定义哪些内容作为模块编译,哪些要编译并链接进内核。
obj-y += foo.o
表示要由foo.c或者foo.s文件编译得到foo.o并链接进内核(无“条件编译”,所以不需要Kconfig配置),而obj-m则表示该文件要作为模块编译、obj-n形式的目标不会被编译。
更常见的做法根据make menuconfig后生成的.config文件的CONFIG_变量来决定文件的编译方式,如:
obj-$(CONFIG_ISDN) += isdn.o
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
除了具有obj-形式的目标以外,还有lib-y library库、hostprogs-y主机程序等目标,但是这两类基本都应用在特定的目录和场合下。
2、多文件模块的定义
最简单的Makefile仅需一行代码就够了。如果一个模块由多个文件组成,会稍微复杂一点,这时候应采用模块名加-y或-objs后缀的形式来定义模块的组成文件,如下:
obj-$(CONFIG_EX2_FS) += ext2.o
ext2-y := balloc.o dir.o file.o fsync.o ialloc.o inode.o \
ioctl.o namei.o super.o symlink.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xttr.o xttr_usr.o xattr_trusted.o
ext2-$(CONFIG_EXT2_FS_POSIX_ACL) += acl.o
ext2-$(CONFIG_EXT2_FS_SECURITY) += xattr_security.o
ext2-$(CONFIG_EXT2_XIP) += xip.o
模块的名字为ext2,由balloc.o、dir.o、file.o等多个目标文件最终链接生成ext2.o直至ext2.ko文件,并且是否包括xattr.o、acl.o等则取决于内核配置文件的配置情况,例如,如果CONFIG_EXT2_FS_POSIX_ACL被选择,则编译acl.c得到acl.o并最终链接进ext2。
3、目录层次的迭代
如下例:
obj-$(CONFIG_EXT2_FS) += ext2/
当CONFIG_EXT2_FS的值为y或则m时,Kbuild将会把ext2目录列入向下迭代的目标中。
note: Makefile中的M是大写
For example:
obj-m:=HelloWorld.o
KDIR:=/home/god/Desktop/raspberry/linux # path of kernel file
PWD:=$(shell pwd) # path of current file
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
@rm -rf *.mod.*
@rm -rf *.o
@rm -rf Module.*
@rm -rf modules.*
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
注:all 和 clean 的后面几行前面都是Tab,不是4个空格!
obj-m:=HelloWorld.o: HelloWorld 是c源文件的文件名,根据 HelloWorld.c 生成 HelloWorld.o,HelloWorld.o 是中间文件
$(MAKE):等价于make,all 和 clean 都是 make 的参数,如果 make 没有带参数,默认执行 Makefile 第一个出现的参数对应的内容,上面的例子是 all。执行 make 命令会寻找Makefile
KDIR:是linux内核文件根目录
PWD:是源文件目录,即 .c 文件和 Makefile 所在文件目录
-C $(KDIR): 表示先跳转到内核源码根目录再执行那里的Makefile,M=$(PWD) 表示把源文件目录赋值给 M,M的值作为变量再传递到内核源码根目录的 Makefile 里面
modules:modules是内核源码根目录下 Makefile 的目标,make M=dir 和 make M=dir modules 一样,所以此处也可以不加 modules
@rm -rf *.o:@表示这个指令不打印到 shell 窗口上
如果内核根目录下的 Makefile 需要添加环境变量,可以先在shell执行如下语句:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
# Makefile2.6 ifneq ($(KERNELRELEASE),) #kbuild syntax. dependency relationshsip of files and target modules are listed here. mymodule-objs := hello.o obj-m := hello.o else PWD := $(shell pwd) KVER ?= $(shell uname -r) KDIR := /lib/modules/$(KVER)/build all: $(MAKE) -C $(KDIR) M=$(PWD) clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions endif
note:
make modules是编译模块,很多驱动还有功能在选的时候选成M的都是modules,不过直接make,不加任何参数,就是make all,包含make modules。不用额外加此make,但是在安装的时候make install只是安装bzimage,Systemmap。没有把modules安装好,还要额外的make modules_install,把模块放到/lib/modules文件夹一个和内核名一样的文件夹下,并且运行depmod生成模块依赖关系文件,系统启动时加载模块就是从dep里面读取信息加载模块。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)