makefile笔记
makefile
在 Makefile 中,预定义的变量(也称为内置变量)提供了对构建过程中的默认值和特殊值的访问。这些变量通常由 Make 自动设置,并且可以覆盖它们以改变 Make 的行为。下面是 Make 环境中常见的几个内置变量及其用途:
-
$@目标文件名(依赖关系中的最后一个文件)。在规则的命令中,用$@表示当前目标的名字。 -
$^所有的依赖文件名列表,没有重复,并且排除了隐含目标。 -
$<第一个依赖文件的名字(主依赖项)。 -
$*用于匹配模式(Pattern)中的通配符部分。通常用于从目标文件名中提取出特定的部分,如不包含扩展名的文件名部分。 -
$?所有比目标更新的依赖文件名列表,只包括那些比目标新的依赖文件。 -
$>所有比依赖文件新的目标文件名列表。
除了这些特殊符号之外,还有一些预定义的变量代表了不同的路径和环境信息:
$AR- 归档命令(用于创建和修改静态库文件)。$AS- 汇编程序命令。$CC- C 编译器命令。$CXX- C++ 编译器命令。$CPP- C 预处理器命令。$RANLIB- 更新库索引文件的命令。$LD- 链接程序命令。$LDFLAGS- 传递给链接器的默认选项。$CFLAGS- 默认的 C 编译选项。$CXXFLAGS- 默认的 C++ 编译选项。$CPPFLAGS- 默认的预处理选项。
此外,还有一些变量提供了有关当前 Makefile 文件的信息:
$MAKEFILE_LIST- 包含当前所有被包含的 Makefile 名称的列表。$MAKEFILE- 当前正在执行的 Makefile 的名字。$MAKEFILES- 用空格分隔的所有 Makefile 名字列表。
最后,有一些变量涉及到文件名路径:
$CURDIR- 当前目录。$VPATH- 虚拟路径,它告诉 Make 到哪里去找源文件。
了解并正确使用这些内置变量可以使 Makefile 更加灵活和强大。当然,用户也可以定义自己的变量,并且可以覆盖这些预定义的变量来改变默认的行为。
MAKE 表示命令是什么
MAKECMDGOALS表示参数是什么
.PHONY:allall:@echo "MAKE = $(MAKE)"@echo "MAKECMDGOALS = $(MAKECMDGOALS)"
输出结果如下:
# make all
MAKE = make
MAKECMDGOALS = all
.PHONY是一个特殊的伪目标,在 Makefile 中使用,主要用于指定一个或多个“伪目标”(phony targets)。作用是明确告诉 make,其后列出的目标名不是文件名,即使文件系统中存在同名的文件,make 也不应该认为它们已经“存在”或“最新”。这样,当你执行 make 时,make 总是会执行该伪目标对应的命令,而不会因为它在文件系统中找到了一个同名的文件就跳过执行。
@echo中的@可以使make不打印当前执行的命令。
在 Makefile 中 $$ 具有特殊的意思,因此,如果想采用 echo 输出 $ ,则必需用两个连着的 $$ 。还有就是,$@ 对于 Shell 也有特殊的意思,我们需要在 $$@ 之前再加一个脱字符 \。
.PHONY:allall:first second third@echo "\$$@=$@"@echo "$$^=$^"@echo "$$<=$<"first second third:
执行结果如下:
# make
$@=all
$^=first second third
$<=first
变量的类别
=符号定义的变量,称之为递归扩展变量,会进行递归扫描
上面这种不能对变量自己赋值,会陷入死循环。如
a=$(a) b这种
:=符号定义的变量,称之为简单扩展变量,只会进行一次扫描和替换
?=称之为条件赋值,当变量以前没有定义时,就定义它并将右边的值赋给它;如果一定定义了就不再改变它的值
看下面的例子
.PHONY:allx=foo
y=$(x) b
x=laterxx:=foo
yy:=$(xx) b
xx:=later
foo=x
foo?=ybar?=yall:@echo "x = $(y), xx = $(yy)"@echo "foo = $(foo), bar = $(bar)"
输出结果如下:
# make
x = later b, xx = foo b
foo = x, bar = y#也可以在命令行上对变量赋值
# make bar=x
x = later b, xx = foo b
foo = x, bar = x#变量也可以来自系统的环境变量
# export bar=aa
# make
x = later b, xx = foo b
foo = x, bar = aa
高级变量引用功能
下面示例了Makefile的变量引用的一种高级功能
在赋值的同时完成后缀替换操作
.PHONY:allfoo = a.o b.o c.o
bar := $(foo:.o=.c)all:@echo "bar = $(bar)"
输出结果如下:
# make
bar = a.c b.c c.c
overrider指令
前面的例子看到参数可以通过命令行和环境变量赋值,如果不想Makefile中定义的变量被命令行或者环境变量覆盖掉,就可以使用override指令
.PHONY:alloverride foo := xall:@echo "foo = $(foo)"
输出结果如下
# make foo=b
foo = x
# export foo=c
# make
foo = x
模式
Makefile中经常存在多个规则用于构建目标文件。如果对于每一个目标文件都要写一个不同的规则来描述就太繁琐了。Makefile中的模式就是用来解决这种问题的。
看下面的例子
main.c
extern void foo();int main(){foo();return 0;
}
foo.c
#include <stdio.h>void foo(){printf("This is foo (). \n");}
Makefile
.PHONY:cleanCC = gcc
RM = rmEXE = simple
OBJS = main.o foo.o$(EXE): $(OBJS)$(CC) -o $@ $^%.o:%.c$(CC) -o $@ -c $^clean:$(RM) $(EXE) $(OBJS)
上面的例子我们%.o:%.c,就是一个模式规则。它匹配所有.c文件并指定如何构建对应的.o文件。会编译出main.o和foo.o。这里的%相当于通配符。注意,这里的通配符是%,而不是*。
函数
函数常常用来简化项目的Makefile
看下面的例子
.PHONY:cleanCC = gcc
RM = rmEXE = simpleSRCS = $(wildcard *.c)
OBJS = $(patsubst %.c,%.o,$(SRCS))$(EXE):$(OBJS)$(CC) -o $@ $^%.o:%.c$(CC) -o $@ -c $^clean:$(RM) $(EXE) $(OBJS)
wildcard是通配符函数, 通过它可以过滤出我们需要的文件,这里的通配符是*,其形式是$(wildcard pattern)
查找当前目录下所有.c文件,并将这些文件的名称赋值给变量SRCS。
patsubst函数是用来进行字符串替换,其形式是$(patsubst pattern, replacement, text),这里的通配符是%。上面的例子中将SRCS变量中所有.c文件的后缀替换为.o,并将结果赋值给变量OBJS
addprefix函数是用来在给字符串中的每个子串前加上一个前缀,其形式是
$(addprefix prefix, names...)
看下面的例子
.PHONY:allwithout_dir=fooc bar.c main.o
with_dir:=$(addprefix objs/,$(without_dir))all:@echo $(with_dir)
执行结果如下:
# make
objs/fooc objs/bar.c objs/main.o
filter函数用于从一个字符串中,根据模式得到满足模式的字符串,其形式是:
$(filter pattern..., text)
看下面的例子
.PHONY:allsources=foo.c bar.c baz.s ugh.hs:=$(filter %.c %.s, $(sources))all:@echo $(s)
执行结果如下:
# make
foo.c bar.c baz.s
filter-out函数用于从一个字符串中根据模式过滤掉一部分字符串,其形式是
$(filter-out pattern..., text)
看下面例子
.PHONY:allobjects=main1.o foo.o main2.o bar.o
result=$(filter-out main%.o,$(objects))all:@echo $(result)
执行结果如下:
# make
foo.o bar.o
strip函数用于去除变量中多余的空格,其形式是:
$(strip string)
看下面例子
.PHONY:alloriginal=foo.c bar.c
stripped:=$(strip $(original))all:@echo "original = $(original)"@echo "stripped = $(stripped)"
执行结果如下:
# make
original = foo.c bar.c
stripped = foo.c bar.c
相关文章:
makefile笔记
makefile 在 Makefile 中,预定义的变量(也称为内置变量)提供了对构建过程中的默认值和特殊值的访问。这些变量通常由 Make 自动设置,并且可以覆盖它们以改变 Make 的行为。下面是 Make 环境中常见的几个内置变量及其用途…...
Rewar Model的输出(不包含训练)
这里写自定义目录标题 介绍模型推理的输出过程方案原始Token输出RM输出(回归任务) 介绍 奖励函数模型 (Reward Model) 是人工智能 (AI) 中的一种方法,模型因其对给定提示的响应而获得奖励或分数。现在的文章清一色的讲解RM的训练,…...
Python调用API翻译Excel中的英语句子并回填数据
一、问题描述 最近遇到一个把Excel表中两列单元格中的文本读取,然后翻译,再重新回填到单元格中的案例。大约有700多行,1400多个句子,一个个手动复制粘贴要花费不少时间,而且极易出错。这时,我们就可以请出…...
SQL面试题——抖音SQL面试题 最大在线用户数
最大在线用户数 下面的数据记录了一个直播平台上用户进入平台和离开平台的情况 +---+-------------------+-----+ | id| etime| type| +---+-------------------+-----+ | 1|2021-06-10 10:00:00|enter| | 1|2021-06-10 19:00:00|leave| | 2|2021-06-10 11:0…...
前端知识点---Window对象(javascript)了解
Window对象 在JavaScript中,当你在非严格模式下的全局作用域中使用this时,它会引用全局对象。在浏览器环境中,这个全局对象就是Window。 01什么是 Window 对象? Window 是浏览器提供的一个全局对象,它代表了浏览器的…...
llama factory lora 微调 qwen2.5 7B Instruct模型
项目背景 甲方提供一台三卡4080显卡 需要进行qwen2.5 7b Instruct模型进行微调。以下为整体设计。 要使用 LLaMA-Factory 对 Qwen2.5 7B Instruct模型 进行 LoRA(Low-Rank Adapters)微调,流程与之前提到的 Qwen2 7B Instruct 模型类似。LoRA …...
类和对象——拷贝构造函数,赋值运算符重载(C++)
1.拷⻉构造函数 如果⼀个构造函数的第⼀个参数是自身类类型的引用,且任何额外的参数都有默认值,则此构造函数也叫做拷贝构造函数,也就是说拷贝构造是⼀个特殊的构造函数。 // 拷贝构造函数//d2(d1) Date(const Date& d) {_year d._yea…...
Android 关于使用videocompressor库压缩没有声音和异常的问题
原库地址 https://gitcode.com/gh_mirrors/vi/VideoCompressor/overview 这个库用起来比较方便,使用Android原生的MediaCodecmp4parser的方式进行压缩,不用接入so库也不用适配cpu 问题 接口库后你会发现过时了,所以你一阵捣鼓后你发现压缩…...
LeetCode-215.数组中的第K个最大元素
. - 力扣(LeetCode)给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问…...
『OpenCV-Python』视频的读取和保存
点赞 + 关注 + 收藏 = 学会了 推荐关注 《OpenCV-Python专栏》 上一讲介绍了 OpenCV 的读取图片的方法,这一讲简单聊聊 OpenCV 读取和保存视频。 视频的来源主要有2种,一种是本地视频文件,另一种是实时视频流,比如手机和电脑的摄像头。 要读取这两种视频的方法都是一样的…...
什么是Spring Boot Actuator
Spring Boot Actuator是一个用于监控和管理Spring Boot应用的框架,它提供了生产级别的功能,如健康检查、审计、指标收集、HTTP跟踪等。以下是对Spring Boot Actuator的详细介绍: 一、主要功能和特点 监控和管理: 提供多种内置端点…...
计算机网络:运输层 —— 运输层端口号
文章目录 运输层端口号的分类端口号与应用程序的关联应用举例发送方的复用和接收方的分用 运输层端口号的分类 端口号只具有本地意义,即端口号只是为了标识本计算机网络协议栈应用层中的各应用进程。在因特网中不同计算机中的相同端口号是没有关系的,即…...
linux下编译安装memcached
一、安装依赖库 Memcached依赖于一些系统库,在大多数Linux发行版中,需要安装libevent库。 Debian/Ubuntu系统 使用以下命令安装依赖库: sudo apt -y update sudo apt -y install libevent - devCentOS/RHEL系统 可以通过以下命令安装&am…...
最短路径生成树的数量-黑暗城堡
信息学奥赛一本通T1486-黑暗城堡 时间限制: 2s 内存限制: 192MB 提交: 18 解决: 9 题目描述 知道黑暗城堡有 N 个房间,M 条可以制造的双向通道,以及每条通道的长度。 城堡是树形的并且满足下面的条件: 设 Di为如果所有的通道都被修建…...
将已有的MySQL8.0单机架构变成主从复制架构
过程: 把数据库做一个完全备份, 恢复到从节点上, 恢复后从备份的那个点开始往后复制,从而保证后续数据的一致性。 步骤: 修改 master 主节点 的配置( server-id log-bin )master 主节点 完全备份( mysqldump )master 主节点 创建…...
JSON.stringify的应用说明
前言 JSON.stringify() 方法将 JavaScript 对象转换为字符串,在日常开发中较常用,但JSON.stringify其实有三个参数,后两个参数,使用较少,今天来介绍一下后两个参数的使用场景和示例。 语法及参数说明 JSON.stringify()…...
pyflink datastream数据流ds经过一系列转换后转为table,t_env.from_data_stream(ds)
在 pyflink 处理数据流过程中,有时候需要将data_stream转为table,下面是正确的方式,即每一个算子(map,reduce, window)操作之后需要指定输出数据类型。 from pyflink.common.typeinfo import Types from pyflink.datastream import StreamEx…...
vxe-grid table 校验指定行单元格的字段,只校验某个列的字段
Vxe UI vue vxe-table 中校验表格行是非常简单的,只需要配置好校验规则,然后调用 validate 方法就可以自动完成校验,但是由于项目淡色特殊需求,在某个单元格的值修改后需要对另一个列的值就行校验,这个时候又不需要全部…...
【Java多线程】单例模式(饿汉模式和懒汉模式)
目录 单例模式的定义: 饿汉式--单例模式 定义: 案例: 优缺点: 懒汉式--单例模式: 定义: 1)懒汉式单例模式(非线程安全) 2)线程安全的懒汉式单例模…...
python 异步编程之协程
最近在学习python的异步编程,这里就简单记录一下,免得日后忘记。 首先,python异步实现大概有三种方式,多进程,多线程和协程;多线程和多进程就不用多说了,基本上每种语言都会有多进行和多线程的…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
