make和makefile
作者:互联网
目录
概述
make是控制如何从源文件(source file)生成可执行文件(excutable)及其他非源文件(non-source file)的一种工具。make工具通过makefile中说明的方式,构建(build)整个程序(program)。在一个庞大的项目中可能包含很多个源文件,修改少部分源文件可能需要重新编译整个程序,这个过程耗时耗力,通过使用make工具可以只重新编译依赖于修改过的文件的部分,从而提升效率;
makefile
makefile的基本语法
makefile主要由一条条如下的规则组成:
target ... : prerequisite ...
command
...
...
注意其中命令行前面是Tab。
如果一条规则的目标属于以下情况之一,就称为需要更新:
- 目标没有生成;
- 某个条件需要更新;
- 某个条件的修改时间比目标晚;
在一条规则被执行前,规则的条件可能处于以下三种状态之一:
- 需要更新。能够找到以该条件为目标的规则,且该规则中目标需要更新;
- 不需要更新。能够找到以该条件为目标的规则,但是该规则中目标不需要更新;或者不能找到以该条件为目标的规则且该条件已经生成;
- 错误。不能找到以该条件为目标的规则,并且该条件没有生成;
执行一条规则A的步骤如下
检查它的每个条件P:
- 如果P需要更新,则执行以P为目标的规则B。之后无论是否生成文件P都认为P已经被更新;
- 如果找不到规则B,并且文件P已经存在,则表示P不需要更新;
- 如果找不到规则B,并且文件P不存在,则报错退出;
检查完A的所有条件后,检查它的目标T,如果属于一下情况之一,就执行命令列表:
- 文件T不存在;
- 文件T存在,但是某个条件的修改时间比它晚;
- 某个条件P已将被更新(并不一定生成文件P,只要执行了命令列表就视为已经更新);
在shell中通过以下命令执行
$ make # 从缺省目标开始更新,即makefile中第一条规则的目标
$ make target # 更新target这个目标
变量
makefile可以用‘=’定义变量和'$'读取变量的值:
$ CC = gcc # 定义变量CC,值是gcc
$ $(CC) # 取出CC的值
$ CC := gcc # 读到$(CC)时立刻展开
$ CC ?= gcc # CC没有定义过则等同'=',否则什么也不做
$ CC += gcc # CC可以追加定义
makefile中还有一些特殊变量:
$ $@ # 表示规则中的目标
$ $< # 表示规则中的第一个条件
$ $? # 表示规则中所有比目标新的条件,组成一个列表,以空格分隔
$ $^ # 表示规则中所有的条件,组成一个列表,以空格分隔
makefile中的隐含变量,有的变量已经定义了缺省值:
AR 静态库打包命令,缺省值ar
ARFLAGS 静态库打包命令的选型,缺省值rv
AS 汇编器的名字,缺省值as
ASFLAGS 汇编器的选项,没有定义
CC C编译器的名字,缺省值是cc
CFLAGS C编译器的选项,没有定义
CXX C++编译器的名字,缺省值是g++
CXXFLAGS C++编译器的选项,没有定义
CPP C预处理器的名字,缺省值是$(CC) -E
CPPFLAGS C预处理器的选项,没有定义
LD 链接器的名字,缺省值是ld
OUTPUT_OPTION 输出的命令行选项,缺省值是-o $@。
RM 删除命令的名字,缺省值是rm -f
常用make命令选项
$ make -n
# 打印要执行的命令而不执行
# 这个命令可以用于查看命令的执行顺序,确认无误了再执行命令
$ make -C # 可以切换到另一个目录执行makefile
例子
# A sample Makefile
# This Makefile demonstrates and explains
# Make Macros, Macro Expansions,
# Rules, Targets, Dependencies, Commands, Goals
# Artificial Targets, Pattern Rule, Dependency Rule.
# Comments start with a # and go to the end of the line.
# Here is a simple Make Macro.
LINK_TARGET = test_me.exe
# Here is a Make Macro that uses the backslash to extend to multiple lines.
OBJS = \
Test1.o \
Test2.o \
Main.o
# Here is a Make Macro defined by two Macro Expansions.
# A Macro Expansion may be treated as a textual replacement of the Make Macro.
# Macro Expansions are introduced with $ and enclosed in (parentheses).
REBUILDABLES = $(OBJS) $(LINK_TARGET)
# Here is a simple Rule (used for "cleaning" your build environment).
# It has a Target named "clean" (left of the colon ":" on the first line),
# no Dependencies (right of the colon),
# and two Commands (indented by tabs on the lines that follow).
# The space before the colon is not required but added here for clarity.
clean :
rm -f $(REBUILDABLES)
echo Clean done
# There are two standard Targets your Makefile should probably have:
# "all" and "clean", because they are often command-line Goals.
# Also, these are both typically Artificial Targets, because they don't typically
# correspond to real files named "all" or "clean".
# The rule for "all" is used to incrementally build your system.
# It does this by expressing a dependency on the results of that system,
# which in turn have their own rules and dependencies.
all : $(LINK_TARGET)
echo All done
# There is no required order to the list of rules as they appear in the Makefile.
# Make will build its own dependency tree and only execute each rule only once
# its dependencies' rules have been executed successfully.
# Here is a Rule that uses some built-in Make Macros in its command:
# $@ expands to the rule's target, in this case "test_me.exe".
# $^ expands to the rule's dependencies, in this case the three files
# main.o, test1.o, and test2.o.
$(LINK_TARGET) : $(OBJS)
g++ -g -o $@ $^
# Here is a Pattern Rule, often used for compile-line.
# It says how to create a file with a .o suffix, given a file with a .cpp suffix.
# The rule's command uses some built-in Make Macros:
# $@ for the pattern-matched target
# $< for the pattern-matched dependency
%.o : %.cpp
g++ -g -o $@ -c $<
# These are Dependency Rules, which are rules without any command.
# Dependency Rules indicate that if any file to the right of the colon changes,
# the target to the left of the colon should be considered out-of-date.
# The commands for making an out-of-date target up-to-date may be found elsewhere
# (in this case, by the Pattern Rule above).
# Dependency Rules are often used to capture header file dependencies.
Main.o : Main.h Test1.h Test2.h
Test1.o : Test1.h Test2.h
Test2.o : Test2.h
# Alternatively to manually capturing dependencies, several automated
# dependency generators exist. Here is one possibility (commented out)...
# %.dep : %.cpp
# g++ -M $(FLAGS) $< > $@
# include $(OBJS:.o=.dep)
参考
标签:CC,make,makefile,缺省值,规则,Make 来源: https://www.cnblogs.com/zchen1995/p/12076910.html