linux makefile基本语法

74 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情

编写驱动,一般代码不大。对编译脚本需要有个大概了解,毕竟工作中,难免需要增删项目文件,少不了修改维护编译脚本。

最小结构

target : prerequisites

《tab》command

这就是最小文件的编译脚本了。target是一个目标,或者写成一个标签。

#include <stdio.h>
int main()
{
    printf("hello world!\n");
    return 0;
}

编译脚本,这里脚本写了个标签,执行文件名在命令中指定。增加了一个clean伪目标,用于清理我们的编译过程文件,可帮助保持项目干净。

objMain : tst.c
	gcc -o hw.out tst.c
clean:
	rm -f *.o *.out

终端执行 make。

image.png

常用符号

正常项目使用的makefile,会看到许多符号。 没必要一起都记住,偏门的工作中慢慢了解,前期先了解常用的。

赋值

make工作逻辑是 读入所有的makefile文件,初始化变量,解析规则,建立依赖关系链,然后按照关系链执行编译动作。
= 在初始化完毕后,再确定变量值。
:= 初始化变量的过程中,确定变量值
?= 如果无值,则赋值
+= 当前值上继续追加值

变量

变量定义: src = %.c
变量取值: dcs = $(src)

$@ 目标
$^ 目标的所有依赖
$< 目标的第一个依赖

了解了变量的知识,那么可以稍微修改下最小编译脚本了,如下所示。

src := tst.c
hw.out : $(src)
	gcc -o $@ $^
clean:
	rm -f *.o *.out

常用函数

wildcard 取出特定类型的所有文件
patsubst 取出特定类型的所有文件,并替换 src =$(wildcard,*.c) 取出当前目录下所有的c文件并复制给src obj =$(patsubst,*.c,*.o,$(src)) src里所有的c后缀替换为o后缀

如多文件,测试代码结构有三个文件,tst.c,func.c,func.h, tst.c调用func.c的函数,脚本可改为:

Src := $(wildcard *.c)
Obj := $(patsubst %.c,%.o,$(Src))
Inc := -I $(shell pwd)
Cflags := -Wall -c


all: sta hw.out

sta:
	@echo "Src= $(Src)"
	@echo "Obj= $(Obj)"
	@echo "Inc= $(Inc)"
	@echo "Cflags= $(Cflags)"

hw.out : $(Obj) 
	@echo "编译 main"
	gcc -o $@  $^
%.o:%.c
	@echo "编译 $@"
	gcc $(Cflags) $(Inc) $< -o $@
clean:
	rm -f *.o *.out 

搜索路径

VPATH: 依赖文件的搜索路径。当当前路径找不到文件时,会按照VPATH的路径去搜索文件。

VAPTH := src
%.o:%.c
    gcc -c $<

找不到c文件,make回去src下找文件。 vpath,是一个关键字,语法:

vpath pattern di dir1:dir2    配置搜索路径
vpath pattern                 删除符合pattern的搜索路径
vpath                         删除全部搜索路径

内核编译

这部分使用了嵌套makefile的相关知识。

obj-m := hello.o 
all: 
    $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules

指令里的make是跳到-C后的内核目录里顶层makefile执行编译,模块源码在M的路径下。其中make modules是内核的一个目标。编译完毕后再跳回M参数配置的的路径里。