我对Makefile的理解

一、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等编译程序,生成最终的目标文件。同时保证依赖文件(包括头文件和源文件等)有变化时,重新生成目标文件,没有变化则不需要重新生成。
所以我们在处理编译相关的问题时,主要就是从这三个方面去寻找突破点。

    原文作者:kevin_wz
    原文地址: https://www.jianshu.com/p/d086f76b4ee3
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