首页 > 其他分享 >Makefile基础教程(变量的高级主题,变量的拓展)

Makefile基础教程(变量的高级主题,变量的拓展)

时间:2023-06-10 10:38:37浏览次数:35  
标签:变量 Makefile echo test 基础教程 var 环境变量

(文章目录)


前言

本篇文章将给大家讲解一下变量的高级主题,变量的拓展,这些主题可以让你更加灵活地编写和维护 Makefile。

一、变量值的替换

1.简单替换

变量替换语法格式:

$(var:a=b)

其中,a 可以是一个字母,表示 var 中每个单词结尾的这个字母。b 则是替换的字符串。它会替换每个单词结尾的 a(如果有的话)。

这个语法通常用于修改一些表示文件路径或文件名的变量,以方便进行操作。

这里给出一个例子:

src := a.bc b.bc c.bc
obj := $(src:bc=oo)


test:
	@echo "src=>$(src)"
	@echo "obj=>$(obj)"

运行结果: 在这里插入图片描述

2.模式替换

1.变量的模式替换

在变量中使用模式替换就是将%前面和后面的换成我们想要替换的值。

src2 := a11b.c a22b.c a33b.c
src3 := $(src2:a%b.c=x%y)

test : 
	@echo "src3=>$(src3)"

运行结果: 在这里插入图片描述

2.规则中的模式替换

在工程开发中会有很多个需要被编译的文件,那么我们肯定不会和之前一样一个目标对应一个依赖,这样写是非常低效的,当要修改时也是非常困难的,所以在这里我们采取模式替换的方式来编写。

CC := gcc
TARGET := hello
OBJS := hello.o func.o


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

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

.PHONY: clean rebuild all

rebuild : clean all

all : TARGET

clean :
	$(RM) *.o TARGET

二、变量值的嵌套

在Makefile中,变量可以嵌套使用,以方便进行更加复杂的操作。嵌套变量的语法格式如下:

$(first_var$(second_var))

其中,first_var和second_var都是变量名。Make会首先展开$(second_var),以获取second_var的值,然后再将其插入到$(first_var)中,以展开为最终的变量值。

下面举一个例子:

x := y
y := z
a := $($(x))

test3 :
	@echo "x=>$(x)"
	@echo "y=>$(y)"
	@echo "a=>$(a)"

运行结果: 在这里插入图片描述

三、命令行变量

在Makefile中,命令行变量指的是通过make命令行传递给Makefile的参数。这些参数可以用于控制Makefile执行过程中的一些行为,例如指定编译器、调试选项等等。命令行变量的定义方式如下:

make <variable>=<value>

其中,variable 是命令行变量的名称,value是其值。在Makefile中,可以使用$(variable)来引用这个命令行变量的值。

这里举一个例子说明一下:

test := hello makefile

all : 
	@echo $(test)

运行结果: 在这里插入图片描述

四、define和override

在 Makefile 中,define 和 override 是两种比较重要的关键字。

define 关键字用来定义一个多行字符串,它的语法格式如下:

define <variable_name>
    <string>
endef

其中,<variable_name> 是定义的变量名,<string> 是这个变量名所对应的字符串,endef 表示字符串定义的结束标志符。事实上,define 定义的是一个多行的文本字符串,可以是命令、参数或者其他内容。定义后,这个变量就可以在 Makefile 的其他地方使用。

举个例子,你可以这样定义一个变量:

define MY_VARIABLE
    echo "hello world"
endef

然后在 Makefile 的其他地方,使用 $(MY_VARIABLE) 得到 "hello world" 的输出。

输出结果: 在这里插入图片描述

override关键字用于指示makefile中定义的变量不能被覆盖。

我们尝试着使用命令行来替换这个override 定义的变量:

define MY_VARIABLE
    "hello world"
endef

override var := hello

all : 
	@echo $(MY_VARIABLE)
	@echo $(var)

运行结果: 在这里插入图片描述 这里可以发现使用override定义的变量无法被命令行参数覆盖。

五.环境变量

在 Makefile 中,可以使用环境变量来传递参数或设置选项。环境变量是一种全局变量,对于整个 shell 都是可见的。Makefile 中可以访问这些环境变量,并在其中读取或设置值。

1.CFLAGS:编译选项的环境变量,可以用来设置编译器选项,例如 -Wall 和 -O2 等。

2.LDFLAGS:链接选项的环境变量,可以用来设置链接器选项,例如 -L 和 -l 等。

3.CC:编译器的环境变量,可以用来指定使用的编译器。例如 CC=gcc 表示使用 gcc 编译器。

使用export定义环境变量

一次定义一个变量和它的值:

export VARIABLE=value

示例代码:

test:
	@echo "var => $(var)"

定义环境变量: 在这里插入图片描述

运行结果:

在这里插入图片描述 这里定义的环境变量不仅可以在这个makefile当中使用也可以在其他的makefile中使用。

环境变量也能够被命令行变量覆盖: 在这里插入图片描述 使用-e选项可以优先使用环境变量:

