C-C++|Makefile基础学习(一)——从依赖到伪目标

一、初识Makefile make是一种用于项目编译的应用程序,本质是一种脚本。而Makefile则是对make脚本的规则描述。
仅仅是写脚本编译项目的话shell脚本也是可以做的,用make的原因在于,make可以解析源文件之间的依赖,根据依赖关系自动维护编译工作。执行宿主操作系统中的各种命令。
Makefile是一个描述文件,定义一系列的规则来指定源文件之间的调用先后顺序。有自己特定的语法规则,可以定义函数及函数调用。可以集成各种系统命令。Makefile用于指导make程序如何完成工作。
Makefile示例:

sayhello: echo "hello world!"

其中sayhello称为目标,下方的 echo “hello world!” 是实现目标的命令。其中echo前面是TAB制表符,而不能是空格。
对于文件名,可以叫Makefile或makefile,也可以自定义名称。对于是否自定义Makefile文件名的区别在于使用方式不同。
采用默认名称makefile或Makefile:有两种方法,我们的Makefile文件名为Makefile
make -f 文件名 目标名


make -f Makefile sayhello

【C-C++|Makefile基础学习(一)——从依赖到伪目标】或者
make 目标名


make -f make.txt sayhello

如果不指定目标名字,则默认执行最前面的目标。
二、Makefile基本结构与依赖 Makefile由一个个规则组成,一个规则的结构大致如下:
targets : prerequisites commands

targets可以有多个目标,目标之间空格隔开,prerequisites可以包含多个依赖项,依赖项之间空格隔开。
其中 target 为我们要构建的目标,prerequisite为构建目标的依赖项。command为构建目标所需的命令。
举例子来说明,有两个c语言程序文件,func.c和main.c:
func.c文件
//func.c #include void func() { printf("hello world!\n"); }

main.c文件
//main.c extern void func(); int main() { func(); return 0; }

Makefile文件:
all main : main.o func.o gcc main.o func.o -o main main.o : main.c gcc -o main.o -c main.cfunc.o : func.c gcc -o func.o -c func.c

目标依赖规则:
  • 当目标不存在时,执行对应命令。
  • 当依赖在时间上比目标更新时,执行对应命令。
  • 当依赖关系连续存在时,要依次向上回溯每个目标。
上面那个Makefile中,all和main都是目标。all是没有规则的终极目标,他可以用作生成多个目标。把main和all写在一起的话,make就会检查main的依赖,如果main是最新的就不会执行编译。
上述Makefile文件,执行make all或 make 命令的时候,先检查,main是否存在,如果不存在则检查main的依赖项,main.o和func.o这两个目标,依次向上检查,生成目标。
如果目标存在,但依赖项比目标时间要新,则也要向上检查,生成目标。
三、伪目标的引入 Makefile中的目标指什么?
  • Makefile中目标一般对应着一个文件
  • make比较目标文件和依赖之间的新旧关系,如果依赖新则执行命令
  • make以文件处理作为第一优先级
为什么需要引入伪目标?
一个场景是,Makefile文件中有一个名为clean的目标。对应的命令是清除相应目标文件。如果当前工作目录下没有名为clean的文件,这样是没问题的。但是如果当前目录下存在名为clean的文件,那么make每次检查这个目标的时候就会发现这个文件已经存在了,clean是最新的,导致clean目标对应的清除命令不会执行。
伪目标的用法?
先定义,再使用。

    推荐阅读