makefile学习笔记(二)

makefille中特殊变量

$(MAKE)   当前make解释器的文件名

$(MAKECMDGOALS) 命令行中指定的目标名

$(MAKEFILE_LIST) make所需处理的makefile文件列表,当前makefile的文件名总是位于列表的最后,文件名之间以空格进行分隔

 

test :

$(MAKE) first

$(MAKE) second

$(MAKE) third

目标first second third可以为其他文件的伪目标,用来关联多个makefile文件

 

$(MAKE_VERSION) 当前make解释器的版本号

$(CURDIR) 当前make解释器的工作目录

$(.VARIABLES) 所有已定义的变量名列表(预定义变量和自定义变量)

 

 

变量值的替换

使用指定字符(串)替换变量值中的后缀字符(串)

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

 

变量的模式替换

使用%保留变量值中的指定字符,替代其他字符

语法格式:$(var:a%b=x%y)或${var:a%b=x%y}

 

规则中的模式替换

targets : target-pattern : prerequisite-pattern

command1\

command2\

意义:通过target-pattern从targets中匹配子目标,再通过prereq-pattern从子目标生成依赖,进而构成完成的规则

 

OBJS := fun.o main.o

 

$(OBJS) : %.o : %.c

gcc -o $@ -c $^

 

变量值的嵌套引用

x := y

y := z

a := $($(x))

 

运行make时,在命令行定义变量,命令行变量默认覆盖makefile中定义的变量

 

Override关键字用于指示makefile中定于的变量不能背覆盖

 

hm := hello makefile

 

override var := override-test

 

test :

@echo "hm => $(hm)"

@echo "var => $(var)"

@echo "fool => $(fool)"

 

make hm=123

 

make var=eee

 

make fool=aaaa

 

Define关键字用于makefile中定义多行变量,多行变量的定义从变量名开始到ended结束,常用于生成命令

例如

define foo

I am good!

endef

 

makefile中能够直接使用环境变量,定义了同名变量,环境变量将会被覆盖,通过make - e选项优先使用环境变量

 

变量在不同的makefile文件中传递

1.采用环境变量

2.使用export定义变量进行传递

3.定义make命令行变量进行传递(推荐)

 

JAVEA_HOEME := java home

export var := qqq

new := huang

 

//makefile

test :

@echo “JAVEA_HOEME => $(JAVEA_HOEME)”

@$(MAKE) -f makefile1 new:=$(new)

 

make test

make -e test

 

//makefile1

test :

@echo “JAVEA_HOEME => $(JAVEA_HOEME)”

@echo “var = $(var)”

@echo “new = $(new)”

  

目标变量为局部变量,作用域只在指定目标及连带规则中

 

模式变量是目标变量的扩展

 

var := 123

 

test : var:= test-var

 

test :

@echo "var => $(var)"

 

var => test-var

 

//

var := 123

 

test : var:= test-var

 

test :

@echo "var => $(var)"

 

another :

@echo "var => $(var)"

 

make another

 

var => 123

 

//

new := qqq

 

%e : override new := awe

 

test :

@echo "new = $(new)"

 

rule :

 

@echo "new = $(new)"

 

 

make test rule

 

new = qqq

new = awe

 

条件判断语句,依据条件的至来决定make的执行,只能控制make实际执行的语句,但是不能控制规则中命令的执行

If (arg1, arg2) //括号可以用单双引号代替

 

else

 

endif

 

条件判断关键字 ifeq infer ifdef ifndef

.PHONY : test

 

var1 := A

var2 := $(var1)

var3 :=

 

test :

ifeq ($(var1), $(var2))

@echo "var1 == var2"

else

@echo "var1 != var2"

endif

 

ifneq ($(var2), )

@echo "var2 is not empty"

else

@echo "var2 is empty"

endif

 

ifdef var2

@echo "var2 is not empty"

else

@echo "var2 is empty"

endif

 

ifndef var3

@echo "var3 is empty"

else

@echo "var2 is not empty"

endif

 

make

 

var1 == var2

var2 is not empty

var2 is not empty

