Linux中makefile

news2024/10/5 15:35:50

 

第一个版本的makefile

Makefile的依赖是从上至下的,换句话说就是目标文件是第一句里的目标如果不满足执行依赖,就会继续向下执行如果满足了生成目标的依赖,就不会再继续向下执行了

Make会自动寻找依赖条件所用到的文件,

 其中,我们可以在中makefile文件中一次执行多个文件,执行命令是make,文件名可以是makefile或是Makefile,必须是这个名字,因为make与之匹配,

在其中我们可以

Makefile是一个脚本文件,该文件存放的是shell命令,既然是脚本文件,就要遵守makefile制定的规则(显示规则)。所以最开始的makefile可以是这样的

前面的hello是所需生成的目标文件,后面的hello.c是生成目标文件所需的依赖文件, 

 

为了将编译的整个过程体现出来,Makefile中的内容可以如下

执行Make指令之后的文件如下 

 

但是hello.i hello.s这些文件都是我们不需要的,所以不需要这么多步骤,hello依赖于hello.o,hello.o依赖于hello.c。所以改写makefile的内容

 

执行Make指令之后的文件如下所示

 

 以上是对单个文件进行编写的makefile,如果是多文件编程的话,应该怎么编写makefile文件?假设文件有add.c mul.c div.c main.c四个文件

Main.c 

 Add.c

Mul.c 

div.c

 对于这四个文件,makefile文件中可以这样写

 

 执行make指令后是这样的

但是这样的makefile是存在问题的,当我修改其中的一个文件后,其他三个文件就必须跟着一起重新编译,效率太低。比如改写add.c文件

 

 

其他三个文件也一起被编译了一遍。

总共有四个文件,需要生成main可执行文件,main依赖于add.o、mul.o、div.o,这三个文件又分别依赖于各自的.c文件,所以makefile可以改写成这样

执行make指令后

 

 此时去修改其中任一个文件,其他文件不会被重新编译,比如修改add.c

修改完之后再重新make一下,发现其他文件并没有被重新编译,只执行了 编译add.c和链接.o文件这两个动作 

为什么会仅执行这两个动作呢?

Makefile的检测原理:

文件有一个属性叫做“修改时间”,当文件被修改后,这个属性就会发生改变。Make就是通过检测这个属性判断哪些文件有没有被修改过。

如果出现目标文件的“修改时间”比依赖文件的“修改时间“更早的话,比如 16:40 早于 16:41。这样的话,make就会重新执行这条规则(重新编译);

Add.o依赖于add.c。add.c 是依赖文件,add.o是目标文件,add.c一被修改,时间就比add.o更晚。所以gcc -c add.c -o add.o 这条规则会重新被执行。一执行后,add.o的时间就比main的时间更晚,所以gcc main.o add.o mul.o div.o 这条规则也会被执行。

关于makefile中的变量

变量的定义:

变量名 = 目标名 等价于 替换功能

变量的使用:

$(变量名)

关于makefile指定最终生成目标问题

Makefile默认将第一条目标视作最终目标,一旦最终目标生成后,其他指令不会继续执行,当将main: add.o mul.o div.o 移到最后时

再去执行make指令,仅仅会生成一个main.o文件,其他文件不会被生成。 

再将mul.o:mul.c放在第一条目标验证一下 

执行make指令后,只生成了mul.o

 

所以可以通过ALL:(最终目标)去指定一个最终目标,ALL需要放在第一条语句

执行完make指令后 

Makefile的两个函数和伪目标

src = $(wildcard *.c)

函数名:wildcard

函数功能:找到当前目录下所有后缀为.c的文件,将文件名组成列表,赋值给src

结果: src = add.c div.c mul.c main.c

obj = $(patsubst %.c,%.o, $(src))

函数名:patsubset

函数功能:将参数3($(src))中,包含参数1(%.c)的部分,替换成参数2

$(src)是一个列表,%会依次顺序遍历列表中的.c文件

结果:obj = add.o div.o mul.o main.o

根据这两个函数,所以makefile可以改写成这样

执行make指令后 

关于伪目标的问题

在上面的makefile文件中,每次都需要删除.o文件,很繁琐,所以在makefile文件中加了删除部分

 通过执行make clean指令可以删除多余的.o文件

rm前面的-,代表出错依然执行。

Make clean -n 是模拟删除动作,并未真正删除,看到模拟执行后,确定没有问题,执行删除动作

