12-Makefile_03(续)

news2025/1/13 7:59:58

使用变量

使用C自动编译成*.o的默认规则有个缺陷,由于没有显式地表示*.o依赖于.h头文件,假如修改了头文件的内容,那么*.o并不会更新,这是不可接受的。并且默认规则使用固定的“cc”进行编译,假如想使用ARM-GCC进行交叉编译,那么系统默认的“cc”会导致编译错误。要解决这些问题并且让Makefile变得更加通用,需要引入变量和分支进行处理。

基本语法

Makefile中的变量类似C语言的宏定义,在引用变量的地方使用变量值进行替换。

定义变量的方法:

  • “=”:延时赋值,该变量只有在调用的时候,才会被赋值
  • “:=”:直接赋值,与延时赋值相反,使用直接赋值的话,变量的值定义时就已经确定了
  • “?=”:若变量的值为空,则进行赋值,通常用于设置默认值
  • “+=”:追加赋值,可以往变量后面增加新的内容

主要介绍前两种:

A = a
B = $(A)
C = $(A)
A += b
.PHONY:check
check:
	echo "A:"$(A)
	echo "B:"$(B)
	echo "C:"$(C)	

在这里插入图片描述
通过-f选项指定执行Makefile文件,可以看见只有C是a。这是因为B采用的延时赋值,只有当调用时,才会进行赋值。当调用B时,A的值已经被修改为a b,因此B的变量值也就等于a b。

改造默认规则

使用变量修改默认规则

CC = gcc
CFLAGS = -I .
DEPS = hello_func.h

hello_main:hello_main.o hello_func.o
	$(CC) hello_main.o hello_func.o -o hello_main
# %为通配符,让所有.o文件依赖于对应的.c文件
%.o:%.c $(DEPS)
	$(CC) $< -c -o $@ $(CFLAGS)
.PHONY:clean
clean:
	rm -f *.o hello_main

上面的Makefile文件使用$(CC)替代了gcc,这样编写的Makefile非常容易更换不同的编译器,如要进行交叉编译,只要把开头的编译器名字修改掉即可

“%”是一个通配符,功能类似“*”,如”%.o”表示所有以”.o”结尾的文件。所以”%.o:%.c”在本例子中等价于”hello_main.o:hello_main.c”、“hello_func.o:hello_func.c”,即等价于o文件依赖于c文件的默认规则。不过这行代码后面的“$(DEPS)”表示它除了依赖c文件,还依赖于变量“$(DEPS)”表示的头文件,所以当头文件修改的话,o文件也会被重新编译。

特殊的变量”$@”,”$<”,可理解为Makefile文件保留的关键字,是系统保留的自动化变量,”$@”代表了目标文件,”$<”代表了第一个依赖文件。即”$@”表示”%.o”,”$<”表示”%.c”。

$(CC) $< -c -o $@ $(CFLAGS)
# 等价于:
gcc hello_main.c -c -o hello_main.o -I .
gcc hello_func.c -c -o hello_func.o -I .
改造链接规则

继续使用变量来修改生成最终目标文件的链接规则:

# 定义变量
TARGET = hello_main
CC = gcc
CFLAGS = -I .
DEPS = hello_func.h
OBJS = hello_main.o hello_func.o

# 目标文件
$(TARGET):$(OBJS)
	$(CC) $^ -o $@ $(CFLAGS)

# *.o文件的生成规则
%.o:%.c $(DEPS)
	$(CC) $< -c -o $@ $(CFLAGS)

# 伪目标
.PHONY:clean
clean:
	rm -f *.o hello_main
其他自动化变量
符号含义
$@匹配目标文件
$%与 $@ 类似,但 $% 仅匹配“库”类型的目标文件
$<依赖中的第一个目标文件
$^所有的依赖目标,如果依赖中有重复的,只保留一份
$+所有的依赖目标,即使依赖中有重复的也原样保留
$?所有比目标要新的依赖目标
使用分支
ifeq(arg1,arg2)
分支1
else
分支2
endif

分支会比较括号内的参数“arg1”和“arg2”的值是否相同,如果相同,则为真,执行分支 1 的内容,否则的话,执行分支 2 的内容,参数 arg1 和 arg2 可以是变量或者是常量。

使用分支切换GCC编译器的Makefile如下:

ARCH ?= x86
TARGET = hello_main
CFLAGS = -I .
DEPS = hello_func.h
OBJS = hello_main.o hello_func.o

