Makefile快速入门


Makefile快速入门

设计得好的 Makefile,当我们重新编译时,只需编译那些上次编译成功后修改过的文件,而不是整个项目。

Makefile最为重要的是掌握二个概念,一个是目标(target),另一个就是依赖(dependency)。

目标就是指要干什么,或说运行 make 后生成什么,而依赖是告诉 make 如何去做以实现目标。

要学会采用目标和依赖关系来思考所需解决的问题。

Makefile三要素:

img

Makefile工作原理:

img

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目录中找