Linux笔记---Makefile的简单用法

news/2024/10/26 23:25:35/

1. 什么是Makefile

Makefile 是一种用于自动化构建和管理项目的工具,特别是在软件开发中非常常见。

它包含了一系列规则(rules)和指令,描述了如何编译和链接源代码文件,以及生成最终的可执行文件或库文件。

简单来说,在系统中存在一个叫做make的命令,该命令被使用之后,会在当前目录下寻找一个叫做makefile/Makefile的文件,依据其内定义的规则进行项目的自动化构建。

当我们的项目由多个文件构成时,Makefile能够极大地简化我们构建程序的过程。

Makefile 的优点

自动化构建:通过 Makefile 可以自动化执行编译、链接等构建任务,减少手动操作。

增量构建:Makefile 可以根据文件的时间戳来实现增量构建,避免不必要的重复构建过程。

可移植性:Makefile 是跨平台的构建工具,可以在不同的操作系统上使用


2. Makefile的基本知识和基本用法


2.1 目标,依赖关系和命令

Makefile 的基本结构包括目标、依赖关系和命令

目标是指要构建的文件或动作,依赖关系描述了生成目标所需的前置条件,而命令则是实际执行的操作,通常是编译源文件、链接目标文件或执行其他操作。

例如,我们需要生成一个test.exe(在Linux下可不带后缀)的可执行程序,而编译出test.exe依赖于其源文件test1.c,test2.c,test3.c...等,则可用下面的语句表述:

目标:目标依赖的文件命令...

注意:命令前有且仅能有 "一个TAB" 键,不可以手动敲4个空格。 

保存退出,输入make命令:

 可以看到,我们再输入make命令并回车之后,自动执行了我们预设的命令,并编译生成了可执行程序test。

如果不希望被自动执行的命令回显到屏幕上,我们可以在命令前加上 "@" : 


2.2 伪目标

在一个Makefile文件中可以有多个目标,默认会执行第一个目标,也可在make后紧跟要执行的目标,以指定执行某个目标:

 上面提到过,目标也可以是动作,这时常常不生成文件,我们叫这种目标为伪目标。

例如,我们有一个目标(clean)的作用是清除生成的可执行程序以重新生成:


 2.3 .PHONY

相信看完上面一小节之后,大家会都很好奇.PHONY是什么。其实,被.PHONY修饰的目标就是始终会执行的目标。

这么说来,test和shishen不是始终会被执行的目标吗?我们尝试多次执行make,会发现:

第一次执行可以成功,然而之后再去执行却发现无法成功,而显示test已是最新。

这是因为test所依赖的文件没有发生更新,所以再次进行make没有任何意义,只会浪费系统资源。

所以,make仅仅提示test已是最新,而不去执行默认目标。

Makefile 通过检查目标文件及其依赖关系的时间戳,确定哪些文件需要重新构建。如果目标文件需要重新构建,Makefile 将按照规则中定义的命令来执行,以生成最终的目标文件。这种方式允许进行增量构建,即只重新构建发生变化的文件,从而提高构建效率。


2.4 自动构建工程的工作原理

Makefile自动构建工程的工作原理:如果某个目标的依赖文件不存在当前目录下,make就会尝试查找与依赖文件同名的目标并优先执行。

如果没有同名目标则会报错,即使在某个目标中存在生成所需文件的指令。

更准确地说,依赖关系列表中的元素默认为文件,当文件不存在时,认为其是同名目标,即使该目标不会生成所需文件,该目标也会被执行。

在下面这个例子中,我们让.c文件一步一步地生成可执行程序,而不是直接生成:

 可以看到,即使我们没有指定,其余的三个目标也自动执行了,而且顺序是按照依赖关系的先后进行的。

可以猜想,make程序的内部应该会维护一个栈,用于存储需要执行,但依赖关系不满足的目标。


3. 简化Makefile的技巧语法


3.1 宏定义

当然,不是C语言的那个宏定义,但是二者十分相似,例如:

此时,"SRC" 就代表了所需源文件的集合,定义的符号需要放到 "$()" 中才能使用

在指令部分,也可用 "$@" 代表目标,"$^" 代表所依赖的文件

