129 Linux 系统编程7 ,makefile 的编写和解析

本文介绍了makefile的编写方法与应用。makefile是一种脚本语言,可用于项目代码编译管理,节省编译时间。文中详细讲解了makefile的规则、函数、自动变量、模式规则等内容,还探讨了运行脚本、处理伪目标、优化参数等问题,并给出了相关练习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前文中,我们有多少个.c文件,就需要build 出来多少个.o文件

假设我们的项目很大,怎么管理这些 .c文件呢?

这里就要学习一个make文件的编写了。

makefile 本质上是一个脚本语言

脚本语言实际上就是将一系列命令放在一起执行

makefile 的用途:

项目代码编译管理

节省编译项目时间

一次编译终身受益

Makefile 工作内容:

makefile 会把遇见的第一条指令作为他的终极指令

但是如果开发者在前面加了关键字 ALL

就会把ALL:后面的 做为 makefile 的终极目标

因此一般,我们都会写ALL

ALL:a.out

make file的写法:

命名只有两种,一种叫做makefile 一种叫做Makefile

一个规则,目标:依赖条件

目标:依赖条件

                (一个tab缩进)命令

hello:hello.c
        gcc hello.c -o hello

解释:

目标是生成hello 这个可执行文件

依赖条件的意思是:要生成hello这个目标文件,需要依赖于 hello.c这个文件

然后缩进,这个是语法格式要求

命令的意思是:怎么使用 hello.c生成hello这个目标文件

基本原则的原文:

        若想生成目标, 检查规则中的额依赖条件是否存在,如不存在,则寻找是否有规则用来生成该依赖文件。

好,我们把这段话从自己刚才写的例子理解一下:

上述我们写的时候 是目标是 hello ,依赖条件是hello.c

我们改写一下 先从hello.c生成 hello.o

然后从hello.o生成目标文件hello

hello:hello.o
        gcc hello.o -o hello

hello.o:hello.c
        gcc -c hello.c -o hello.o

hunandede@hunandede-virtual-machine:~/day03/makefilestudy$ ls
hello.c  makefile
hunandede@hunandede-virtual-machine:~/day03/makefilestudy$ make
gcc -c hello.c -o hello.o
gcc hello.o -o hello
hunandede@hunandede-virtual-machine:~/day03/makefilestudy$ 

1.学习这个之前,我们将昨天的部分整理过来并 按照g++的方法手动build 一下

文件内容如下,head 中存放.h文件

src 文件夹下放着所有的.cpp文件

g++ src/test.cpp src/addfunc.cpp src/devfunc.cpp src/mulfunc.cpp src/subfunc.cpp -o a.out -I ./head

如上,我们build 出来了一个 a.out文件,如下是执行 a.out文件

hunandede@hunandede-virtual-machine:~/day03/makefilestudy2$ ./a.out 
a+b = 15
a-b = 5
a*b = 50
a/b = 2

2. 改造成makefile 的写法

a.out:addfunc.o subfunc.o mulfunc.o devfunc.o test.o
	g++ addfunc.o subfunc.o mulfunc.o devfunc.o test.o -o a.out
addfunc.o:addfunc.cpp
	g++ -c addfunc.cpp -o addfunc.o -I../head

subfunc.o:subfunc.cpp
	g++ -c subfunc.cpp -o subfunc.o -I../head

mulfunc.o:mulfunc.cpp
	g++ -c mulfunc.cpp -o mulfunc.o -I../head

devfunc.o:devfunc.cpp
	g++ -c devfunc.cpp -o devfunc.o -I../head

test.o:test.cpp
	g++ -c test.cpp -o test.o -I../head

执行make 就会生成a.out文件,然后我们运行 a.out文件

hunandede@hunandede-virtual-machine:~/day03/makefilestudy2/src$ ./a.out 
a+b = 15
a-b = 5
a*b = 50
a/b = 2

 这里有一个问题:我们上面为什么要将所有的.c分开写,转成.o,然后再使用使用所有的.o生成 a.out呢? 直接 g++ addfunc.cpp subfunc.cpp mulfunc.cpp divfunc.cpp -o a.out 写起来不是更方便吗?

原因是 当addfunc.cpp的代码有改动后,重新build的时候,这么一行的写法会让所有的.cpp文件编译成.o,然后将所有的.o文件再链接成 a.out文件。

实际上只有 addfunc.cpp改动了,其他的都没有变化,让其他的跟着重新build出来自己的.o文件是很没有必要的。因此要分开写。

回顾 g++编译的四个阶段

预处理:头文件展开,宏替换,注释去掉

编译:检查语法错误,将c语言变成汇编语言,消耗时间和系统资源最多

汇编:将汇编语言变成 二进制指令

链接:数据段合并以及地址回填,将函数库中相应的代码组合到目标文件中

引申出的另一个问题:g++是如何知道addfunc.cpp有变化了,那就要看file 属性中的ctime了,changed time,当一旦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值