makefile介绍

makefile概述

​ Makefile是一种用于自动化构建和管理程序的工具。它通常用于编译源代码、链接对象文件以生成可执行文件或库文件。Makefile以文本文件的形式存在,其中包含了一系列规则和指令,用于描述程序的依赖关系以及构建步骤,指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译。核心思想是根据文件的最后修改时间来确定哪些部分需要重新编译,以及以什么顺序来执行编译步骤。每个规则由一个目标(target)和一组依赖项(dependencies)组成,以及执行指令(commands)。

​ makefile带来的好处就是自动化编译,一旦写好就只需要一个make指令来实现该文件。当执行make命令时,Makefile解析并执行其中的规则。它首先检查目标文件和依赖文件的时间戳,如果目标文件不存在或其依赖项的时间戳较新,则执行该规则所定义的指令来生成目标文件。这种方式可以避免不必要的重新编译,提高构建效率。Makefile中常见的指令包括编译源代码、链接对象文件、复制文件、清理生成的文件等。通过定义变量和规则,可以使Makefile更加灵活和可维护。

​ Makefile广泛应用于C、C++等编程语言的项目中,但也可以用于其他类型的项目。它是一种跨平台的工具,可以在不同的操作系统上使用,例如Linux、Unix和Windows等。

​ 总而言之,Makefile是一种用于自动化构建和管理程序的工具,通过描述依赖关系和构建步骤,可以有效地管理大型项目的编译过程,并提高开发效率。

makefile文件命名和规则

文件命名

makefile或者Makefile

makefile 规则

​ 一个makefile文件可以有多个规则

目标 ...:依赖...
   命令(shell命令)
   ...

目标:最终要生成的文件

依赖:生成目标所需要的文件或是目标

命令:该target要执行的命令,可以有多个命令行,每个命令行都以TAB 缩进字符开始,[Tab]告 诉 make 此行是一个命令行;

注意:

·makefile的其他规则都是为第一条规则服务的

·依赖中如果有一个以上的文件更新的话,定义的命令就会被执行

·如果一个工程有3个头文件和8个c文件,为了完成前面所述的那三个规则,我们的makefile 应该是下面的这个样子的:

edit : main.o kbd.o command.o display.o \
        insert.o search.o files.o utils.o
    gcc -o edit main.o kbd.o command.o display.o \
        insert.o search.o files.o utils.o
 
main.o : main.c defs.h
    gcc -c main.c
kbd.o : kbd.c defs.h command.h
    gcc -c kbd.c
command.o : command.c defs.h command.h
    gcc -c command.c
display.o : display.c defs.h buffer.h
    gcc -c display.c
insert.o : insert.c defs.h buffer.h
    gcc -c insert.c
search.o : search.c defs.h buffer.h
    gcc -c search.c
files.o : files.c defs.h buffer.h command.h
    gcc -c files.c
utils.o : utils.c defs.h
    gcc -c utils.c
clean :
    rm edit main.o kbd.o command.o display.o \
        insert.o search.o files.o utils.o

使用案例

app:sub.c add.c mult.c div.c main.c
        gcc sub.c add.c mult.c div.c main.c -o app

在makefile文件里写入以上规则,即可执行:

lin@lin-virtual-machine:~/Linux/lesson05/calc$ make
gcc sub.c add.c mult.c div.c main.c -o app
lin@lin-virtual-machine:~/Linux/lesson05/calc$ ./app
a = 20, b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 1.666667

可以有多条规则,接下来我们换一种写法:

app:sub.o add.o mult.o div.o main.o
        gcc sub.o add.o mult.o div.o main.o -o app

sub.o:sub.c
        gcc -c sub.c -o sub.o

add.o:add.c
        gcc -c add.c -o add.o

mult.o:mult.c
        gcc -c mult.c -o mult.o

div.o:div.c
        gcc -c div.c -o div.o

main.o:main.c
        gcc -c main.c -o main.o                          

执行结果:

lin@lin-virtual-machine:~/Linux/lesson05/calc$ make
gcc -c sub.c -o sub.o
gcc -c add.c -o add.o
gcc -c mult.c -o mult.o
gcc -c div.c -o div.o
gcc -c main.c -o main.o
gcc sub.o add.o mult.o div.o main.o -o app
lin@lin-virtual-machine:~/Linux/lesson05/calc$ ./app
a = 20, b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 1.666667

在上面的规则里,当第一条规则没找到对应的依赖时,会依次往下找对应的目标规则

同时这里也反映了之前所说的,makefile里面的其他规则通常是为第一条规则服务的

对于上面的规则,如果我只对main.c函数做修改,那么我们再一次执行make,会发生什么呢:

lin@lin-virtual-machine:~/Linux/lesson05/calc$ make
gcc -c main.c -o main.o
gcc sub.o add.o mult.o div.o main.o -o app

会发现比原先少了很多。

很显然,在执行makefile文件时,会比较依赖和目标文件的时间,正常情况下main.c应该早于main.o,这样不会执行对应的编译规则,但是如果晚于,就会执行,这就是检测更新的手段。

我们编写的两个版本,第一个简短,但是第一个如果有一个.c文件发生修改,则需要重新编译所有的.c文件,效率比第二个版本其实更低。

makefile的变量

预定义的变量:

AR:归档维护程序的名称,默认值为ar

CC:c编译器的名称,默认值为cc

CXX:c++编译器名称,默认值位g++

$@:目标的完整名称

$<:第一个依赖文件的名称

$^:所有的依赖文件

获取变量的值:$(变量名)

模式匹配

%.o:%.c

–%:通配符,匹配一个字符串

–两个%匹配的是同一个字符串

函数
在这里插入图片描述

在这里插入图片描述

对makefile文件进行化简

#定义变量
src= sub.c add.c mult.c div.c main.c
target=app
$(target):$(src)
        $(cc) $(src) -o $(target)	
        
%.o:%.c
        $(CC) -c $< -o $@

如下是利用函数进行化简:

#定义变量
src= $(wildcard ./*.c)
objs=$(patsubst %.c,%.o,$(src))
target=app
$(target):$(objs)
        $(cc) $(objs) -o $(target)	
        
%.o:%.c
        $(CC) -c $< -o $@
        
.PHONY:clean        
clean:
        rm $(objs) -f

需要执行clean规则时,我们需要在make后加上clean

即命令行输入如下命令:

make clean
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值