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异步实现大概有三种方式,多进程,多线程和协程;多线程和多进程就不用多说了,基本上每种语言都会有多进行和多线程的…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