var3 is empty

 

条件判断语句之前可以有空格,但是不能有tab字符(‘\t’)

 

在条件语句中不要使用自动变量($@, $^, $<)

 

一条完整的条件语句必须位于同一个makefile中

 

条件判断语句类似于c语言中的宏,预处理阶段有效,执行阶段无效

Make在加载makefile时,根据判断语句的表达式决定执行的内容

.PHONY : test

 

var1 :=

var2 := $(var1)

 

var3 =

var4 = $(var3)

 

test :

ifdef var1

@echo "var1 is defined"

else

@echo "var1 is not defined"

endif

 

ifdef var2

@echo "var2 is defined"

else

@echo "var2 is not defined"

endif

 

ifdef var3

@echo "var3 is defined"

else

@echo "var3 is not defined"

endif

 

ifdef var4

@echo "var4 is defined"

else

@echo "var4 is not defined"

endif

 

make

 

var1 is not defined

var2 is not defined

var3 is not defined

var4 is defined

 

递归复制,make解释器无法解析var4是否定义,默认为已定义

 

 

函数的定义及调用

1.make解释器提供了一系列函数供makefile调用

2.通过define关键字实现自定义函数

 

//定义

define fun1

@echo “My name is $(0).”

@echo “Param => $(1)”

endef

 

//调用

test :

$(call func1)

 

自定义函数是一个多行命令,无法直接调用,是一种过程调用,没有任何的返回值

自定义函数是make解释器在预定义时call函数在调用时将参数传递给多行变量

.PHONY : test

 

define func1

@echo "My name is $(0)."

@echo "Param => $(1)"

endef

 

var := $(call func1)

new := $(func1)

 

test :

@echo "var => $(var)"

@echo "new => $(new)"

$(call func1, hello)

 

var => @echo My name is func1

new => @echo My name is

My name is func1.

Param =>  hello

 

//

.PHONY : test

 

define func1

@echo "My name is $(0)."

endef

 

func2 := @echo "My name is $(0)."

 

 

test :

$(call func1)

$(call func2)

 

make

 

My name is func1.

My name is .

 

原因是call只能处理多行变量

 

变量与函数的综合示例

$(wildcard _pattern)   获取当前工作目录满足_pattern的文件或目录列表

$(addprefix _prefix, names) 给名字列表_names中的每一个名字增加前缀_prefix

 

SRCS := $(wildcard *.c)   自动获取当前目录下的源文件列表

OBJS := $(SRCS:.c = .o )   替换变量值,将.c替换为.o文件

OBJS := $(addprefix path/, $(OBJS))    对每一个目标文件列表加上路径前缀

 

%.c用于模式匹配当前目录下的文件列表

%.o : %.c

gcc -o $@ -c $^

 

CC := gcc

MKDIR := mkdir

RM := rm -fr

 

DIR_OBJS := objs

DIR_TARGET := target

 

DIRS := $(DIR_OBJS) $(DIR_TARGET)

 

TARGET := $(DIR_TARGET)/hello-makefile.out

 

# main.c const.c fun.c

SRCS := $(wildcard *.c)

# main.o const.o fun.o

OBJS := $(SRCS:.c=.o)

# objs/main.o objs/const.o objs/fun.o

OBJS := $(addprefix $(DIR_OBJS)/, $(OBJS))

 

.PHONY : rebuild clean all

 

$(TARGET) : $(DIRS) $(OBJS)

$(CC) -o $@ $(OBJS)

@echo "Target file ==> $@"

 

$(DIRS) :

$(MKDIR) $@

 

$(DIR_OBJS)/%.o : %.c

$(CC) -o $@ -c $^

 

rebuild : clean all

 

all : $(TARGET)

 

clean :

$(RM) $(DIRS)

 

make all

 

mkdir objs

mkdir target

gcc -o objs/const.o -c const.c

gcc -o objs/fun.o -c fun.c

gcc -o objs/main.o -c main.c

gcc -o target/hello-makefile.out objs/const.o objs/fun.o objs/main.o

Target file ==> target/hello-makefile.out

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值