【Linux操作系统】makefile操作详解

一、makefile简介

在Linux中,Makefile是一种用于自动化构建和编译软件项目的工具。它通常用于管理大型项目中的源代码文件,以及定义项目的编译、链接和其他构建过程

Makefile是一种文本文件,其中包含了一系列的规则,这些规则定义了如何从源代码文件生成目标文件(如可执行文件或库文件),它用于自动化编译过程,提高开发效率,减少手动编译的繁琐和出错率

我们在一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率

可以说,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力

二、使用

1.规则

Makefile的核心是规则,每个规则都描述了如何生成一个或多个目标文件。规则的基本格式如下:

目标: 依赖文件  
<tab>命令

其中,目标是需要生成的文件,依赖文件是生成目标所需的文件,命令是生成目标所需执行的Shell命令

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

makefile文件写好后使用 make 指令运行makefile文件

2.依赖关系和依赖方法

依赖关系和依赖方法是构建自动化过程的核心
Makefile中的依赖关系和依赖方法是通过规则(rules)来定义的。

1.依赖关系

赖关系指的是源文件(如.c或.cpp文件)和目标文件(如.o对象文件或可执行文件)之间的关系。简单来说,就是哪些源文件需要被编译或重新编译来生成或更新目标文件。在Makefile中,这种关系通过规则的目标(target)和前置条件(prerequisites,也称为依赖)来定义。

例如,考虑一个简单的C程序,它由main.c和hello.c两个源文件组成,我们希望将它们编译成hello可执行文件。main.o和hello.o是这两个源文件编译后的对象文件。Makefile中的一个规则可能看起来像这样:

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

在这个例子中,hello依赖于main.o和hello.o,而main.o依赖于main.c,hello.o依赖于hello.c。这就是依赖关系的表示。

2.依赖方法

依赖方法指的是如何根据依赖关系来生成目标文件。在Makefile中,这是通过规则中的命令(commands)来定义的。当make工具发现某个目标文件(或它的任何前置条件)比规则中列出的文件新时,它会执行该规则中的命令来生成或更新目标文件。

继续上面的例子,hello目标的依赖方法是使用gcc命令将main.o和hello.o链接成hello可执行文件。同样地,main.o和hello.o的依赖方法分别是使用gcc
-c命令分别编译main.c和hello.c。

3.自动变量

在Makefile中,还有一些自动变量可以帮助简化规则的编写。
例如, @ 代表规则中的目标, @代表规则中的目标, @代表规则中的目标,<代表规则中的第一个依赖。使用这些自动变量,上面的规则可以简化为:

hello: main.o hello.o  
    gcc $^ -o $@  
  
main.o: main.c  
    gcc -c $<  
  
hello.o: hello.c  
    gcc -c $<

这里, 代 表所有前置条件的列表,而 ^代表所有前置条件的列表,而 表所有前置条件的列表,而@仍然代表目标文件

4.伪目标

使用make指令运行makefile文件时要确保目标文件的任何一个依赖文件比目标文件更新(即依赖文件的最后修改时间晚于目标文件的最后修改时间)

即“如果依赖文件比可执行代码更新,则重新构建可执行代码”
否则就会报错,这是Makefile保证软件项目构建正确性和一致性的重要机制之一。

如果你想要确保某个可执行代码(目标文件)总是被重新构建,而不管其依赖文件是否变化,你可以使用伪目标来实现这一点

在Makefile中,伪目标(也称为伪规则或伪依赖)是一种特殊的目标,它不代表一个真实的文件名。

在Makefile中,你可以通过.PHONY特殊目标来明确声明一个或多个伪目标。这样做的好处是,make会知道这些目标不是文件名,并且在执行这些目标时不会检查它们是否存在或是否最新。

.PHONY: clean all install  
  
clean:  
    rm -f *.o hello  
  
all: hello  
  
hello: hello.o  
    gcc -o hello hello.o  
  
install: hello  
    cp hello /usr/local/bin/

在这个例子中,clean、all和install都被声明为伪目标。这意味着,无论你运行make clean、make all还是make install,这些目标下的命令都会被执行,而不论对应的文件是否存在或是否最新

5.形成多个可执行文件

一般来说,makefile形成目标文件的时候,默认是从上到下扫描makefile文件,默认形成的是第一个目标文件(默认只形成一个可执行文件)

如果我们想要形成多个可执行文件,可以将这些文件作为 all 的依赖项列出。

# 定义编译器  
CC=gcc  
  
# 定义编译选项  
CFLAGS=-Wall  
  
# 定义可执行文件  
all: program1 program2  
  
# program1 的构建规则  
program1: program1.o  
    $(CC) $(CFLAGS) -o $@ $^  
  
# program1.o 的构建规则  
program1.o: program1.c  
    $(CC) $(CFLAGS) -c -o $@ $<  
  
# program2 的构建规则  
program2: program2.o  
    $(CC) $(CFLAGS) -o $@ $^  
  
# program2.o 的构建规则  
program2.o: program2.c  
    $(CC) $(CFLAGS) -c -o $@ $<  
  
# 清理构建文件的规则  
clean:  
    rm -f *.o program1 program2  
  
.PHONY: all clean

在这个例子中,all 目标依赖于 program1 和 program2,这意味着当你运行 make 或 make all 时,Makefile 会检查 program1 和 program2 是否已经是最新的,如果不是,它会根据提供的规则来构建它们。

.PHONY: all clean 这行告诉 make,all 和 clean 是伪目标,不对应任何文件名。这对于防止 make 将它们解释为文件名是很有用的,尤其是当它们与目录中的文件名相同时。

通过这种方式,你可以很容易地扩展Makefile来构建更多的文件,只需将新的目标添加到 all 的依赖列表中,并为它们提供相应的构建规则即可。

  • 23
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

饿了我会自己捡代码吃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值