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 #依赖方法
相关推荐
honey ball4 小时前
R & S的EMI接收机面板
linux·运维·网络
木下-俱欢颜5 小时前
搭建基于chrony+OpenSSL(NTS协议)多层级可信时间同步服务
运维·网络安全·udp·ssl
旧故新长6 小时前
访问 Docker 官方镜像源(包括代理)全部被“重置连接”或超时
运维·docker·容器
柳如烟@6 小时前
在Rocky Linux 9.5上部署MongoDB 8.0.9:从安装到认证的完整指南
linux·运维·mongodb
struggle20257 小时前
AgenticSeek开源的完全本地的 Manus AI。无需 API,享受一个自主代理,它可以思考、浏览 Web 和编码,只需支付电费。
人工智能·开源·自动化
搬码临时工7 小时前
电脑怎么远程访问服务器?4种常见的简单方法
运维·服务器·网络·异地访问
北漂老男孩7 小时前
ChromeDriver 技术生态与应用场景深度解析
java·爬虫·python·自动化
QQ2740287567 小时前
Kite AI 自动机器人部署教程
linux·运维·服务器·人工智能·机器人·web3
文牧之7 小时前
PostgreSQL 配置设置函数
运维·数据库·postgresql
.小墨迹7 小时前
Apollo学习——planning模块(3)之planning_base
linux·开发语言·c++·学习·自动驾驶