15-makefile
一、Makefile的概述
1.认识make
- make 是一个命令,是个可执行程序,用来解析 Makefile 文件的命令;
- linux 环境下,这个命令存放在 /usr/bin/ 目录下;
- 当用户输入 make 指令时,系统会自动寻找
makefile、Makefile、GNUmakefile中任何一个,根据该文件中的指令编译工程。
2.什么是makefile
- makefile 是一个编译指令的脚本,里面记录了一条条编译指令,用于描述程序的编译规则;
- Makefile 文件里面的编译指令是根据我们自己写的程序,编写的编译规则。
3.makeflie与gcc的对比
-
用 gcc 编译的时候,我们要在后面跟上要编译的文件名,如:
gcc main.c func.c文件量和代码量较少的时候,用这种方式编译还比较方便,但如果整体项目很多,文件很多的时候,编译起来就比较困难,而且还容易漏掉一些文件。没人能保证自己的代码一次运行成功,会反复编译,调试,那每次调试都需要输入很长的 gcc 命令。遇到后期追加功能的时候,时间长了,也忘记项目用到了哪些文件了,对后期工作也会造成困扰;
-
而在 makeflie 里面提前写好了编译指令,只是在编写 makefile 文件的时候需要花费时间,但后面重复编译每次只需要 make 指令调用编译就行了,简化了编译过程。同时后期即使追加功能,以前的编译的文件指令都保存在 makefile 文件里了,也不用担心忘记需要编译哪些文件;
-
gcc 编译很大项目的时候,编译时间会很长,如果对代码进行了修改再编译,即使没有修改代码的文件,也要一起重新编译一次,又得消耗很长的时间;
-
makefile 只会对修改过的代码文件重新编译,其它未修改的直接使用以前编译好的可执行文件,除了第一次编译需要花费较长时间外,后面编译都比较快。因此,make 不仅简化了编译步骤,还节省编译时间,提高编译效率。
二、makefile的语法规则
1.makefile语法规则
1.1语法
先创建一个 makefile 文件,在文件里面写命令:
目标:依赖文件列表命令列表 // 命令列表前有缩进
- gcc 编译
gcc main.c -o main
- 目标:通常是要产生的可执行文件名,如上面的 main;
- 依赖文件:是用来输入从而产生目标的文件,一个目标通常有一个或多个依赖文件,如上面的 main.c;
- 命令:make 执行的动作,一个规则可以含几个命令,有多个命令时,每个命令占一行,如上面的
gcc main.c -o main。
- 注意: makefile 文件里面写的是脚本,要严格遵守脚本的语法规则,有时候多一个少一个空格都可能造成错误。
1.2makefile编译演示
先创建 makefile 文件,在文件里写入如下命令:
main:main.c func.cgcc main.c func.c -o main
接着在 linux 终端输入make命令即可实现编译。
- 注意:上面只是演示 makefile 命令的语法,和真正的 makefile 实现的功能差远了。这里的 make 只会执行第一个目标的语句,如果下方还有其它语句不会执行。
1.3make命令格式
1.3.1自定义 makefile 文件名
make -f 自定义文件名
- 在终端输入 make 命令时默认在工作目录中寻找名为 GNUmakefile、makefile、Makefile 的文件作为 makefile 输入文件,但如果我们不按照上面的文件名命名,而是修改为自定义的文件名,那么就需要在 make 命令后面加上我们自定义的文件名,如:
make -f my_makefile
但一般不建议这样做。
1.3.2make后跟其它目标
前面说到,make 执行第一个目标的语句后,后面目标的语句就不会执行了,那要执行后面目标的语句,我们可以指定目标:
make 目标
- 例如:makefile
main:main.c func.cgcc main.c func.c -o main
clean:rm main.c
可以通过输入:终端输入make clean,来执行指定的语句。
1.3.3复杂版makefile
main:main.o fun.ogcc main.o fun.o -o main
main.o:main.cgcc -c main.c -o main.o
fun.o:fun.cgcc -c fun.c -o fun.o
clean:rm main *.o
- 说明:
- 当终端输入 make 命令时,会执行 makefile 文件里的第一条命令,但发现依赖的
main.o fun.o文件不存在,会执行下面的命令,先生成main.o fun.o再执行第一条的命令; *.o里面的 * 是通配符,这里表示所有以.o结尾的文件;clean:为假想目标,只有目标,没有依赖。
- 当终端输入 make 命令时,会执行 makefile 文件里的第一条命令,但发现依赖的
三、makefile的变量
makefile 变量类似于 C 语言中的宏,当 makefile 被 make 工具解析时,其中的变量会被展开。变量一般用于:保存文件名列表、保存文件目录列表、保存编译器名、保存编译参数、保存编译的输出等。
1.自定义变量
- 定义格式
变量名=变量值
-
说明
- 注意,等号两边没有空格,应该严格遵循脚本语言的语法编写;
- makefile 变量名可以以数字开头,区分大小写;
- 变量一般都在 makefile 的头部定义,几乎可在 makefile 的任何地方使用;
- 如果需要读取变量的值,需要在变量名前加上美元符号 , , ,(变量名)或${变量名};
- 自定义变量的作用,主要是为了方便切换不同编译方式,方便指定生成的可执行文件名等,如果一个字符在命令中出现多次,就可以通过变量来代替,如:
CC=gcc EXEC=main$(EXEC):main.o fun.o$(CC) main.o fun.o -o $(EXEC) main.o:main.c$(CC) -c main.c -o main.o fun.o:fun.c$(CC) -c fun.c -o fun.o clean:rm $(EXEC) *.o
2.系统环境变量
make 工具会拷贝系统的环境变量并将其设置为 makefile 的变量,在 makefile 中可直接读取或修改拷贝后的变量,读取环境变量的方法和前面读取自定义变量的方法相同,如:
CC=gcc
EXEC=main$(EXEC):main.o fun.o$(CC) main.o fun.o -o $(EXEC)
main.o:main.c$(CC) -c main.c -o main.o
fun.o:fun.c$(CC) -c fun.c -o fun.o
clean:rm $(EXEC) *.oecho $(PWD) // PWD 是一个环境变量
- 说明:
- echo 相当于C语言里的 printf,将内容输出到终端;
- 我们除了可以使用系统的环境变量,还可以自己导出环境变量:
export NUM=100; - 自己导出的环境变量只在当前终端有效,不会影响系统的环境变量。
3.预定义环境变量
预定义环境变量即 makefile 定义好的环境变量。
- $@ 当前命令的目标名
- $< 当前命令依赖文件列表中的第一个文件
- $^ 当前命令依赖文件列表,带有除去重复文件的功能
- AR 归档维护程序的程序名,默认值为 ar
- ARFLAGS 归档维护程序的选项
- AS 汇编程序的名称,默认值为 as
- ASFLAGS 汇编程序的选项
- CC C 编译器的名称,默认值为 cc
- CFLAGS C 编译器的选项
- CPP C 预编译器的名称,默认值为$(CC) -E
- CPPFLAGS C 预编译的选项
- CXX C++编译器的名称,默认值为 g++
- CXXFLAGS C++编译器的选项
较常用的是前三个,对上面命令的升级版:
CC=gcc
EXEC=main$(EXEC):main.o fun.o$(CC) $^ -o $@
main.o:main.c$(CC) -c $< -o $@
fun.o:fun.c$(CC) -c $< -o $@
clean:rm $(EXEC) *.oecho $(PWD)
上面的代码可以发现,7、8行代码重复,因此可以合并,使用通配符 %:
CC=gcc
EXEC=main
OBJ=main.o fun.o // 将依赖文件通过自定义变量保存 $(EXEC):$(OBJ)$(CC) $^ -o $@
%.o:%.c$(CC) -c $< -o $@
clean:rm $(EXEC) $(OBJ)echo $(PWD)
相关文章:
15-makefile
一、Makefile的概述 1.认识make make 是一个命令,是个可执行程序,用来解析 Makefile 文件的命令;linux 环境下,这个命令存放在 /usr/bin/ 目录下;当用户输入 make 指令时,系统会自动寻找 makefile、Makef…...
yii2 手动添加 phpoffice\phpexcel
1.下载地址:https://github.com/PHPOffice/PHPExcel 2.解压并修改文件名为phpexcel 在yii项目的vendor目录下创建一个文件夹命名为phpoffice 把phpexcel目录放到phpoffic文件夹下 查看vendor\phpoffice\phpexcel目录下会看到这些文件 3.到vendor\composer目录下…...
使用 AI 辅助开发一个开源 IP 信息查询工具:一
本文将分享如何借助当下流行的 AI 工具,一步步完成一个开源项目的开发。 写在前面 在写代码时,总是会遇到一些有趣的机缘巧合。前几天,我在翻看自己之前的开源项目时,又看到了 DDNS 相关的讨论。虽然在 2021 年我写过两篇相对详细的教程&am…...
HNUST-数据分析技术课堂实验
1.要求 1,从下列第一、二、三组实验中各至少选取一个算法进行实验,选修组实验不作强制要求;2,实验过程不限,目标在于锻炼算法实现过程,即可采用C、C、Java、Python(建议)等任意语言编…...
P3456 [POI2007] GRZ-Ridges and Valleys BFS-连通块思想
题目描述 Byteasar loves trekking in the hills. During the hikes he explores all the ridges and valleys in vicinity. Therefore, in order to plan the journey and know how long it will last, he must know the number of ridgesand valleys in the area he is goi…...
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
WhisperKit: Android 端测试 Whisper 1.环境需要2.环境构建(1)克隆项目:(2)工具检查(make setup):(3)下载模型(make download-models)(4)Docker中构建环境(ma…...
Clickhouse(Centos)
地址信息 官网地址:Fast Open-Source OLAP DBMS - ClickHouse 下载地址:packages.clickhouse.com/rpm/stable/ 1.clickhouse-client-23.1.3.5.x86_64.rpm 2.clickhouse-common-static-23.1.3.5.x86_64.rpm 3.clickhouse-common-static-dbg-23.1.3.5.x86_…...
Yolo11改进策略:Block改进|使用FastVit的RepMixerBlock改进Yolo11,重参数重构助力Yolo11涨点(全网首发)
文章目录 摘要FastViT:一种使用结构重新参数化的快速混合视觉变换器1、简介2、相关工作3、体系结构3.1、概述3.2、FastViT3.2.1、重新参数化跳过连接3.2.2、线性训练时间过参数化3.2.3、大核卷积4、实验4.1、图像分类4.2、鲁棒性评价4.3、3D Hand网格估计4.4、语义分割和目标检…...
微信小程序-基于Vant Weapp UI 组件库的Area 省市区选择
Area 省市区选择,省市区选择组件通常与 弹出层 组件配合使用。 areaList 格式 areaList 为对象结构,包含 province_list、city_list、county_list 三个 key。 每项以地区码作为 key,省市区名字作为 value。地区码为 6 位数字,前两…...
NIO(New IO)和BIO(Blocking IO)的区别
Java中的NIO(New IO)和BIO(Blocking IO)的区别及NIO的核心组件 Java中的NIO(New IO)和BIO(Blocking IO)是两种不同的网络通信模型,各自具有独特的特性和适用场景。下面将…...
ROS1入门教程6:复杂行为处理
一、新建项目 # 创建工作空间 mkdir -p demo6/src && cd demo6# 创建功能包 catkin_create_pkg demo roscpp rosmsg actionlib_msgs message_generation tf二、创建行为 # 创建行为文件夹 mkdir action && cd action# 创建行为文件 vim Move.action# 定义行为…...
碰撞检测算法之闵可夫斯基差集法(Minkowski Difference)
在游戏开发和机器人路径规划乃至于现在比较火的自动驾驶中,我们常常需要确定两个物体是否发生碰撞,有一种通过闵可夫斯基差集法求是否相交的算法,下面将介绍一下 闵可夫斯基差集法的优势 闵可夫斯基差集法优势: 可以处理复杂的…...
【唐叔学算法】第18天:解密选择排序的双重魅力-直接选择排序与堆排序的Java实现及性能剖析
引言 在数据排序的世界里,选择排序是一类简单而直观的算法,它通过不断选取未排序部分中的最小(或最大)元素来逐步构建有序序列。今天,我们将深入探讨两种基于选择思想的排序方法——直接选择排序和堆排序,…...
2008-2020年各省技术服务水平相关指标数据
2008-2020年各省技术服务水平相关指标数据 1.时间:2008-2020年 2.指标:行政区划代码、地区、年份、信息传输、软件和信息技术服务业城镇单位就业人员(万人)、软件业务收入(万元)、高技术产品出口额占商品出口额比重(%) 3.范围&…...
机器学习DAY4续:梯度提升与 XGBoost (完)
本文将通过 XGBoost 框架来实现回归、分类和排序任务,帮助理解和掌握使用 XGBoost 解决实际问题的能力。我们将从基本的数据处理开始,逐步深入到模型训练、评估以及预测。最后,将模型进行保存和加载训练好的模型。 知识点 回归任务分类任务…...
ML-Agents:训练配置文件(一)
注:本文章为官方文档翻译,如有侵权行为请联系作者删除 Training Configuration File - Unity ML-Agents Toolkit–原文链接 常见训练器配置 关于训练,您需要做出的首要决定之一是使用哪种训练器:PPO、SAC 还是 POCA。有些训练配置…...
【物联网技术与应用】 实验13:雨滴传感器实验
实验13 雨滴传感器实验 【实验介绍】 雨滴传感器或雨滴检测传感器用于检测是否下雨以及降雨。广泛应用于汽车的雨刷系统、智能照明系统和天窗系统。 【实验组件】 ● Arduino Uno主板* 1 ● USB数据线*1 ● 雨滴传感器* 1 ● 雨滴传感器调理板* 1 ● 面包板*1 ● 9V方型…...
帝国cms电脑pc站url跳转到手机站url的方法
本文讲解一下帝国cms电脑网站跳转到手机动态网站和手机静态网站的方法,笔者以古诗词网 www.gushichi.com为例,为大家介绍操作步骤。方法一:帝国pc站跳转到手机静态站 1、假设我们有帝国cms 电脑网站www.XXX.com,手机网站m.XXX.com …...
Django models中的增删改查与MySQL SQL的对应关系
在 Django 中,models 提供了一种高层次的抽象来与数据库进行交互,使得开发者可以使用 Python 代码而非直接编写 SQL 来执行增删改查(CRUD)操作。下面将详细介绍 Django 的 ORM(对象关系映射)操作如何对应到…...
双指针——快乐数
一.题目描述 202. 快乐数 - 力扣(LeetCode) 二.题目解析 我们要判断一个数是不是快乐数要通过它的三个性质来进行判断。这个数会一直变化,由它的各个位的平方和重新构成这个数。如果这个数在变化的过程中变成了1,那么就是快乐数…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践
在电商行业蓬勃发展的当下,多平台运营已成为众多商家的必然选择。然而,不同电商平台在商品数据接口方面存在差异,导致商家在跨平台运营时面临诸多挑战,如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...
GAN模式奔溃的探讨论文综述(一)
简介 简介:今天带来一篇关于GAN的,对于模式奔溃的一个探讨的一个问题,帮助大家更好的解决训练中遇到的一个难题。 论文题目:An in-depth review and analysis of mode collapse in GAN 期刊:Machine Learning 链接:...
Netty自定义协议解析
目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…...
初探用uniapp写微信小程序遇到的问题及解决(vue3+ts)
零、关于开发思路 (一)拿到工作任务,先理清楚需求 1.逻辑部分 不放过原型里说的每一句话,有疑惑的部分该问产品/测试/之前的开发就问 2.页面部分(含国际化) 整体看过需要开发页面的原型后,分类一下哪些组件/样式可以复用,直接提取出来使用 (时间充分的前提下,不…...
