gnu make 手册 学习笔记 C语言 / C++ 构建工具 part.3 变量的使用,传递,取消 特殊变量 VPATH 缓存的变量

3-2.变量

3-2-1.变量的定义

Makefile

.PHONY: print   

Immediate_var  := _immediate_$(var)        # 将右边的值赋值给Immediate_var变量,
                          #立即量,马上赋值,就是会在解析这个文件的时候找到变量$(var)的值,然后将完整的右边的值赋值到左边
                          #如果运行到这里var没有值,就没有值了,下面的语句,可以重新使用 = 为这个变量赋值
                          


Lazy_var       =_lazy_$(var)               # 将value赋值给Lazy_var的变量,
                          #如果后面改变了这个中,引用这个变量的recipe在调用的时候会更新为最新的值,就是最下面定义的值
 
var            =_value_to_be_change  

Immediate      :=$(var)_immediate#这个立即量就会有值
                          
setIfAbsent    ?= _set_if_absent           # 如果变量没有值,就赋值,如果有值了,就不再赋值,就是不再更新值
setIfAbsent    ?= _can_not_revise

append_var     =_want_to_be_append                           
append_var     +=_this_is_append_message.                 #相当于字符串append

print:                                
	@echo  var___________________=__________$(var) ;
	@echo  lazy_var______________=_________$(Lazy_var);
	@echo  immediate_var_________=__________$(Immediate_var);
	@echo  setIfAbsent_var_______=________$(setIfAbsent);
	@echo  append_var____________=__________$(append_var);   

var =_value_changed        #在执行的语句后面变更变量的值,值依然可以改变

在这里插入图片描述

3-2-2.Secondary Expansion $$

GNU make also has the ability to enable a second expansion of the prerequisites (only) for some or all targets defned in the makefle.

Makefile

.PHONY: all clean

all: main lib



#这里是定义了用于依赖的变量,简单说就是有两组源文件
.SECONDEXPANSION:
main_OBJS := src/main.o   src/try.o   src/test.o   
lib_OBJS  := lib/lib.o    lib/api.o                    

#这里是写了两个target,这两个target的规则是模式相同的
#  $@引用的是target,例如将main带入,就是$$(main_OBJS)
main  lib : $$($$@_OBJS)        
	gcc  $^  -o  $@
#将规则中的依赖作为源文件,使用gcc编译为一个可执行文件,文件的名字是target,
#这里的target是在使用的时候的target,例子make main或者make lib

clean:
	rm -rf *.o *.exe
需要项目结构

在这里插入图片描述
执行后的结果是,在当前文件生成了两个exe文件,并且在每个源文件都生成了.o文件,自动生成的.o文件是make有pattern rule
在这里插入图片描述

3-2-3.特殊的变量VPATH

VPATH可以理解为,指定prerequires的查找路径
例如上面的例子可以改为

VPATH =src lib           #VPATH可以设定多个值,相当于一个path list

指定了查找路径就可以直接写文件的名字,不用写路径
.SECONDEXPANSION:
main_OBJS := main.o   try.o   test.o   
lib_OBJS  := lib.o    api.o   
main  lib : $$($$@_OBJS)        
gcc  $^  -o  $@

但是如果VPATH的多个路径中,存在同名的文件,那么是会报错的。
例如 , 下面两个main.o是会造成错误的。
main_OBJS := main.o   try.o   test.o   
lib_OBJS  := main.o   lib.o    api.o   
是否使用VPATH,可以根据需要确定

3-2-4.make缓存的变量

使用make -p 命令,会将这些变量打印出来
下面是摘出来的一些变量

