影响 Makefile 中变量值的方式

影响 Makefile 中变量值的方式

1,直接赋值

变量的赋值方式
Makefile 中变量的赋值方式影响着变量的覆盖和更新。主要有以下几种赋值方式:
简单赋值 (=): 变量在被赋值时展开,如果变量之前被赋值过,可以被后续的赋值覆盖。
递归赋值 (:=): 变量在被赋值时立即展开,之后的赋值不会影响已经赋值的变量。
条件赋值 (?= ): 只有在变量之前没有被赋值时,才会对变量进行赋值。
追加赋值 (+=): 将值追加到变量的当前值之后。


2,包含其他makefile文件

在 Makefile 中,变量的跨文件传递主要依赖于 Makefile 的包含机制和变量的赋值方式。
Makefile 允许一个文件包含另一个文件,这使得在多个文件之间共享变量成为可能。以下是一些关键点和规则,用于理解和实现 Makefile 变量的跨文件传递:
包含其他 Makefile
使用 include 指令可以将一个 Makefile 的内容包含到另一个 Makefile 中。例如:

include cpp_src.mk
-include cu_src.mk

则 cpp_src.mk 中定义的变量会包含进来。

注意事项
当使用 include 包含其他 Makefile 时,被包含的 Makefile 中的变量和规则就好像是直接写在主 Makefile 中一样。
如果在多个被包含的 Makefile 中定义了相同的变量,那么变量的最终值将取决于赋值方式和包含的顺序。
使用条件赋值可以避免在不同文件中对同一个变量的重复赋值。


3,导出为环境变量

可以在调用子 Makefile 前,将需要传递的变量导出为环境变量。在子 Makefile 中,这些环境变量就可以像普通的 Makefile 变量一样被访问。
例如:
 

export VAR_NAME=value
all:
    make -C subdir

4,通过命令行传递变量


另一种方法是在 make -C dir 命令中直接指定变量的值,这样在子 Makefile 中就可以访问这些变量了。

例如:
 

all:
    make -C subdir VAR_NAME="value"


5,使用 make 的 -e 选项


使用 -e 选项,可以让环境中的变量覆盖 Makefile 中的同名变量。
这意味着如果你在父 Makefile 中导出了一个环境变量,然后使用 -e 选项调用 make -C dir,子 Makefile 中的同名变量将会被环境变量的值覆盖。
例如:
 

export VAR_NAME=value
all:
    make -e -C subdir

注意
使用环境变量的方法可能会受到操作系统对环境变量长度和数量的限制。
通过命令行传递变量是显式的,容易理解和维护,但可能会使命令行变得很长。
使用 -e 选项可以方便地覆盖子 Makefile 中的变量,但可能会导致预期之外的行为,因为它会使所有的环境变量都能覆盖 Makefile 中的同名变量。

6,优先级


 6.1 命令行定义的变量(最高优先级)


 当你在命令行中直接为 make 命令指定变量时,这些变量的值具有最高优先级。例如:
           

 make -C subdir VAR="value"


 这里,VAR 的值在子 Makefile 的执行过程中将被设置为 "value",无论子 Makefile 内部如何定义 VAR。
 
 


 6.2 环境变量(受 -e 选项影响)


 默认情况下,Makefile 中定义的变量会覆盖同名的环境变量。
 但是,如果使用了 make 的 -e 选项,环境变量将具有更高的优先级,能够覆盖 Makefile 中的同名变量定义。
 这适用于从父 Makefile 传递到子 Makefile 的环境变量:

export VAR="value from environment"


如果在父 Makefile 中这样导出变量,并在调用子 Makefile 时使用 -e 选项,那么环境变量将覆盖子 Makefile 中的同名变量。


 6.3 子 Makefile 中的变量定义


 子 Makefile 中直接定义的变量(不考虑通过命令行或环境变量传递的情况)。这些定义根据赋值方式(=、:=、?=、+=)有不同的行为。
 
 


 6.4 父 Makefile 中通过 export 导出的变量


 父 Makefile 可以通过 export 关键字导出变量,使其成为环境变量,这些环境变量在子 Makefile 中可用,除非被命令行变量或 -e 选项影响的环境变量覆盖。
 


 6.5 包含的 Makefile 中的变量


 当一个 Makefile 使用 include 指令包含另一个 Makefile 时,被包含 Makefile 中的变量定义会影响到当前 Makefile。
 这种情况下,被包含 Makefile 中的变量定义相当于直接写在包含它的 Makefile 中。
 

 6.6 默认变量


Make 提供的默认变量(如 CC 默认为 cc)。如果在 Makefile 中没有显式定义这些变量,它们将使用默认值。

总结优先级
1. 命令行定义的变量(最高优先级)
2. 环境变量(受 -e 选项影响)
3. 子 Makefile 中的变量定义
4. 父 Makefile 中通过 export 导出的变量
5. 包含的 Makefile 中的变量
6. 默认变量