3.2 通配符

在Makefile中,通配符为 "%" ,假如要将所有.c文件先编译为对应的.o文件,再进行链接(也是最常用的方式):

 3.3 相同后缀的集合

在源文件增多时,上面的Makefile需要在宏定义处增加对应的文件。

这未免太麻烦了,我们所使用的通配符也不能最大限度地发挥其作用。

而下面的写法可以解决这个问题:

 4. 大多数情况下通用的Makefile

BIN=code
CC=gcc
SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o)
LFLAGS=-o
FLAGS=-c
RM=rm -f$(BIN):$(OBJ)@echo "linking $^ to $@..."@$(CC) $(LFLAGS) $@ $^
%.o:%.c@echo "compling $< to $@..."@$(CC) $(FLAGS) $<.PHONY:clean
clean:@echo "removing $(BIN)..."@$(RM) $(BIN) $(OBJ)@echo "Finish"


http://www.ppmy.cn/news/1542226.html

相关文章

2024MathorCup大数据竞赛 B题基本思路

AB两题的难度分析 赛道A&#xff1a;台风的分类与预测 赛道A要求参赛者利用大数据分析方法解决台风分类与预测的问题。具体任务包括分析台风特征参数&#xff08;强度、等级、风速等&#xff09;与气温、气压、季风的关系&#xff0c;建立分类模型&#xff0c;并进行台风路径…

[项目详解][boost搜索引擎#1] 概述 | 去标签 | 数据清洗 | scp

目录 一、前言 二、项目的相关背景 三、搜索引擎的宏观原理 四、搜索引擎技术栈和项目环境 五、正排索引 VS 倒排索引--原理 正排索引 分词 倒排索引 六、编写数据去除标签和数据清洗模块 Parser 1.数据准备 parser 编码 1.枚举文件 EnumFile 2.去标签ParseHtml(…

入侵检测算法平台部署LiteAIServer视频智能分析平台行人入侵检测算法

在当今科技日新月异的时代&#xff0c;行人入侵检测技术作为安全防护的重要组成部分&#xff0c;正经历着前所未有的发展。入侵检测算法平台部署LiteAIServer作为这一领域的佼佼者&#xff0c;凭借其卓越的技术实力与广泛的应用价值&#xff0c;正逐步成为守护公共安全的新利器…

Bitcoin全节点搭建

1. wget https://bitcoincore.org/bin/bitcoin-core-0.20.1/bitcoin-0.20.1-x86_64-linux-gnu.tar.gz 2.tar -xzvf bitcoin-0.20.1-x86_64-linux-gnu.tar.gz mv bitcoin-0.20.1 bitcoin 3.创建配置文件&#xff08;bitcoin.conf&#xff09; mkdir -p /btc_data mkdir ~/.b…

linux中myshell的实现

目录 引言 全局信息 核心代码 核心函数 引言 随着计算机技术的飞速发展&#xff0c;操作系统在人们日常工作和生活中扮演着越来越重要的角色。Linux作为一款开源、自由且功能强大的操作系统&#xff0c;已经成为了众多服务器和开发者的首选平台。Shell作为Linux系统的用户界…

线程安全-同步与互斥/死锁

目录 前言 一、线程安全 1.互斥 2、死锁 3、同步 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 临界资源—同时只能被一个线程/进程进行安全访问的资源&#xff0c;如共享内存、文件、硬件设备、全局变量等 提示&#xff1a;以下是本篇文章正文内…

jmeter学习(6)逻辑控制器-循环

循环执行 1、循环读取csv文件的值 2、foreach 读取变量&#xff0c;变量数字后缀有序递增&#xff0c;通过counter实现 ${__V(typeId${typeIdNum})} beansell断言 String typeIdNum vars.get("typeIdNum"); String response prev.getResponseDataAsString(); …

verilog实现一个5bit序列检测器

以下是用 Verilog 实现一个 5bit 序列检测器的代码&#xff1a; module five_bit_sequence_detector(input clk,input reset,input [4:0] in,output reg detected );// 定义状态参数localparam IDLE 4b0000;localparam STATE1 4b0001;localparam STATE2 4b0010;localparam …