Linux中项目自动化构建工具-make/Makefile

前言

前面我们学习了vim的使用,直到vim是一个文本编辑器,那么要形成可执行程序还需要我们手动编译,这是一个相当繁琐的步骤。因此需要一些工具来简化这个步骤。

简单使用示范

首先我们需要清楚,make是一个命令而Makefile是一个文件。

构建

首先我们先编写一个code.c文件:

然后创建一个makefile(或Makefile)文件,在里面写入如下内容:

注意此时我们的文件仅有:

shell 复制代码
[zhangwho@VM-0-2-centos code]$ ll
total 8
-rw-rw-r-- 1 zhangwho zhangwho 463 Dec  4 18:17 code.c
-rw-rw-r-- 1 zhangwho zhangwho  36 Dec  4 18:21 makefile

运行make之后:

shell 复制代码
[zhangwho@VM-0-2-centos code]$ make
gcc -o myexe code.c	
[zhangwho@VM-0-2-centos code]$ ll
total 20
-rw-rw-r-- 1 zhangwho zhangwho  463 Dec  4 18:17 code.c
-rw-rw-r-- 1 zhangwho zhangwho   36 Dec  4 18:21 makefile
-rwxrwxr-x 1 zhangwho zhangwho 8360 Dec  4 18:24 myexe

可以看到自动生成了myexe的可执行程序.

尝试运行:

shell 复制代码
[zhangwho@VM-0-2-centos code]$ ./myexe 
hello Linux! M=100
hello Linux! M=100
hello Linux! M=100

非常完美!

清理

我们现在还可以给makefile附上一些清理临时文件的功能:

尝试运行make clean:

shell 复制代码
[zhangwho@VM-0-2-centos code]$ make clean
rm -f myexe
[zhangwho@VM-0-2-centos code]$ ll
total 8
-rw-rw-r-- 1 zhangwho zhangwho 463 Dec  4 18:17 code.c
-rw-rw-r-- 1 zhangwho zhangwho  68 Dec  4 18:27 makefile

直接将myexe删除了!

运行原理

makefile

学习了如何使用make之后,我们来看看makefile的构成。

首先我们将第一行称为依赖关系,第二行称为依赖方法。

其中第一行':'后的部分称为依赖文件列表,可以有多个文件,按照空格分割,如:code.c test.c love.c

':'前的称为目标文件

从语法上来讲,第二行的依赖方法必须以Tab开头而非Space。

make运行过程

  1. 首先我们输入make命令
  2. make会在当前目录下找名字叫"Makefile"或"makefile"的文件。
  3. 然后make根据makefile的内容完成编译或清理工作。

make clean

前面我们已经了解make会默认生成myexe的目标文件,那么clean和PHONY又是什么呢?

首先我们需要明确一个概念:clean也是目标文件,虽然说运行这个命令没有形成什么文件就是了/

并且clean他是不依赖于任何文件的!

那么我们很容易想到,make命令会默认生成第一个目标文件。

因此呢,我们的make还可以像这样调用:

shell 复制代码
[zhangwho@VM-0-2-centos code]$ make myexe
gcc -o myexe code.c	

.PHONY

那么.PHONY又是什么呢?

别急我们再执行一次make看看:

shell 复制代码
[zhangwho@VM-0-2-centos code]$ make
make: `myexe' is up to date.

holy shit!我们的make文件被拦截了。因为此时目标文件已经是最新的了,主要是上次make之后,依赖文件没有更新。如果此时我们修改一下依赖文件:

shell 复制代码
[zhangwho@VM-0-2-centos code]$ ll code.c 
-rw-rw-r-- 1 zhangwho zhangwho 463 Dec  4 18:17 code.c
[zhangwho@VM-0-2-centos code]$ touch code.c
[zhangwho@VM-0-2-centos code]$ ll code.c
-rw-rw-r-- 1 zhangwho zhangwho 463 Dec  4 18:48 code.c

我们用touch命令修改了依赖文件的acm时间,然后看看能不能make吧:

shell 复制代码
[zhangwho@VM-0-2-centos code]$ make
gcc -o myexe code.c	

可以看到此时就可以make了。

也就是make指令会自动检索依赖文件是否更改,如果没有就不给你执行.

像clean都没有依赖文件,那就从头到尾只能执行一次咯!

因此为了让目标文件能一直生成而不依赖于依赖文件是否改变,仅需在前面加上 .PHONY 列表就可以了。

当然我们也可以让myexe一直生成,就是没什么意义罢了

为什么makefile对最新形成的目标文件,默认不重新形成?

简单来说就是为了提高编译效率。

当写的项目非常大的时候,一个目标文件想要重新编译就会带动其他所有目标文件编译。这是非常消耗资源的,因此默认最新形成的不重新编译。

那么这是怎么做到的?

上面已经提到了,就是看依赖文件和目标文件的acm时间。

如果目标文件的生成时间晚于依赖文件的修改时间,自然说明目标文件是最新的。

$ @ ^在makefile 的含义

首先@可以代表目标文件,^代表所有依赖文件,$的含义就是提取内容。因此我们上面的makefile符号还可以这样写:

实则是一样的效果哦!

makefile完整写法

前面我们不是定义了一个make clean来清理myexe吗,有没有读者觉得这多少有点多余了,毕竟只需要rm myexe即可,还比make clean方便。

实际上是我们的makefile没写全,完整的写法如下:

简单使用下:

shell 复制代码
[zhangwho@VM-0-2-centos code]$ ls
code.c  makefile
[zhangwho@VM-0-2-centos code]$ make
gcc -E -o code.i code.c
gcc -S -o code.s code.i
gcc -c -o code.o code.s
gcc -o code.exe code.o
[zhangwho@VM-0-2-centos code]$ ls
code.c  code.exe  code.i  code.o  code.s  makefile
[zhangwho@VM-0-2-centos code]$ make clean
rm -f code.i code.o code.s code.exe
[zhangwho@VM-0-2-centos code]$ ls
code.c  makefile

可以看到我们的make执行逻辑是在找到依赖关系链中的已存在的依赖文件,然后一次性执行这些依赖关系。类似于递归的实现。

makefile的变量

每次写makefile都要写一堆重复的简单的工作是不是很无趣,有没有办法实现一个模板,然后简单套一下目标文件名和依赖文件名呢?

有的兄弟,有的!

这时候先看用法:

非常直观的用法吧,这时候我们只要将dest和src指向的名称改为目标文件和依赖文件就完成makefile的编写咯。

不显示执行的依赖方法

我们没make一下就会显示执行了什么依赖方法。像这样:

shell 复制代码
[zhangwho@VM-0-2-centos code]$ make
gcc -o code.exe code.c

多少有点缺少逼格。

为了去掉这些提示,我们只需在每个依赖方法前加上@符号即可:

shell 复制代码
[zhangwho@VM-0-2-centos code]$ make clean
[zhangwho@VM-0-2-centos code]$ ls
code.c  makefile
[zhangwho@VM-0-2-centos code]$ make
[zhangwho@VM-0-2-centos code]$ ls
code.c  code.exe  makefile

是不是一下就逼格上来了。

多行依赖方法

前面我们的makefile里面的每个依赖关系都只对应一个依赖方法,但这不是必要的。

实际上我们可以写多个依赖方法:

shell 复制代码
[zhangwho@VM-0-2-centos code]$ make
echo "compiler code.c to code.exe"
compiler code.c to code.exe

可以看到,一下子执行了多个命令哦。

相关推荐
chao1031 小时前
ubuntu下业务运行环境搭建
linux·运维·ubuntu
weixin_46681 小时前
Docker Dockerfile文件
linux·运维·服务器
赖small强1 小时前
【Linux C/C++ 开发】 GCC 编译过程深度解析指南
linux·c语言·c++·预处理·链接·编译·编译过程
做人不要太理性1 小时前
【Linux系统】ext2文件系统
大数据·linux·操作系统·文件系统
保持低旋律节奏1 小时前
linux——软件包、yum 安装和卸载
linux·运维·服务器
莫道桑榆晚丶1 小时前
Linux系统编程--------MP3项目实战
linux·学习
小oo呆2 小时前
【学习心得】Python好库推荐——pipx
linux·开发语言·python
龙吟游戏2 小时前
Ubuntu 25.10桌面版安装
linux·运维·ubuntu
筑梦之路2 小时前
centos 7 grub加密 —— 筑梦之路
linux·运维·centos