7, .EXPORT_ALL_VARIABLES


In Makefile, to ensure that all variables are automatically exported to child Makefiles or subprocesses,
you can use the `.EXPORT_ALL_VARIABLES` special variable.
This tells [make]  to export all variables to the environment of every shell command.
 It does not need to be assigned a value; its presence in the Makefile is sufficient.

8, 对 ?= 变量的影响方式

在 Makefile 中,`?=` 操作符用于条件赋值,即只有当变量之前未被定义(即未被赋值)时,才会对其进行赋值。这意味着,如果一个变量在子 Makefile 中使用 `?=` 被赋值,那么它只会在该变量在之前的环境中未被定义时接受这个赋值。

对于父 Makefile 和子 Makefile 的交互,以下是几种情况下父 Makefile 中的同名变量会改变子 Makefile 中变量的值:

8.1. 父 Makefile 中通过命令行传递变量

如果在调用子 Makefile 时,通过命令行传递了同名变量,那么这个变量的值会被传递给子 Makefile,即使子 Makefile 中使用了 `?=` 进行了条件赋值。命令行传递的变量具有最高优先级。

8.2. 父 Makefile 中导出变量

如果父 Makefile 中通过 `export` 明确导出了一个变量,那么这个变量会成为环境变量,子 Makefile 在执行时会继承这个环境变量。如果子 Makefile 中使用 `?=` 对同名变量进行了条件赋值,由于环境变量已经定义了该变量,子 Makefile 中的赋值将不会生效。

8.3. 使用 `.EXPORT_ALL_VARIABLES`

如果父 Makefile 中声明了 `.EXPORT_ALL_VARIABLES`,那么所有在父 Makefile 中定义的变量都会自动导出为环境变量。这意味着,如果子 Makefile 中使用 `?=` 对同名变量进行了条件赋值,这个赋值将不会生效,因为该变量已经通过父 Makefile 被定义了。

8.4 注意

- 如果子 Makefile 在使用 `?=` 赋值之前已经通过其他方式(如直接赋值或通过命令行参数)接收到了该变量的值,那么 `?=` 的赋值将不会生效,因为该变量已经被定义。
- `?=` 的赋值只有在变量之前未被定义时才会生效,这包括之前没有被赋值或者被赋予空值。

总的来说,父 Makefile 中的同名变量会通过命令行参数传递、环境变量(包括使用 `export` 或 `.EXPORT_ALL_VARIABLES`)影响子 Makefile 中使用 `?=` 定义的变量的值,前提是这些操作发生在子 Makefile 执行之前。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Qt之OpenGL】01创建OpenGL窗口