# 根据输入的ARCH变量来选择编译器
ifeq ($(ARCH),x86)
CC = gcc
else
CC = arm-linux-gnueabihf-gcc
endif

$(TARGET):$(OBJS)
	$(CC) $^ -o $@ $(CFLAGS)

%.o:%.c $(DEPS)
	$(CC) $< -c -o $@ $(CFLAGS)

.PHONY:clean
clean:
	rm -f *.o hello_main

Makefile 主要是增加了 ARCH 变量用于选择目标平台,代码中使用“?=”给 ARCH 赋予默认值 x86。
在这里插入图片描述
以上示例使用交叉编译进行编译。

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

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

相关文章

Nacos原理简单介绍

注册中心原理 官网&#xff1a;Nacos 注册中心的设计原理 | Nacos nacos注册中心采用了 &#xff1a;pull &#xff08;客户端的轮询&#xff09;和push &#xff08;服务端主动push&#xff09;策略 客户端启动时会将当前服务的信息包含ip、端口号、服务名、集群名等信息封装…

树莓教育坚持特色引领,建设一流应用型影像培训

树莓教育&#xff0c;作为树莓集团旗下的子公司&#xff0c;自创立以来已经走过了十余个春秋。在这漫长的教育征程中&#xff0c;树莓教育始终坚守初心&#xff0c;秉持着七个坚持和十项行动的原则为数字影像产业的建设和发展做出了巨大的贡献。 七个坚持&#xff0c;是树莓教育…

【网络编程】Java网络编程中的基本概念及实现UDP、TCP客户端服务器程序(万字博文)

系列文章目录 【网络通信基础】网络中的常见基本概念 【网络编程】Java网络编程中的基本概念及实现UDP、TCP客户端服务器程序&#xff08;万字博文&#xff09; 【网络原理】UDP协议的报文结构 及 校验和字段的错误检测机制&#xff08;CRC算法、MD5算法&#xff09; 目录 …

大小端解释以及如何使用程序判断IDE的存储模式

今天让我们来了解一下大小端的概念吧 什么是大小端&#xff1f; 大端&#xff08;存储&#xff09;模式&#xff1a;指的是数据的低位保存在内存的高地址处&#xff0c;而数据的高位则保存在内存的低地址处。 小端&#xff08;存储&#xff09;模式&#xff1a;指的是数据的低位…

使用表格法插入公式和编号

如何将公式和编号优雅地插入到论文当中呢&#xff1f; 首先插入一个1行2列的表格 调整一下 输入公式方法一&#xff1a;感觉墨迹公式挺好用的&#xff0c;word自带的 输入公式方法二&#xff1a;图片转LATEX代码 这个方法更快 分享一个公式识别网站 图片识别得到LATEX代码&…

免费PNG素材网站推荐:设计效率倍增!

一、即时设计 新一代协同设计工具即时设计&#xff0c;内置丰富社区资源&#xff0c;可以在此获得设计前线的各类PNG图像&#xff0c;以及矢量图标&#xff0c;包括毛玻璃、3D混搭、全息投影、单色、平面化等&#xff0c;都是符合目前市场的主流风格。通过最近更新、作品、资源…

【ks爬虫软件】把快手评论API接口封装成GUI采集工具

用Python开发爬虫采集软件&#xff0c;可自动抓取快手评论数据&#xff0c;且包含二级评论。 快手的评论接口URL&#xff1a; # 请求地址 url https://www.kuaishou.com/graphql开发者模式分析过程&#xff1a; 进而封装成GUI界面软件&#xff0c;如下&#xff1a; 软件效…

【Linux】开关机命令和服务管理类命令

一般Linux是不会经常进行关机的,关机的正确流程是: sync->shutdown->reboot->poweroff sync: 将内存中的数据同步到硬盘中poweroff: 关闭系统,等同于shutdown -h nowreboot: 重启系统,等同于 shutdown -r nowshutdown[选项] [时间] shutdown命令常见用法: shutdown:…

[vite] ts写配置根目录别名

参考:配置 Vite | Vite 写对象的形式吧 import { defineConfig } from vite import vue from vitejs/plugin-vue import path from path// https://vitejs.dev/config/ export default defineConfig({plugins: [vue()],resolve: {alias: {"": path.resolve(__dirname…

电磁仿真--基本操作-CST-(2)

