其他分享
首页 > 其他分享> > make和makefile

make和makefile

作者:互联网

目录

概述

make是控制如何从源文件(source file)生成可执行文件(excutable)及其他非源文件(non-source file)的一种工具。make工具通过makefile中说明的方式,构建(build)整个程序(program)。在一个庞大的项目中可能包含很多个源文件,修改少部分源文件可能需要重新编译整个程序,这个过程耗时耗力,通过使用make工具可以只重新编译依赖于修改过的文件的部分,从而提升效率;

makefile

makefile的基本语法

makefile主要由一条条如下的规则组成:

target ... : prerequisite ...
    command
    ...
    ...

注意其中命令行前面是Tab
如果一条规则的目标属于以下情况之一,就称为需要更新:

  • 目标没有生成;
  • 某个条件需要更新;
  • 某个条件的修改时间比目标晚;

在一条规则被执行前,规则的条件可能处于以下三种状态之一:

  • 需要更新。能够找到以该条件为目标的规则,且该规则中目标需要更新;
  • 不需要更新。能够找到以该条件为目标的规则,但是该规则中目标不需要更新;或者不能找到以该条件为目标的规则且该条件已经生成;
  • 错误。不能找到以该条件为目标的规则,并且该条件没有生成;

执行一条规则A的步骤如下

  1. 检查它的每个条件P:

    • 如果P需要更新,则执行以P为目标的规则B。之后无论是否生成文件P都认为P已经被更新;
    • 如果找不到规则B,并且文件P已经存在,则表示P不需要更新;
    • 如果找不到规则B,并且文件P不存在,则报错退出;
  2. 检查完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)

参考

  1. Linux C编程一站式学习
  2. GNU make tutorial
  3. GCC and Make Compiling, Linking and BuildingC/C++ Applications
  4. CMake VS Make

标签:CC,make,makefile,缺省值,规则,Make
来源: https://www.cnblogs.com/zchen1995/p/12076910.html