var := abc

test :
	@echo "var =>$(var)"

使用make -e选项运行结果: 在这里插入图片描述

六.局部变量

在 Makefile 中,可以使用局部变量(也称为自动化变量),用于临时存储一些值,例如命令行参数、编译器选项和源文件列表等。和全局变量不同,局部变量只在当前的规则中有效。

test : test1

test : var1:=test-var1

test : test1
	@echo "var1=>$(var1)"

test1 :
	@echo "var1=>$(var1)"

test2 : 
	@echo "var1=>$(var1)"

运行效果:

从结果可以看出局部变量只在指定目标和连带规则中有效。 在这里插入图片描述

七.模式变量

模式变量则是一种构建在模式规则之上的变量类型,它可以让我们更方便地定义和管理模式规则的组合。

var := D.T.Software
new := TDelphi

%e : override new:= test-new
	
test : rule
	@echo "var => $(var)"
	@echo "new => $(new)"
	
rule :
	@echo "var => $(var)"
	@echo "new => $(new)"

运行结果: 从结果中可以看出模式变量作用域只在符合模式的目标及连带规则中。 在这里插入图片描述

总结

本篇文章知识点较多,这些内容也是makefile中比较重要的一些内容大家看完后要多加练习。

标签:变量,Makefile,echo,test,基础教程,var,环境变量
From: https://blog.51cto.com/u_16153875/6454038

相关文章

  • 2.3标识符、关键字、保留字 2.4 常量、变量、数据类型
     2.3标识符、关键字、保留字2.3.1标识符标识符只能由字母、下划线"_"、数字、美元符号"$"组成并且首字母不能是数字。区分大小写、且不能插入空格。以下举例:合法:Dog、class_3、_price、$123、$123bay、abc_123、¥123非法:3_class、&class、class、NO.1(关键字)、.com、#myname2.3.2......
  • python3中print()函数打印多个变量值
    第一种方法:print("变量1",file_name,"变量2",new_name) print("变量1",file_name,"变量2",new_name) 第二种方法:print("变量1:%s变量2:%s"%(file_name,new_name)) print("变量1:%s变量2:%s"%(file_name,new_nam......
  • [Java SE] 彻底搞懂Java程序的三大参数配置途径:系统变量与JVM参数(VM Option)/环境变
    0序言一次没搞懂,处处受影响。这个问题属于基础问题,但又经常踩坑,不得不重视一下了。1Java程序动态参数的配置途径:系统变量与JVM参数(VMOption)vs环境变量vs启动程序参数argsIDEA中的配置位置参数使用方式示例代码获取方式系统属性由操作系统、JVM、应用......
  • 反射:获取类的成员变量
        ......
  • [从jQuery看JavaScript]-变量与作用域链(Variable and Scope Chain)
    jQuery片段: 1.var2.//Willspeedupreferencestowindow,andallowsmungingitsname.3.window=this,4.//Willspeedupreferencestoundefined,andallowsmungingitsname.5.undefined,6.//MapoverjQueryinc......
  • sed引入变量:三引号'''
    sed引入变量时,需要使用三引号,格式为三个单引号,或者单引号内套一个双引号!!![root@controller~]#cattest.txt123456789[root@controller~]#sed-i's/3/'''c'''/'test.txt[root@controller~]#cattest.txt12c456789[root@controller~]#sed-i......
  • 过滤器-使用Vue.filter定义全局变量
    私有过滤器和全局过滤器在filters节点下定义的过滤器,称为”私有过滤器“,因为它它只能在当前VM实例所控制的el区域内使用。如果希望在多个vue实例之间共享过滤器,则可以按照如下的格式定义全局过滤器:<!DOCTYPEhtml><html> <head> <metacharset="utf-8"> <title></title> ......
  • 解决ssh连接docker容器环境变量无效的问题
    问题缘由:因在docker容器中的linux系统输入nvcc等命令都是有效的,但通过ssh连接到docker容器内,就存在该命令未找到等问题,查询资料得知,这是因为通过ssh连接docker容器后环境变量发生了变化,修改方法:解决方法:更改字段分隔符,使之仅仅遇到换行时分割/etc/profile中添加以下代码即可......
  • 变量 和 注释
    #####变量和注释之前我们就说过:Python语言中,所有的数据都被称之为对象。每个整数、小数、字符串,还有我们后面要学的字典、元组、列表等,都是对象。在Python程序运行的时候,这些对象其实就是内存中的一段数据。我们的程序是经常要操作这些内存中的数据对象的,比如打印......
  • Makefile基础教程(自动生成依赖关系)
    @TOC前言在前面的文章中我们都只使用到了.c文件作为依赖但是在实际的工程中肯定是不可能只有.c文件的还存在.h文件,那么在包含了.h文件后又该如何来包含依赖关系呢?一、makefile不包含.h依赖的后果首先先在目录下新建四个文件夹,其中就包含了fun.h这个文件。makefile:OBJS:=fun.omai......