1.创建子类继承QOpenGLWidget 2.重写三个虚函数 /** 设置OpenGL的资源和状态,最先调用且调用一次* brief initializeGL*/ virtual void initializeGL() override; /** 设置OpenGL视口、投影等,当widget调整大小(或首次显示)时调用* brief resizeGL* param w* para…

请求接口报错:java.lang.IllegalStateException: argument type mismatch

目录 一、场景二、报错信息三、控制器四、接口调用五、原因六、解决 一、场景 1、调用后端接口报错 2、接口参数以Json方式传递 – 二、报错信息 java.lang.IllegalStateException: argument type mismatch Controller [com.xxx.huarunshouzheng.controller.MallControlle…

Ubuntu如何更换 PyTorch 版本

环境: Ubuntu22.04 WLS2 问题描述: Ubuntu如何更换 PyTorch 版本考虑安装一个为 CUDA 11.5 编译的 PyTorch 版本。如何安装旧版本 解决方案: 决定不升级CUDA版本,而是使用一个与CUDA 11.5兼容的PyTorch版本,您可…

75、堆-前K个高频元素

思路 这道题还是使用优先队列,是要大根堆,然后创建一个类,成员变量值和次数。大根堆基于次数排序。前k个就拿出前k的类的值即可。代码如下: class Solution {public int[] topKFrequent(int[] nums, int k) {if (nums null || …

解决: 0x803f7001 在运行Microsoft Windows 非核心版本的计算机上,运行“ slui.exe 0x2a 0x803f7001 “以显示错误文本,激活win10步骤流程。

一. 解决 0x803F7001在运行Microsoft Windows非核心版本的计算机错误 首先,按下winR打开"运行",输入 regedit 后回车,打开注册表。   然后再注册表下输入地址HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProt…

Electron+Vue3+Vite+ElectronForge整合 - 一键启动两个服务 一键打包两个服务

说明 本文介绍一下 Electron Vue3 Vite Electron Forge 的高级整合操作。vue3 : 使用 TS 的语法开发; Electron : 使用 JS 的语法开发。本文将从项目初始化开始,一步一步的完成项目的启动、打包全流程的介绍。实现的效果是 : 1、一个正常…

一个类实现Mybatis的SQL热更新

引言 平时用SpringBootMybatis开发项目,如果项目比较大启动时间很长的话,每次修改Mybatis在Xml中的SQL就需要重启一次。假设项目重启一次需要5分钟,那修改10次SQL就过去了一个小时,成本有点太高了。关键是每次修改完代码之后再重…

前端打包过大如何解决?

前端开发完毕部署到线上是,执行npm run build。当打包过大时,部署到服务端后加载缓慢,如何优化? 我们可以通过执行npm run analyze。可以看到各个包文件大小的区别。 当打包过大时,通过压缩gzip的方式,可以…

React路由导航

1. 什么是路由导航 一个路由跳转到另一个路由&#xff0c;并且在跳转的同时有可能需要传递参数进行通信&#xff0c;比如列表页跳转到详情页携带参数 2. 声明式导航 声明式导航是指通过在模版中通过 <Link/> 组件描述出要跳转到哪里去&#xff0c;比如后台管理系统的…

【LeetCode】---15.最小栈

【LeetCode】---15.最小栈 一、题目解析&#xff1a;二、算法原理&#xff1a;三、代码实现&#xff1a; 一、题目解析&#xff1a; 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初…

ARP学习及断网攻击

1.什么是ARP ARP&#xff08;Address Resolution Protocol&#xff09;是一种用于在IPv4网络中将IP地址映射到MAC地址的协议。在计算机网络中&#xff0c;每个网络接口都有一个唯一的MAC地址&#xff08;Media Access Control address&#xff09;&#xff0c;用于识别网络设备…

形态学图像处理

首先自己随便写了一个单词&#xff0c;然后在周围画一些相对细一点的噪声。 # 读取原始图片 original cv2.imread("romance.jpg") # 构造一个全1的5*5矩阵 kernel np.ones((5, 5), np.int8) 腐蚀 腐蚀&#xff08;Erosion&#xff09;是形态学图像处理中的一种基本…

Linux操作系统·进程管理

一、什么是进程 1.作业和进程的概念 Linux是一个多用户多任务的操作系统。多用户是指多个用户可以在同一时间使用计算机系统&#xff1b;多任务是指Linux可以同时执行几个任务&#xff0c;它可以在还未执行完一个任务时又执行另一项任务。为了完成这些任务&#xff0c;系统上…

初识Linux -- Linux的背景和发展史介绍

点赞关注不迷路&#xff01;&#xff0c;本节涉及初识Linux&#xff0c;主要为背景介绍和xshell登录主机。 1.Linux背景 1.1 发展史 Linux从哪里来&#xff1f;它是怎么发展的&#xff1f;在这里简要介绍Linux的发展史。 要说Linux&#xff0c;还得从UNIX说起。 1.2 UNIX发…

水下机器人(ROV)中继器(TMS)究竟是个啥?

前段时间公众号后台有人问释放ROV的装置&#xff0c;由于只用过观察级ROV Valor&#xff0c;博主一直以为他说的是绞车&#xff0c;后来才明白他说的是中继器&#xff0c;在水中用来释放、控制和回收ROV的装置。 中继器TMS的全称是缆绳管理系统Tether Management System&#…

Linux基础——Linux开发工具(下)_make/makefile

前言&#xff1a;在经过前面两篇学习&#xff0c;大家对Linux开发工具都有一定的了解&#xff0c;而在此之前最重要的两个工具就是vim&#xff0c;gcc。 如果对这两个工具不太了解&#xff0c;可以先阅读这两篇文章&#xff1a; Linux开发工具 (vim) Linux开发工具 (gcc/g) 首先…

vue 时间轴页面 自己的写法 欢迎交流指正

<div class"first-box"><!--贯穿线--><div class"vertical-line-wrap"><div class"vertical-line"></div><div class"vertical-line-arrow"></div></div><!--开始--><div c…

多输入多输出 | Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机多输入多输出预测

多输入多输出 | Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机多输入多输出预测 目录 多输入多输出 | Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机多输入多输出预测预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 Matlab实现WOA-LSSVM鲸鱼算法优化…

我五一是这样计划的,第一天...

前言 这个时间点&#xff0c;大多数人一定已经“峡谷做好准备全军出击”或者在出行的路上了。这个时间我也在回老家路上聊一聊。 行程 老读者都知道我老家在内蒙的西北的边陲城市&#xff0c;往年票都是随便买、除了春运几乎坐不满&#xff0c;今年五一居然也需要抢票&#…

用Python实现播放gif文件

用Python实现播放gif文件 在Python中&#xff0c;你可以使用第三方库Pillow&#xff08;PIL&#xff09;来加载和展示 GIF 文件。并实现“暂停”和“继续”控制功能。 Pillow是Python社区中最受欢迎的图像处理库之一&#xff0c;可以轻松地完成各种图像处理任务&#xff0c;它…