=========C语言编译的语句==========
# default    定义使用的编译器cc有说法就是原来的gcc
CC = cc
# default   预编译
PREPROCESS.S = $(CC) -E $(CPPFLAGS)
# default      编译成二进制,就差链接
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c         
# default    链接
LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)
# default    编译
COMPILE.S = $(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c
# default   链接
LINK.S = $(CC) $(ASFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_MACH)

# default  链接
LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
# default   链接
LINK.s = $(CC) $(ASFLAGS) $(LDFLAGS) $(TARGET_MACH)

===============================命令和参数====================================================
# default        make的命令
MAKE_COMMAND := make
# default         make的版本
MAKE_VERSION := 4.2.1
# default         make的命令
MAKE = $(MAKE_COMMAND)
# default               库的文件名样式
.LIBPATTERNS = lib%.dll.a %.dll.a lib%.a %.lib lib%.dll %.dll
# default    查找include的路径
.INCLUDE_DIRS = /usr/include /usr/include   
# default      输出的选项,简单理解是gcc -o $@可以写为   gcc  $(OUTPUT_OPTION)
OUTPUT_OPTION = -o $@                  
# default   Linux下删除文件的命令,window下需要cygwin或者mingw
RM = rm -f
# default     使用的shell的位置
SHELL := /bin/sh                                                      
# default   静态库的打包命令
AR = ar




# makefile       当前工作目录
CURDIR := /cygdrive/f/temp/makeLearning/HelloWorld    

# environment   系统的环境变量
TEMP = /cygdrive/c/Users/JimmyLee/AppData/Local/Temp

===========================================自动变量======================================
# automatic 
$@             当前target的名字,是实际执行recipe的target ,如果target是一个库的target,那么就是这个库的名字
# automatic
$<              第一个prerequires的名字
# automatic
$^              所有prerequires的名字,如果有重复将会去除
# automatic
$?            表示prerequires中变化了的值
		#lib: foo.o   bar.o   lose.o   win.o
		#	 ar  r  lib  $?    #foo.o  bar.o  lose.o  win.o的文件发生变化的才被选中打包
# automatic
$%        foo.a(bar.o):bar.o     
				recipe          
				 # 文档上写  $@就是foo.a    $%就是bar.o  如果target不是archive那么返回空
				 #试不出来
# automatic
$*            需要是make识别的后缀,最好不要使用了例如target是mylib.a,那么$*就是mylib,可是make不识别就返回空
# automatic
$+             类似$^,不同的是没有去重
# automatic
$|          The names of all the order-only prerequisites, with spaces between them.??????

=================使用上面自动变量的方式匹配prerequires来表示路径(D)或者文件(F)=======================
# automatic
$(@D)           当前target文件的所在路径,例如$@表示dir/foo.o,那么$(@D)就是dir
# automatic
$(@F)  			当前target的文件名字,例如$@表示dir/foo.o,那么$(@F)就表示foo.o
# automatic
$(*D)               路径的名字,使用$*的方式匹配prerequirs
# automatic
$(*F)		文件的名字,使用$*的方式匹配prerequires
# automatic
$(%D)
# automatic
$(%F)
# automatic
$(<D)
# automatic
$(<F)
# automatic
$(^D)
# automatic
$(^F)
# automatic
$(+D)
# automatic
$(+F)
# automatic
$(?D)
# automatic
$(?F)
自动变量的例子

Makefile

test_target :  src/main.o    test.o
	@echo $@       #当前target的名字
	@echo $<       #第一个prerequires的名字
	@echo $^       #全部prequires的名字,使用空格分隔,去重
	@echo $?       #prequires中出现了变化的内容,
	@echo $+       #不去重的 $^
	@echo $(@D)    #target的路径
	@echo $(@F)    #target的文件名
	@echo $(<D)    #第一个prequires的路径
	@echo $(<F)    #第一个prequires的文件名
	@echo $(^D)    #全部prequires的路径,使用空格分隔
	@echo $(^F)    #全部prequires的文件名
	@echo $(?D)    #prequires中变化的内容的路径
	@echo $(?F)    #prequires中变化的内容的文件名
	@echo $(+D)	   #不去重的$(^D)
	@echo $(+F)	   #不去重的$(^F)

在这里插入图片描述

项目的简单结构

在这里插入图片描述

∗ 和 *和 %

Makefile

#这里的target使用的是Archive Members as Targets的写法 archive(member)
foolib.a$(libsource.o):libsource.o
	@echo "%="$% "@="$@ "*="$*

在这里插入图片描述

3-2-5.变量在不同Makefile中的传递

Makefile

include lib/nestFile

makefile_var ="on top"

export makefile_var

lib/nestFile

print :
	@echo "in nest file "$(makefile_var)

在这里插入图片描述

3-2-6变量的代换substritution

语法
	$(var:a=b)或者${var:a=b}

例子,可以用来改后缀

.PHONY: print clean

foo =  a.c   b.c   c.c   d.o   e.b     

print : 
	@echo $(foo:.c=.o)            #将.c后缀改为.o后缀,:后面不能有空格

在这里插入图片描述

3-2-7 取消一个变量

例子

foo =value
undefine    foo          #使用undefine来取消一个变量的定义,这样下面$(foo)就是空

print : 
	@echo  $(foo)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值