Linux基础工具|自动化构建工具make和makefile

文章目录

1.make概念

make是一个指令,makefile是一个在当前目录下存在的一个具有特定格式的文件。

如果在Linux中编写了大量的代码文件,难不成要一个一个使用gcc/h++编译吗,要是代码出了问题,修改后又需要编译怎么办?因此出现了make这样的自动化构建工具。

2.编写.c/.cpp源文件

先在一个目录下编写一个或多个.c源文件。

3.编写makefile文件

  1. 首先touch一个makefile文件

  2. makefile内部编写目标文件、依赖文件列表、依赖方法

  3. 写入用作清理的伪目标,.PHONY是修饰伪目标的关键字

bash 复制代码
#make指令自顶向下执行,如果直接使用make指令就会执行第一份依赖命令

#目标文件:依赖文件列表
#   依赖方法(Linux下的命令)
#.PHONY:伪目标(重点是执行方法而不是目的("phony"即"假的,伪的"))
#   依赖方法

run:main.c #依赖关系
    gcc main.c -o run #依赖方法

.PHONY:clean #没有依赖关系,设定为伪目标
clean:
    rm -f run #依赖方法
  1. 使用make指令运行makefile文件,不指定目标直接使用make指令,就会自动找第一对依赖关系和依赖方法(即makefile的第一个目标)。

4.运行指令

bash 复制代码
$ ll
total 8
-rw-rw-r-- 1 limou limou 147 Sep 14 10:51 main.c
-rw-rw-r-- 1 limou limou  62 Sep 14 10:53 makefile
$ cat main.c
#include <stdio.h>
int main()
{
    int i = 0;
    for(i; i < 10; i++)
    {
        printf("%d ", i * i);
    }
    printf("\n");
    return 0;
}
$ cat makefile
run:main.c
    gcc main.c -o run
.PHONY:clean

clean:
    rm -f run

$ make run
gcc main.c -o run

$ ll
total 20
-rwxrwxr-x 1 limou limou 8408 Sep 14 10:54 run
-rw-rw-r-- 1 limou limou  147 Sep 14 10:51 main.c
-rw-rw-r-- 1 limou limou   62 Sep 14 10:53 makefile

$ ./run
0 1 4 9 16 25 36 49 64 81 

$ make clean
rm -f run

$ ll
total 8
-rw-rw-r-- 1 limou limou 147 Sep 14 10:51 main.c
-rw-rw-r-- 1 limou limou  62 Sep 14 10:53 makefile

5.重复指令

很多书都会写:"伪目标总是会被执行的"。例如:

  1. make run/make指令是不能被重复调用的(会显示make:'run' is up to date.

    除非我们要编译的源文件的最近修改时间发生了变动,也就是说如果源文件没有经过修改,make run是不会再次编译的,因为这样做的效率低下(大型的文件编译的时间非常久))。

    另外如果我们对源文件使用touch指令更新修改时间,那么就也是能重复使用make main指令。

  2. make clean指令总是可以被调用的。因此"总是被执行"的另外一个说法是"总是会根据依赖关系,执行依赖方法"。

补充:使用stat可以查看文件的三个重要时间

  1. Access:文件最近被访问的时间(即:读取的时候,touch只更改这个时间,但是由于Access也是属性,所以这个改动也会同时改动Change属性),如果修改了文件也算访问。不过由于读取文件是高频工作,因此Linux修改了内核,只会在一定时间后进行修改,不会读取一次就修改一次(每次都修改就会导致反复访问磁盘,导致效率低下)

  2. Modify:文件的最近内容修改时间(make指令就是看这个文件来确认是否要重新编译的),不过有的时候改变内容会改变大小,导致文件的属性变化,Change也发生了变化

  3. Change:文件的最近属性修改时间,比如:文件权限的设置、文件的大小改变

注意:文件改变的本质不是时间变化,而是随着时间文件内容产生新旧内容。

6.自动推导

make可以进行自动推导(嵌套代码),但是一般不建议像下面这么写,只是为了证明make可以自动推导这一现象:

bash 复制代码
run:main.o
    gcc main.o -o run
main.o:main.s
    gcc -c main.s -o main.o
mian.s:main.i
    gcc -S mian.i -o mian.s
mian.i:mian.c
    gcc -E main.c -o main.i

.PHONY:clean

clean:
    rm -f run main.i main.s main.o

7.拓展学习

上面的知识在平时的学习和使用中就很够用了,但是我们可以拓展学习一些其他的内容。

  1. 有的时候不希望打印出使用make命令的信息,这个时候可以在每个依赖方法前加上@符号,这样就不会回显信息了

  2. makefile允许创建变量,因此我们上面的代码还可以改写为更加普遍的(变量的赋值一般不建议留空格,不过您其实可以将这种变量作为宏来理解)

    bash 复制代码
    cc=gcc
    src=main.c
    target=run
    
    $(TAGET):$(src) #依赖关系
        $(cc) $(src) -o $(target) #依赖方法
    
    .PHONY:clean #伪目标
    clean:
        rm -f $(target) #依赖方法
  3. makefile还可以在依赖方法省略依赖关系用到的依赖文件列表和目标文件

    bash 复制代码
    run:main.c #依赖关系
        gcc $^ -o $@ #依赖方法,$^表示冒号右侧内容,$@表示冒号左侧的内容
    
    .PHONY:clean #没有依赖关系,设定为伪目标
    clean:
        rm -f run #依赖方法
相关推荐
NiNg_1_23433 分钟前
使用Docker Compose一键部署
运维·docker·容器
萠哥啥都行37 分钟前
Linux安装Docker以及Docker入门操作
运维·docker·容器
王哲晓38 分钟前
Linux通过yum安装Docker
java·linux·docker
小江湖199443 分钟前
元数据保护者,Caesium压缩不丢重要信息
运维·学习·软件需求·改行学it
gopher95111 小时前
linux驱动开发-中断子系统
linux·运维·驱动开发
码哝小鱼1 小时前
firewalld封禁IP或IP段
linux·网络
鼠鼠龙年发大财1 小时前
【x**3专享】安装SSH、XFTP、XShell、ARM Linux
linux·arm开发·ssh
nfgo1 小时前
快速体验Linux发行版:DistroSea详解与操作指南
linux·ubuntu·centos
吃面不喝汤662 小时前
如何配置和使用自己的私有 Docker Registry
运维·docker·容器
Rookie_explorers2 小时前
Linux下go环境安装、环境配置并执行第一个go程序
linux·运维·golang