makefile基础

Makefile                      转自韦东山教程笔记

参考链接:

   Makefile中的%标记和系统通配符*的区别       https://www.cnblogs.com/warren-wong/p/3979270.html

   makefile中的shell编程注意点                          https://www.cnblogs.com/blue-sea-sky/p/5689181.html

Makefile中的目标                                               https://www.cnblogs.com/chusiyong/p/11384712.html

makefile的重要函数和通配符                             https://www.cnblogs.com/elseliving/p/7528632.html

makefile 中 $@ $^ %< 使用                            https://blog.csdn.net/kesaihao862/article/details/7332528

Makefile详解——从入门到精通                          https://blog.csdn.net/freeking101/article/details/51610782

Make命令完全详解教程                                      https://www.cnblogs.com/nosadness/p/5136652.html

Linux下的make命令使用心得                             https://blog.csdn.net/qq_29350001/article/details/51886665?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

linux中的make命令                                              https://blog.csdn.net/LV_YONG/article/details/80625661?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

 Makefile中命令前的@和-符号                             https://www.cnblogs.com/MyEyes/archive/2012/01/12/2320505.html

Makefile VPATH && vpath 区别                           https://blog.csdn.net/zcf1002797280/article/details/50420772

Makefile里面的$(MAKE)到底是啥                        https://www.cnblogs.com/LiuYanYGZ/p/5441071.html

 Linux 下的make命令与Makefile                          https://blog.csdn.net/qq_22182835/article/details/89467386

001_Makefile的引入及规则
使用keil, mdk, avr等工具开发程序时点点鼠标就可以编译了,
它的内部机制是什么?它怎么组织管理程序?怎么决定编译哪一个文件?

gcc -o test a.c b.c
// 简单,
// 但是会对所有文件都处理一次,
// 文件多时如果只修改其中一个文件会导致效率低

Makefile的核心---规则 :

目标 : 依赖1 依赖2 ...
[TAB]命令

当"目标文件"不存在,

某个依赖文件比目标文件"新",
则: 执行"命令"

参考代码:

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

002_Makefile的语法
a. 通配符: %.o
$@ 表示目标
$< 表示第1个依赖文件
$^ 表示所有依赖文件

参考代码:

test: a.o b.o c.o
gcc -o test $^

%.o : %.c
gcc -c -o $@ $<

b. 假想目标: .PHONY

参考代码:

test: a.o b.o c.o
gcc -o test $^

%.o : %.c
gcc -c -o $@ $<

clean:
rm *.o test

.PHONY: clean

c. 即时变量、延时变量, export
简单变量(即时变量) :
A := xxx # A的值即刻确定,在定义时即确定
B = xxx # B的值使用到时才确定

:= # 即时变量
= # 延时变量
?= # 延时变量, 如果是第1次定义才起效, 如果在前面该变量已定义则忽略这句
+= # 附加, 它是即时变量还是延时变量取决于前面的定义

参考代码:

A := $(C)
B = $(C)
C = abc

#D = 100ask
D ?= weidongshan

all:
@echo A = $(A)
@echo B = $(B)
@echo D = $(D)

C += 123


参考文档:
a. 百度搜 "gnu make 于凤昌"
b. 官方文档: http://www.gnu.org/software/make/manual/

如果想深入, 可以学习这视频:
第3期视频项目1, 第1课第4节_数码相框_编写通用的Makefile_P

003_Makefile函数
a. $(foreach var,list,text)


b. $(filter pattern...,text) # 在text中取出符合patten格式的值


$(filter-out pattern...,text) # 在text中取出不符合patten格式的值

c. $(wildcard pattern) # pattern定义了文件名的格式,
# wildcard取出其中存在的文件


d. $(patsubst pattern,replacement,$(var)) # 从列表中取出每一个值
# 如果符合pattern
# 则替换为replacement

参考代码:

A = a b c
B = $(foreach f, $(A), $(f).o)


C = a b c d/

D = $(filter %/, $(C))
E = $(filter-out %/, $(C))

files = $(wildcard *.c)


files2 = a.c b.c c.c d.c e.c abc
files3 = $(wildcard $(files2))

dep_files = $(patsubst %.c,%.d,$(files2))

all:
@echo B = $(B)
@echo D = $(D)
@echo E = $(E)
@echo files = $(files)
@echo files3 = $(files3)
@echo dep_files = $(dep_files)

004_Makefile实例
a. 改进: 支持头文件依赖
http://blog.csdn.net/qq1452008/article/details/50855810

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

b. 添加CFLAGS
c. 分析裸板Makefile

参考代码:

objs = a.o b.o c.o

dep_files := $(patsubst %,.%.d, $(objs))
dep_files := $(wildcard $(dep_files))

CFLAGS = -Werror -Iinclude

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

ifneq ($(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

原文地址:https://www.cnblogs.com/lh03061238/p/12035201.html