Makefile快速入门
设计得好的 Makefile,当我们重新编译时,只需编译那些上次编译成功后修改过的文件,而不是整个项目。
Makefile最为重要的是掌握二个概念,一个是目标(target),另一个就是依赖(dependency)。
目标就是指要干什么,或说运行 make 后生成什么,而依赖是告诉 make 如何去做以实现目标。
要学会采用目标和依赖关系来思考所需解决的问题。
Makefile三要素:
Makefile工作原理:
Makefile格式
# Makefile格式
# 目标:依赖
# 执行编译命令生成目标
target: depemdemcy
<TAB> command
# 例子1
hello.o: hello.c hello.h
gcc -c hello.c -o hello.o
# 例子2
mkdemo: test1.o test2.o main.o
gcc test1.o test2.o main.o -o mkdemo
test1.o: test1.c test1.h
gcc -Wall -O -g -c test1.c -o test1.o
test2.o: test2.c test2.h
gcc -Wall -O -g -c test2.c -o test2.o
main.o: main.c
gcc -Wall -O -g -c main.c -o main.o
clean:
rm *.o mkdemo
# -Wall: 表示允许gcc发出所有的报警信息。 -w关闭警告
# -c: 只编译不链接,生成目标文件'.o'
# -o file: 表示将文件输出到file中
# -O: 大O意思是开启编译优化
# -g: 加个-g 是为了gdb 用,不然gdb用不到
# clean 执行make clean命令时执行用于清理编译结果
创建和使用变量
OBJ = test1.o test2.o
OBJ += main.o
CC = gcc
CFLAGS = -Wall -O -g -c
mkdemo: $(OBJ)
$(CC) $(OBJ) -o $@
test1.o: test1.c test1.h
$(CC) $(CFLAGS) test1.c -o $@
test2.o: test2.c test2.h
$(CC) $(CFLAGS) test2.c -o $@
main.o: main.c
$(CC) $(CFLAGS) main.c -o $@
.PHONY:clean
clean:
$(RM) $(OBJ) mkdemo
# ?= 之前没有定义过,则等于新值
# += 为变量添加新的值
# 预定义变量
# AR 默认值ar,AS汇编程序名称
# CC 默认值cc
# CPP C语言预编译器,默认值$(CC) -E
# CXX C++编译器,默认g++
# RM 默认rm -f,删除程序的名称 、
# .PHONY 来定义假目标,make 并不会将其当作一个文件来处理,而只是当作一个概念上的目标。防止命令和文件同名。
# 自动变量
# 以 “test1.o: test1.c test1.h” 为例
# $@ 表示编译的目标文件 test1.o
# $^ 表示规则中的所有先决条件 test1.c test1.h
# $< 表示规则中的第一个先决条件 test1.c
Make命令常用参数
-C 目录 读取执行目录下的Makefile
-f 文件 读取当前目录下的file文件作为Makefile
-i 忽略所有的命令执行错误
-I 目录, --include-dir=目录 在 <目录> 中搜索被包含的 makefile。
-n, --just-print, --dry-run, --recon只打印命令配方,不实际执行。
-p, --print-data-base 打印 make 的内部数据库。
-q, --question 不运行任何配方;退出状态说明是否已全部更新。
-s, --silent, --quiet 不输出配方命令。
-w, --print-directory 打印当前目录。
VPATH 虚路径
VPATH = src:../headers # 定义了src和../header目录,先从当前目录的src目录中找,找不到则向上层headers目录中找