目录 1. 回顾基操 2. 操作流程 2.1 创建工程 2.2 修改单位 2.3 创建 Shape 2.4 使用拉伸 Extrude 2.5 修改形状 Modify Locally 2.6 导入材料 2.7 材料解释 2.8 材料分配 2.9 查看已分配的材料 2.10 设置频率、背景和边界 2.11 选择 Edge&#xff0c;设置端口 2.…

Linux-进程间通信:System V消息队列

目录 System V IPC概述标识符与IPC Key System V消息队列创建或打开一个消息队列发送消息接收消息控制消息队列1、IPC_STAT2、IPC_SET3、IPC_RMID 查看系统当前的消息队列代码示例 System V IPC&#xff08;Inter-Process Communication&#xff09;是一组用于在 Unix-like 操作…

五款最受欢迎的上网行为管理软件

五款最受欢迎的上网行为管理软件 员工上网看视频怎么办&#xff1f;员工偷偷刷抖音怎么办&#xff1f;员工天天上招聘网&#xff0c;是不是有离职打算&#xff1f; 解决上述困扰的最好办法是使用监控软件了解员工一言一行。以下是几款推荐的上网行为管理和监控软件&#xff1a;…

基于Linux系统命令行安装KingbaseES数据库

人大金仓通用性数据库&#xff08;Kingbase&#xff09;下载网址&#xff1a;人大金仓-成为世界卓越的数据库产品与服务提供商 选择“软件版本-数据库”&#xff0c;筛选条件Linux、完整版。找到需要的版本&#xff0c;点击下载。我下载的是KingbaseES_V008R006C008B0014_Lin6…

机器学习理论基础—神经网络算法公式学习

机器学习理论基础—神经网络公式学习 M-P神经元 M-P神经元&#xff08;一个用来模拟生物行为的数学模型&#xff09;&#xff1a;接收n个输入(通常是来自其他神经 元)&#xff0c;并给各个输入赋予权重计算加权和&#xff0c;然后和自身特有的阈值进行比较 (作减法&#xff0…

【大语言模型基础】Transformer模型Torch代码详解和训练实战

一、Transformer概述 Transformer是由谷歌在17年提出并应用于神经机器翻译的seq2seq模型&#xff0c;其结构完全通过自注意力机制完成对源语言序列和目标语言序列的全局依赖建模。 Transformer由编码器和解码器构成。下图展示了它的结构&#xff0c;其左侧和右侧分别对应着编…

奇妙的探索——偶然发现的bug

今天想在腾讯招聘官网找几个前端的岗位投一下&#xff0c;最近自己也在找工作&#xff0c;结果简历还没有投出去&#xff0c;就发现了腾旭招聘官网的3个前端bug。 1.有时候鼠标hover还没有滑倒下拉选框的菜单上&#xff0c;就消失了&#xff0c;消失的太快了&#xff0c;根本点…

方便快捷!使用Roboflow进行数据增强(附详细操作)

最近使用自定义数据集训练yolov8模型的时候突然发现一件很令人头疼的事情。那就是&#xff0c;数据集中图片太少了。于是想通过数据增强的方法扩大数据集。 通过查阅资料发现&#xff0c;大部分人都是用python中的imgaug库进行图像处理&#xff1b;这种方法最大的不便就是需要转…

【数据结构】stack queue —— 栈和队列

前言 这阵子一直在学数据结构&#xff0c;知识点消化地有点慢导致博客一直没写&#xff0c;现在总算是有时间歇下来补补前面落下的博客了。从现在起恢复周更&#xff0c;努努力一周两篇也不是梦……闲话少说&#xff0c;今天就让我们一起来认识栈和队列 1. 栈的介绍和使用 栈…

40-50W 1.5KVDC 隔离 宽电压输入 DC/DC 电源模块——TP40(50)DC 系列

TP40(50)DC系列电源模块额定输出功率为40-50W、应用于2:1、4&#xff1a;1电压输入范围 9V-18V、18V-36V、36V-75V、9V-36V、18V-75V的输入电压环境&#xff0c;输出电压精度可达1%&#xff0c;可广泛应用于通信、铁路、自动化以及仪器仪表等行业。

dremio支持设置

Dremio 支持提供可用于诊断目的的设置。这些设置通过 Dremio UI&#xff1a;设置>支持启用&#xff08;或禁用&#xff09; 使用 Client Tools 可以配置当用户查看数据集中的数据时&#xff0c;Dremio 项目的工具栏上显示哪些客户端应用程序按钮。用户可以通过单击相应的工具…