一、GNU make
makefile是GNU make的配置文件, 常用的make参数如下:
-j --jobs N: job个数,即线程个数,推荐用4的整数倍(4*n)
-B --always-make:无条件的编译所有目标
-f --file=file
二、makefile基本语法
2.1 常用变量
TARGET := helloserver #普通变量,赋值立即生效
TARGET_CLASS = exe #普通变量,赋值延迟生效
CC #Makefile内置变量,隐式变量
${PWD} #bash环境变量
2.2 变量的引用
$(TARGET) #引用makefile自己定义的变量
${PWD} #引用bash环境变量
注意:这两种引用变量的方法$()和${}经实验都可以,但通常约定$()引用makefile的变量,${}引用bash环境变量。
2.3 函数
函数调用格式:$(<function> <arguments> )
# $(patsubst <pattern>,<replacement>,<text> )
TARGET=a.c b.c
# 如果将TARGET变量中的.c文件,全部替换成相应的.o文件,如下
objs := $(patsubst %.c,%.o,$(TARGET)) #objs = a.o b.o
此外,除了函数替换,还可以通过变量替换的方式得到以上目的。
v_objs := $(TARGET:%.c=%.o) #v_objs = a.o b.o
2.4 makefile目标
很重要的一点,要弄清目标的含义。在makefile里,目标代表一个文件,真实文件和虚拟文件。
真实文件通常是: 目标bin文件, lib文件, 源文件,头文件之类。
虚拟文件通常是: 命令build,clean之类。
为了表示虚拟文件,可以用关键字.PHONY标识。
TARGET := helloserver.lib #真实文件目标
build : # 虚拟文件目标
.PHONY : build
2.5 makefile依赖规则
makefile运行的原理,根据目标是否发生变化,来执行目标下的shell cmd.
TARGET : TARGET1
#do shell command
# for example
# 当TARGET依赖的objs中的.o文件发生变化时,就会编译target
$(TARGET) : $(objs)
# compile target
#clean为虚拟文件,所以当make clean这个目标时,目标永远不存在,
#那么就会无条件执行clean下的rm command
clean :
# rm -f $(objs)
注意:这里的变化十分重要,包括依赖文件的变化和目标文件变化。
三、makefile基本思想
最后想谈一下makefile的核心目的,即组织好源文件、头文件和库文件等,调用gcc等编译程序,生成最终的目标文件。同时保证依赖文件(包括头文件和源文件等)有变化时,重新生成目标文件,没有变化则不需要重新生成。
所以我们在处理编译相关的问题时,主要就是从这三个方面去寻找突破点。