linux 下项目自动化构建工具makefile详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40921797/article/details/82344913

什么是makefile

一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。(以上内容来源与百度百科)
在我的理解makefile就是一个plan,一个记录在文件中详细的plan计划,我们规定好要用什么文件,生成什么文件,以及用什么具体操作。然后系统在接收到信号后,就会根据我们的命令去完成我们想要的操作

什么是make

make 是一个命令,当我们利用vim 完成好makefile的内容后,只需要make一下,系统会自动找到当前目录下的makefile文件,对其 内容进行解析,最后实现我们预期的结果

make,makefle连用操作

  1. 输入命令打开makefile:vim makefile
    这里写图片描述
  2. 要生成目标对象文件名称 依赖对象文件名称
    (注意打开vim输入要切换到输入模式哦详细参见:linux vi/vim编辑器
    这里写图片描述
  3. 换行后:记得要输入一个制表符(及按Tab键)不可以按空格。
    这里写图片描述
  4. 为了生成目标对象文件所要执行的编译命令
    这里写图片描述
  5. esc 切换到普通模式 “ :wq ”保存退出
    这里写图片描述
  6. 退出后输入命令:make 及完成gcc工作
    这里写图片描述

makefile特点

  1. make有一个特点就是不重复生成同样内容。当我们的文件内容是最新的,make命令后,不会重复生成,而是告诉我们一句话:文件已经是最新的了。
  2. make会自动判断,若文件存在内容是否有修改,若有修改则从新剩下,若没有则不生产。
  3. make是以对象为目标进行操作的,而目标永远都只有一个,make当完成目标对象的生成后就会立马退出,不会晚上下方多余操作。也就是说,我们如果没有巧妙的方法,make永远只生成文件内容最上方的一个目标文件。
  4. 那我们想要生成多个目标文件对象时,怎么办呢?
    举个例子:
all :test1 test2

test1:test1.c
    gcc test1.c -o test1
test2:test2.c
    gcc test2.c -o test2

我们利用一个假对象,也就是没有具体操作生成的,没有用处的对象all,因为实现all需要test1,test2.系统就向下找,发现生成test1 需要进行操作gcc,生成test2需要操作gcc,然后生成好test1,test2然乎到生成all的操作中去。因为没有操作,所以我们的all是不会真的被生成的。
打个比方:西游记经常有一个山鬼需要拿两个童男童女祭奠报今年风调雨顺,所以村里的两户人家,就需要生两个童男童女,无论最后有什么风调雨顺,两个童男女都是要准备的。

clearn

因为我们的makefile目标文件最新的只会生成一次,但是我们就是想要他重复编译怎么办呢?clearn操作
我们在要生成的目标文件以及其操作下方写上这样一段话:

clearn:
    rm -f cond

你说一般情况下这句话会被执行吗?
-不会的,当我们完成第一个目标文件生成,无论有没有真的生成吧,都返回了,根本不会执行到这段话。那这句话写到这有什么用呢?
–是为我们在makefile外,和make命令连用使用的:
这里写图片描述
我们就可以通过这样手动清理掉目标文件,然后重新生成了。

预定义变量

//$^ 代表冒号“ :”右边所依赖的文件,去除重复文件
//$+ 代表冒号“ :”右边所依赖的文件,不去除重复文件
//$@ 代表冒号 : 左边的要生成的目标文件对象
//$< 代表冒号 :右边所依赖的文件对象中的第一个依赖文件
test:test.c
    gcc $^ -o $@

makefile中的伪对象

 # .PHONY: 对象名      
 # 声明一个伪对象,意味着不管这个对象文件是否存在或者更新都需要每次重新生成要声明的是真正要生成的文件
 .PHONY : cond

1.这里注意,makefile 和要gcc/g++编译的其他文件不同,在makefile中注释是 “ # ”
2.

*     :: 表示任意一个或多个字符
?     :: 表示任意一个字符
[...] :: ex. [abcd] 表示a,b,c,d中任意一个字符, [^abcd]表示除a,b,c,d以外的字符, [0-9]表示 0~9中任意一个数字
~     :: 表示用户的home目录

makefile中变量定义以及追加

# := 只能使用前面定义好的变量
OBJ1 := proA.o proB.o
OBJ2 := $(OBJ1) proC.o

#  = 可以使用后面定义的变量
OBJ2 = $(OBJ1) proC.o
OBJ1 = proA.o proB.o
# += 追加操作
SRCS := proA.c proB.c
SRCS += proC.c

                                       部分内容来源网络

猜你喜欢

转载自blog.csdn.net/weixin_40921797/article/details/82344913