预
c/c++编译过程
- 预处理(Preprocessing)gcc -E hello.c -o hello.i
- 编译(Compilation)gcc -S hello.i -o hello.s
- 汇编(Assembly)gcc -c hello.s -o hello.o
- 链接(Linking)gcc hello.c -o hello gcc -static hello.c -o hello
ldd hello //可以看出该可执行文件链接了很多其他动态库,主要是Linux的glibc动态库
1、makefile的规则
target:main.c add.c sub.c
gcc main.c add.c sub.c -o target
规则三要素:目标、依赖、命令
目标(target):目标文件, 可以是 Object File, 也可以是可执行文件
依赖(prerequisites ):生成 target 所需要的文件或者目标
命令(command):make需要执行的命令 (任意的shell命令), Makefile中的命令必须以 [tab] 开头
1、显示规则:说明如何生成一个或者多个目标文件(目标文件、依赖文件、执行命令)
2、隐晦规则:make自动推导功能所执行的规则
3、变量定义:makefile中定义的变量
4、文件指示:makefile中引用的其他makefile;指定makefile中有效部分;
2、工作方式:
- 读入主Makefile (主Makefile中可以引用其他Makefile)
- 读入被include的其他Makefile
- 初始化文件中的变量
- 推导隐晦规则, 并分析所有规则
- 为所有的目标文件创建依赖关系链
- 根据依赖关系, 决定哪些目标要重新生成
- 执行生成命令
3、makefile编写
最上面规则的目标一定是最终目标,即最后要生成的文件;第一个规则的命令执行时如果没有发现相应的依赖,就会在下面的规则中寻找
target:main.o add.o sub.o
gcc main.o add.o sub.o -o target
mian.o:main.c
gcc -c main.c
add.o:add.c
gcc -c add.c
sub.o:sub.c
gcc -c sub.c
4、makefile变量
1、自定应变量
obj=main.o add.o sub.o
OBJ=main.o add.o sub.o
TAR=target
$(TAR):$(OBJ)
gcc $(OBJ) -o $(TAR)
2、自动变量
$< 规则中的第一个依赖,如果依赖是多个目标,逐个表示依赖目标
$@ 规则中的所有目标
$^ 规则中的所有依赖,会去除重复的依赖目标
$+ 规则中的所有依赖,不会去除重复的依赖目标
$% 当目标是函数库文件时,表示其中的目标文件名
$? 比目标新的依赖集合
%.c 规则中的任意一个.c文件
*.c 规则中的所有.c文件
APPFLAGS:预处理使用的选项
CFLAGS:编译的时候使用的选项
LDFLAGS:链接库使用的选项
OBJ=main.o add.o sub.o
TAR=target
CC=gcc
$(TAR):$(OBJ)
$(CC) $(OBJ) -o $(TAR)
%.o:%.c
$(CC) -c $< -o $@
3、makefile中的函数
SRC=$(wildcard ./*.c)
OBJ=$(patsubst ./%.c,./%o,$(SRC))
TAR=target
CC=gcc
$(TAR):$(OBJ)
$(CC) $^ -o $@
%.o:%.c
$(CC) -c $< -o $@
.PHONY:clean
clean
rm -rf $(OBJ) $(TAR)
4、路径搜索
特殊变量VPATH指定路径,在当前路径没有找到相应的文件或依赖时,makefile会到VPATH指定我路径中去寻找
VPATH 使用方法:
- vpath <directories> 当前目录中找不到文件时, 就从<directories>中搜索
- vpath <pattern> <directories> 符合<pattern>格式的文件, 就从<directories>中搜索
- vpath <pattern> 清除符合<pattern>格式的文件搜索路径
- vpath 清除所有已经设置好的文件路径
# 示例1 - 当前目录中找不到文件时, 按顺序从 src目录 ../parent-dir目录中查找文件
VPATH src:../parent-dir
# 示例2 - .h结尾的文件都从 ./header 目录中查找
VPATH %.h ./header
# 示例3 - 清除示例2中设置的规则
VPATH %.h
# 示例4 - 清除所有VPATH的设置
VPATH
5、makefile命令前缀
不用前缀:输出执行的命令以及执行结果,出错即终止
前缀@: 只输出执行结果,出错即终止
前缀 - : 命令出错会忽略错误,继续执行
6、引用其他的makefile
include <filename> (filename可以包含通配符和路径)
include ./other/Makefile