韦东山一期视频学习笔记-Makefile学习

一、最简单的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
  1. 要生成test依赖a.o b.o
  2. a.o生成依赖于a.c
    gcc -c -o a.o a.c
  3. b.o生成依赖于b.c
    gcc -c -o b.o b.c

二、简单的Makefile语法

使用通配符

  • 可以匹配任意个c文件
    $@:表示目标文件
    $<:表示第一个依赖文件
    $^:表示所有的依赖文件
test : a.o b.o
    gcc -o test $^

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

清除文件

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

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

clean:
    rm *.o test
.PHONY: clean

make clean:指定执行clean,不指定默认执行第一个目标
.PHONY:不加的话如果有同名目标文件就无法执行

变量

A := xxx:A的值即可确定
B = xxx:B的值使用到时才确定
?=:延时变量,如果是第一次定义才有效,如果之前定义过则忽略
+=:附加,延时变量还是即时变量取决于前面
@:不显示命令本身
make D=1234:给变量传递值

A := $(C)
B = $(C)
#C = abc
D = first
D ?= Second

all:
    @echo $(A)
    @echo $(B)
    @echo $(D)
C = abc
输出
root@ubuntu_armv4:~/mini2440_v2/makefile# make
root@ubuntu_armv4:~/mini2440_v2/makefile# make

abc
first
  • 可以看出A为空,B为abc
  • C的前后顺序没有影响
  • ?=第一次定义才有效

函数

$(foreach var,list,text):遍历list,每个值为var

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

all:
    @echo B = $(B)

输出:B = a.o b.o c.o


$(filter pattern...,text):在text中选出匹配pattern的项
$(filter-out pattern...,text):在text中选出除了匹配pattern的项

C = a b c d/
D = $(filter %/, $(C))
E = $(filter-out %/, $(C))

all:
    @echo $(D)
    @echo $(E)
root@ubuntu_armv4:~/mini2440_v2/makefile# make
d/
a b c

$(wildcard pattern...):寻找当前目录下符合pattern的文件

files = $(wildcard *.c)

files2 = a.c b.c e.c g.c
files3 = $(wildcard $(files2))
all:
    @echo files = $(files)
    @echo files3 = $(files3)
输出
files = a.c b.c
files3 = a.c b.c

file3=从file2中选出当前目录存在的文件


$(patsubst pattern,replacement,text):在text中符合pattern的值替换成replacement

files = a.c b.c e.c g.c
dep_files = $(patsubst %.c, %.d, $(files))

all:
    @echo dep_files = $(dep_files)

输出dep_files = a.d b.d e.d g.d

三、Makefile实例分析

gcc -M c.c:可以看到c.c的依赖

#输出
root@ubuntu_armv4:~/mini2440_v2/makefile# gcc -M c.c
c.o: c.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \
 /usr/include/x86_64-linux-gnu/bits/wordsize.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \
 /usr/lib/gcc/x86_64-linux-gnu/5/include/stddef.h \
 /usr/include/x86_64-linux-gnu/bits/types.h \
 /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \
 /usr/include/_G_config.h /usr/include/wchar.h \
 /usr/lib/gcc/x86_64-linux-gnu/5/include/stdarg.h \
 /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \
 /usr/include/x86_64-linux-gnu/bits/sys_errlist.h c.h

gcc -M -MF c.d c.c:把c.c的依赖写入c.d
gcc -c -o c.o c.c -MD -MF c.d:把c.c的依赖写入c.d同时编译c.c
CFLAGS = -Werror:编译选项,把所有警告当作错误
CFLAGS = -Iinclude:指定当前目录include文件夹为编译器默认头文件目录
代码

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
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 来自陈浩的一片老文,但绝对营养。 示例工程:3 个头文件*.h,和 8 个 C 文件*.c。 初 编译过程,源文件...
    周筱鲁阅读 4,727评论 0 17
  • 1 GNU make介绍 make 在执行时,需要一个命名为 Makefile 的文件。这个文件告诉 make 以...
    城市的风10阅读 563评论 0 0
  • 1.Makefile规范 target 这 一 个 或 多 个 的 目 标 文 件 依 赖 于prerequisi...
    G风阅读 1,927评论 0 3
  • makefile关系到整个工程的编译规则,一个工程中的源文件不计其数,按其类型、功能、模块分别放在若干的目录当中,...
    Joe_HUST阅读 1,893评论 0 3
  • 五月 云很淡 风不清 昨天的日光与今天的 一样光亮,这是月季 芍药 和蔷薇的季节,却不是 我的季节 我把心事隐匿 ...
    一念生安阅读 514评论 0 0