Makefile文件---定义变量和引用变量

📅 发布时间:2026/9/1 4:54:37
Makefile文件---定义变量和引用变量
0 Preface/Forword0.1 makefile文件定义变量的方法在Makefile中定义变量的方法直接在makefile文件内部定义在make命令行中定义1 变量定义1.1 make命令中定义在makefile中通过命令定行定义或修改变量是一种非常灵活且常用的方式主要用于动态控制构建行为切换编译模式、指定安装路径等。1.1.1 语法规则基本语法在执行make命令时直接在命令后添加var_namevalue就可以。如果有多个变量可以用空格分隔。1.1.2 实例源码var_print: echo compiler: ${CC} echo compiler: $(CC)运行结果cc和gcc1.1.3 命令行定义命令常用场景场景命令示例说明切换编译器make CCg临时更换C/C编译器开启调试make CFLAGS-g -O0添加调试符号关闭优化指定安装路径make PREFIX/usr/local install自动以软件安装路径选择构建目标make BUILD_TYPErelease all根据变量条件编译不同代码分支1.2 ? 定义变量 (Conditional assignment)在makefile中通过?来定义变量的值。处理规则赋值前判断该变量是否已经存在如果存在则不重新赋值如果不存在则重新赋值。用于给变量赋默认值展开方式与赋值方式一样递归展开以下三种情况?不会赋值命令行定义了变量。makefile中前面已经定义了变量环境变量中已经定义了该变量比如CC变量。1.2.1 ExampleCC ? g MODE ? debug var_print: echo compiler: $(CC) echo mode: $(MODE)运行结果1.3 : 定义变量 (Simple Expansion)通过:方式定义的变量称为简单展开变量或者称为立即展开变量。相关属性如下规则立即求值Make在读取该行时会立即计算右边表达式的值并将结果固定下来。静态值一旦赋值完成变量的值就确定了后续对右侧依赖变量的修改不会影响改变量。只能引用已经定义过的变量右侧只能引用在此之前已经定义过的变量否则值为空。优点效率高只计算一次行为可预测避免循环引用问题。缺点不能引用后面定义的变量。1.4 定义变量 (Appended)用于向变量的末尾添加内容常用于累积源文件列表或编译标志。具体属性如下所示规则自动空格make会在原有值和新增值之间自动添加一个空格。继承类型的行为取决于该变量之前是如何定义的。如果变量之前是用定义的保持递归展开特性。如果变量之前是用:定义的保持简单展开特性。先展开旧值再追加新值如果变量之前未定义等效于将其定义为递归展开变量。典型场景模块化构建中不同模块向同一个变量如SRCS或CFLAGS添加内容。1.5 定义变量 (Recursive Expansion)makefile中最基本的赋值方式定义的变量称之为递归展开变量。相关属性如下规则延时求值make在读取该行时不会立即计算右边的值而是将右边的文本原样保存。使用时展开只有当该变量在后续被引用$(VAR)时make才会去展开其中的内容。引用最新值展开时它会使用变量在makefile中最后一次被赋予的值。意味着可以引用在定义之后才赋值的变量。优点灵活允许变量引用未来定义的变量。缺点如果存在循环引用如A$(B), B$(A)会导致无限递归错误每次引用都重新计算性能较低。1.6 变量传递给子make (sub-make)在一个makefile中调用另一个make命令嵌套make时命令行定义的变量会自动传递给子make进程。define_var.mk源码CC ? g MODE ? debug var_print: echo compiler: $(CC) echo mode: $(MODE) make -f sub_test.mksub_test.mk源码MODE ? debug all: echo mode: $(MODE)运行结果1.7 override的作用override标记的变量不会被命令行中的定义所覆盖。CC ? g override MODE debug var_print: echo compiler: $(CC) echo mode: $(MODE) make -f sub_test.mk1.8 变量定义对比总结总结表如下所示操作符名称求值时机能否引用后定义变量是否覆盖已有值典型用途递归赋值使用时延时✅️能✅️是通用变量定义灵活性强。:简单赋值定义时立即❌️不能✅️是性能敏感场景避免副作用循环引用。?条件赋值使用时延时✅️能❌️否若已有值设置默认值允许命令行覆盖。追加赋值取决于前文取决于前文❌️追加积累列表如源文件、标志1.9 变量定义最佳实践定义变量相关建议优先使用 :除非需要引用后面定义的变量否则强烈推荐使用 : 因为它效率更高且行为直观。使用 ? 设置默认值对于编译器路径、优化级别等配置项使用 ? 可以让用户更容易通过命令行自定义。使用 管理列表在大型项目中使用 逐步构建源文件列表或编译参数可以提供makefile的可维护性。避免循环引用使用 时要小心不要形成 A$(B) 和 B$(A)这样的循环。2 变量引用引用变量的两种方法$(VAR)${VAR}var_print: echo compiler: ${CC} echo compiler: $(CC)3 变量优先级3.1 变量的来源Make变量的来源只要有四个渠道优先级从高到底依次为命令行参数最高优先级通过命令行make VARvalue传递。makefile中override定义使用override VARvalue定义变量。makefile中普通定义使用、:、?、定义变量。环境变量最低优先级系统环境中已经存在的变量除非使用-e选项