但是如果你在当前目录下去创建一个clean文件,当你执行make clean的时候系统就会认为你要执行clean文件,从而干扰原本的执行命令。 

此时可以在makefile文件中的伪目标clean前加上.PHONY:来指定伪目标从而去除干扰: 

此时再次执行make clean看一下效果: 

这时候就算在本文件下有clean文件也不会造成干扰。

在上面的makefile中,各个生成.o的指令还是很繁琐,应该怎么办?

关于makefile3个自动变量和模式规则的问题

3个自动变量

$@ :在规则命令中,表示规则中的目标

$^ :在规则命令中,表示所有的依赖条件 

$<:这个只能使用在规则命令中,表示规则中的第一个依赖条件。如果将该变量使用在模式规则中,它可以将依赖条件列表中的依赖依次取出,套用模式规则。

所以可以将makefile改写成这个样子,sub,add这些指令中使用$<和$^都能达到效果,但是为了模式规则,所以使用的$<

执行make指令后 

 

上面的makefile不能进行扩展,可扩展性不行。比如,要添加一个乘法函数,就需要在makefile里面增加乘法函数的部分。不科学,所以,模式规则就来了

%.o:%.c

gcc -c $< -o $@

修改makefile,如下

 

 执行make指令

 

 

此时再添加一个乘法函数,无须更改makefile。

扩展:

当文件中存在clean文件时,make失灵

添加一个伪代码 

再使用变量完善一下 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/757952.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uni-app的H5版本下载跨域问题

前端能正常访问图片&#xff0c;但无法下载 因为路径不经过业务代码&#xff0c;所以需要在nginx配置跨域 代码&#xff1a; add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods GET, POST, OPTIONS; add_header Access-Control-Allow-H…

【黑客】网络安全靠自学?你不要命了!

1️⃣网安现状 ❗本文面向所有 想要涉足网安领域 或 已经涉足但仍处在迷茫期 的伙伴&#xff0c;如果你月薪达到了3w&#xff0c;那么请你离开。 如果没有&#xff0c;希望你继续看下去&#xff0c;因为你人生的转折点将从这篇文章开始。 ✈️网络安全&#xff0c;一个近几年大…

路径规划算法:基于斑马优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于斑马优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于斑马优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法斑马…

Keil5新建51单片机demo工程模板

51单片机新建工程使用到的软件有keil5&#xff0c;首先安装好keil5软件&#xff0c;安装教程在:【Keil&#xff08;C51&#xff09;介绍、下载、安装、注册与2个补丁】Keil&#xff08;C51&#xff09;介绍、下载、安装与2个补丁_西晋的no1的博客-CSDN博客 一、新建一个空工程 …

【QT】——基础窗口类QMainWindow

目录 1.概念 2.菜单栏——QMenuBar 3.工具栏 添加QAction 工具栏属性设置 5.状态栏——QStatusBar 6 停靠窗口 属性设置 1.概念 QMainWindow 是标准基础窗口中结构最复杂的窗口&#xff0c;QMainWindow继承QWidget&#xff0c;他在QWidget的基础上提供了菜单栏&#…

网络编程 socket

目录 网络编程 套接字&#xff08;socket&#xff09;1. 认识端口号2. TCP协议3. UDP协议4. 网络字节序列5. 常见的套接字6. socket编程接口6.1 socket常见APIsocket函数recvfrom函数sendto函数read函数 从tcp socket中读取接收数据 6.2 sockaddr结构6.3 地址转换函数6.4 udp s…

input输入日期时间,自动格式化组件/工具

input输入日期时间&#xff0c;自动格式化组件/工具 组件/工具使用说明 只能输入日期时间&#xff0c;不能选择日期时间格式 yyyy-MM-dd HH:mm:ss基于VUE框架输入效果见下图 组件/工具解决的痛点 组件库日期时间组件&#xff0c;选日期时间很花时间 例如想快速得到 2021-1…

OJ练习第137题——有序链表转换二叉搜索树

有序链表转换二叉搜索树 力扣链接&#xff1a;109. 有序链表转换二叉搜索树 题目描述 给定一个单链表的头节点 head &#xff0c;其中的元素 按升序排序 &#xff0c;将其转换为高度平衡的二叉搜索树。 本题中&#xff0c;一个高度平衡二叉树是指一个二叉树每个节点 的左右…

[golang gin框架] 40.Gin商城项目-微服务实战之Captcha验证码微服务

