Makefile基础

一、Makefile最基本的规则

规则

目标文件 :依赖文件

TAB 命令

复制代码
当依赖文件比目标文件新或者目标文件不存在时,才会执行命令。如下所示,当a.o或者b.o比test新,
则下面重新链接test的命令,但是a.o和b.o还要根据a.c和b.c来比较是否需要重新生成a.o或者b.o。
makefile 复制代码
test:a.o b.o
	gcc -o test a.o b.o
a.o:a.c
	gcc -c -o a.o a.c
b.o:b.c
	gcc -c -o b.o b.c

二、通配符(%)和假想目标(.PHONY)

复制代码
当执行make clean的时候,如果当前目录下有一个clean的文件的时候,并且又没有依赖文件,所以不能执行这条命令,当把clean定于为假想目标的时候就不会去判断这个文件是否存在。

$@表示目标文件

$<表示第一个依赖文件

$^表示所有的依赖文件
makefile 复制代码
test:a.o b.o c.o
	gcc -o test $^
%.o:%.c
  gcc -c -o $@ $<
clean:
	rm *.o test
.PHONY:clean

三、即时变量,延时变量

A := xxx //即时变量,A的值即刻确定,在定义时即确定

B = xxx //延时变量,B的值使用时才确定

?= //延时变量,如果是第一次定义才起效,如果在前面该变量已定义则忽略这句

+= //附加,它是延时变量还是即时变量取决于前面的定义

四、函数功能

makefile 复制代码
A = a b c
B = $(foreach f,$(A),$(f).o)                #从A里面取出每个元素换成.o赋给B
C = a b c d/
D = $(filter %/,$(C))                       #从C里面找出符合条件的元素赋给D
E = $(filter-out %/,$(C))                   #从C里面找出不符合条件的元素赋给E
files = $(wildcard *.c)                     #找出当前目录下的所有.c文件
files2 = a.c b.c c.c d.c e.c
files3 = $(wildcard $(files2))              #从files2里面找出当前目录下有的.c文件
dep_files = $(patsubst %.c,%.d,$(files2))   #将files2里面的所有.c文件替换成.d文件赋给dep_files
all:
  @echo B = $(B)
  @echo D = $(D) 
  @echo E = $(E)  
  @echo files = $(files)
  @echo files3 = $(files3)
  @echo dep_files = $(dep_files)

五、Makefile实例

makefile 复制代码
gcc -M c.c                    #打印出依赖文件
gcc -M -MF c.d c.c            #把依赖写进文件c.d
gcc -c -o c.o c.c -MD -MF c.d #编译c.o,把依赖写进文件c.d
makefile 复制代码
objs = a.o b.o c.o                         #变量objs等于后面的.o元素

dep_files := $(patsubst %,.%.d, $(objs))   #将objs里面的所有.o元素替换成.a.o.d等类似,%是通配符,表示所有的.o
dep_files := $(wildcard $(dep_files))      #将当前目录下的文件和dep_files的所有元素匹配,有的话才赋给dep_files

CFLAGS = -Werror -Iinclude                 #将警告换成错误,并且会去include文件下查找对应的头文件

test: $(objs)
	gcc -o test $^

ifneq ($(dep_files),)                      #判断dep_files文件是否为空,不为空的话就包含这些文件
include $(dep_files)
endif

%.o : %.c
	gcc $(CFLAGS) -c -o $@ $< -MD -MF .$@.d  #将警告替换成错误报错

clean:
	rm *.o test

distclean:
	rm $(dep_files)
	
.PHONY: clean	
相关推荐
码农小韩5 分钟前
Linux驱动理论(二)——Linux字符设备驱动
linux·嵌入式软件开发·linux操作系统·linux应用开发·linux驱动理论
well061212 分钟前
Linux粘滞位与Makefile机制深度解析
linux·运维·服务器
再写一行代码就下班21 分钟前
linux sh脚本在windows修改导致无法使用解决方式
java·linux·centos
额额额对了35 分钟前
SPI通信
linux·c语言·汇编·单片机·嵌入式硬件·arm
子木HAPPY阳VIP1 小时前
Ubuntu 关闭防火墙操作步骤
linux·运维·ubuntu
王振超wzc1 小时前
嵌入式开发环境搭建--WM软件安装,Ubuntu操作系统安装
linux·运维·ubuntu
GeW3 小时前
制造强国底座:Linux与数据库驱动的新型工业基础设施
linux
xiaoye-duck3 小时前
《Linux 网络编程》深入理解 IO 多路复用:select 函数详解与 Echo 服务实战
linux·网络
Tairitsu_H3 小时前
[Linux系统] 命令行参数 | 环境变量 | 程序地址空间
linux·环境变量·命令行参数·程序地址空间
雯宝4 小时前
devices_init / buses_init / classes_init / firmware_init / hypervisor_init 函数
linux