本次内容需要 gin框架基础知识, golang微服务基础知识才能更好理解 一.Captcha验证码功能引入 在前面,讲解了微服务的架构等,这里,来讲解前面商城项目的 Captcha验证码 微服务 ,captcha验证码功能在前台,后端 都要用到 ,可以把它 抽离出来 ,做成微服务功能 编辑 编辑 这个验证码…

MySQL 第七天作业 nosql作业

作业一&#xff1a;string list hash结构中&#xff0c;每个至少完成5个命令&#xff0c;包含插入 修改 删除 查询&#xff0c;list 和hash还需要增加遍历的操作命令 1、 string类型数据的命令操作&#xff1a; &#xff08;1&#xff09; 设置键值&#xff1a; set key1 re…

C++基础与深度解析01——函数基本组成+函数传参的三种方法

0.前期准备 请安装Visual Studio 并学习基本的新建项目、新建CPP文件以及运行代码。 1.从Hello World 开始 1.1代码内容 函数功能&#xff1a;打印“Hello World” #include<iostream> int main() { std::cout << "Hello World" << std::endl…

学习babylon.js --- [1] 初次体验和安装

babylon.js是微软推出的Web3D库&#xff0c;本文写作时版本是6.x&#xff0c;官方介绍如下&#xff0c; 看这意思是6.x系列的版本大大提高了性能&#xff0c;并提供了很多新特性。其Github地址是https://github.com/BabylonJS/Babylon.js 本篇文章讲述使用babylon.js的初次体…

申请阿里云服务器并搭建公网可支持数据上传的HTTP服务器

1. 前言 拥有一台自己的云服务器可以做很多事情。阿里云服务器毫无疑问是国内最好的。 阿里云服务器可以用于各种互联网应用的搭建和运行&#xff0c;提供稳定、高性能的服务。 阿里云服务器的用途&#xff0c;包括但不限于以下几个方面&#xff1a; 网站托管&#xff1a;可以将…

常用adb命令整理

一、adb介绍 adb&#xff1a;Android Debug Bridge&#xff0c;Android 调试桥的缩写&#xff0c;adb 是一个 C/S 架构的命令行工具&#xff0c; 主要由 3 部分组成&#xff1a; 运行在 PC 端的 Client : 可以通过它对 Android 应用进行安装、卸载及调试运行在 PC 端的 Serv…

Python实现校园网自动连接

用过校园网的小伙伴可能深有体会&#xff0c;在连接上校园网之后&#xff0c;需要再进行一个用户认证&#xff0c;才算真正的连接成功。这就会带来一些问题&#xff0c;比如若在长时间内没有网络请求&#xff0c;用户认证就会失效&#xff0c;它会自动断开校园网&#xff0c;这…

Android 系统开发工具

Android 系统开发工具 1、SSH 服务与 Tabby Terminal1.1 配置 Ubuntu ssh 服务 2、Samba 服务器搭建3、Idegen Android Studio 查看源码3.1 修改android.iml文件 (可选) 4、AIdegen Android Studio 查看源码4.1 准备工作4.2 Android Studio 配置4.2.1 添加源码中的 jdk 和 sd…

两数之和

给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出和为目标值 target 的那两个整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。…

arcgis实现影像监督分类

1、打开ArcMap,右击空白处打开影像分类工具栏&#xff0c;如下&#xff1a; 2、打开影像&#xff0c;如下&#xff1a; 打开的影像由于未经处理&#xff0c;颜色看起来很昏暗&#xff0c;这时候可以拉伸一下。具体操作&#xff0c;右击图层选择属性&#xff0c;如下&#xff1a…

python使用websockets进行数据传输

背景说明&#xff1a; 最近在研究一个智能监控系统&#xff0c;后台通过rtsp读取摄像头视频流&#xff0c;使用yolov算法进行目标检测&#xff0c;然后将检测的视频帧通过字符串的方式抛转到前台html页面显示&#xff0c;需要用到前后台数据交互技术&#xff0c;查询资料发现w…

ShareX设置快捷键、自定义保存路径、取消上传等设置

让ShareX变成顺手的形状 设置篇ShareX设置快捷键ShareX设置自定义保存路径ShareX取消自动上传和打开OCR 使用篇OCR 设置篇 ShareX设置快捷键 ShareX设置自定义保存路径 ShareX取消自动上传和打开OCR 为什么取消上传功能&#xff1a;因为不需要自动把本地截图自动上传到远程服务…