您的位置:首页 > 其它

Makefile构建工程设计——Makefile函数调用

2017-09-24 10:26 555 查看
变量定义展开通配符函数 wildcard parameter1 parameter2

条件判断函数
非空判断函数 if ifdefifndef

相等与不等判断函数 ifeqifneq

赋值shell命令函数 shell command

字符串处理函数
字符串替换函数 subst

文件名操作函数
取文件名目录函数 dir

取目录文件名函数 notdir

取后缀函数 suffix

取前缀函数 basename

加后缀函数 addsuffix

加前缀函数 addprefix

在Makefile中可以使用Makefile特点的函数来出来问题,例如在源码搜寻中使用的函数SRC = (wildcard(DIR_SRC)/*.c)

与变量相识,用关键字wildcard修饰,该函数的作用是实现通配符“*”,因为在Makefile变量定义中通配符不会自动展开,需要关键字修饰。整个函数的作用是:定义变量SRC,将目录$(DIR_SRC)/下的所有后缀为.c的文件都赋给变量SRC,这个定义与SRC = ./src/main.c ./src/module_func的功能是一样的。

与C语言类似,变量SRC其实就是函数的返回形式,也可以看做是这个函的宏定义。

Makefile的函数调用以关键字为核心修饰形式,结合变量定义来使用。

函数基本书写方法:$( )

function:函数名、关键字

arguments:函数传参

例如SRC = (wildcard(DIR_SRC)/.c)函数,源码路径不止只有一个,多个源码路径可以写成SRC = (wildcard(DIR_SRC)/.c $(DIR_SRC)/module/*.c)

变量定义展开通配符函数 $(wildcard parameter1 parameter2 …)

与上文描述的一样,通过该函数关键字的修饰,后面的参数就可以使用Linux下的通配符,参数以空格间隔。

条件判断函数

非空判断函数 $(if …)、ifdef、ifndef

函数写法:

$(if <condition>,<then-part>,<else-part>)
ifdef <condition>
ifndef <condition>


该函数判断的条件是判断condition是否非空,非空函数返回then-part的部分,空值则返回else-part的部分。该函数if没有判断condition里面逻辑是否为真假的能力,如果condition的值为1>2,对于Makefile来说,这个就是一个字符串,为非空值,所以判断为真。若不需要执行else-part部分,可以省略不写。

TESTIF1 = string
TESTIF2 =
IFFUNC1 = $(if 1>2,ture,false)
IFFUNC2 = $(if $(TESTIF1),then-part,else-part)
IFFUNC3 = $(if $(TESTIF2),then-part,else-part)

all:
@echo "this is all project"

@echo "$(IFFUNC1)"
@echo "$(IFFUNC2)"
@echo "$(IFFUNC3)"


执行结果

ghost@ghost-machine:~/workspace/testMakefile$ make
this is all project
ture
then-part
else-part


对于ifdef与ifndef,条件需要endif来约束,其判断的条件与上面的判断不同,但变量的标准是一致的。

TESTIF1 = string
TESTIF2 =

all:
@echo "this is all project"

ifdef $(TESTIF1)
@echo "test if 1 call true"
else
@echo "test if 1 call salse"
endif

ifdef TESTIF1
@echo "test if 1 true"
else
@echo "test if 1 salse"
endif

ifdef TESTIF2
@echo "test if 2 true"
else
@echo "test if 2 salse"
endif


执行结果:

ghost@ghost-machine:~/workspace/testMakefile$ make
this is all project
test if 1 call salse
test if 1 true
test if 2 salse


ifdef $(TESTIF1)

编译过程中展开:ifdef string

在Makefile文件中没有定义到“string”这个变量,执行else选项。

ifdef TESTIF1

在Makefile文件中定义了这个变量,并且这个变量的值非空,执行if选项。

ifdef TESTIF2

在Makefile文件中定义了这个变量,但这个变量的值为空,执行else选项。

相等与不等判断函数 ifeq、ifneq

书写方式:

相等判断:ifeq (string1,string2)

不等判断:ifneq (string1,string2)

该函数严格来说不是Makefile专用的函数,仅仅作为脚本判断语句,该函数是判断字符串string1与string2是否相等,根据相等或不等来执行下面的脚本,if执行脚本的范围由endif约束。

函数中可以不需要else的部分,但是不能去掉if的结尾部分endif来约束范围。

STRINFG1 = test
STRINFG2 = test

all:
@echo "this is all project"

ifeq ($(STRING1),$(STRING2))
@echo "true"
else
@echo "salse"
endif

ifneq ($(STRING1),$(STRING2))
@echo "true"
else
@echo "salse"
endif


执行结果

ghost@ghost-machine:~/workspace/testMakefile$ make
this is all project
true
salse


赋值shell命令函数 $(shell command)

Makefile本身就可以兼容一些shell脚本,比如在Makefile语句中直接输入:

gcc main.c -o main.o
或者
./test.sh


这些都是可以直接运行的,但这个赋值shell命令函数是将系统执行shell语句后,将结果返回给变量,最常见的是返回地址“pwd”的内容。

TESTSHELL1 = $(shell echo ./src/module/*.c)
TESTSHELL2 = $(shell pwd)

all:
@echo "this is all project"
@echo "$(TESTSHELL1)"
@echo "$(TESTSHELL2)"
@./test.sh


test.sh内容

#!/bin/bash

echo "this is shell test!!!"


执行结果:

ghost@ghost-machine:~/workspace/testMakefile$ make
this is all project
./src/module/module_func.c ./src/module/module_system.c
/home/ghost/workspace/testMakefile
this is shell test!!!


字符串处理函数

字符串替换函数 $(subst ,,)

该函数是以string为基础,在其中搜索找到source字符串,并将其替换为target字符串,这里的字符串可以是纯粹的字符串也可以是变量。

纯粹的字符串在Makefile有两种写法

1、带引号的字符串

TEST = $(subst abc,def,"abc test")

all:$(BIN_TARGET)
@echo "this is all project"
@echo $(TEST)


2、不带引号的变量

TEST = $(subst abc,def,abc test)

all:$(BIN_TARGET)
@echo "this is all project"
@echo $(TEST)


输出的结果都是一样的

ghost@ghost-machine:~/workspace/testMakefile$ make
this is all project
def test


通过变量可以被替换,那么在实际应用中,最多使用的是源码与目标文件的变换,例如将.c替换为.o

以Makefile书写风格为例工程的书写为

SRC = $(wildcard $(DIR_SRC)/*.c)
DIR_TARGET = $(subst %.o,%.c,$(SRC))
CFLAGS = -g -Wall $(DIR_INC)

all:$(BIN_TARGET)
@echo "this is all project"

$(BIN_TARGET):$(DIR_TARGET)
$(CC) $(CFLAGS) -o $@ $(DIR_TARGET)

$(DIR_TARGET):
@$(CC) $(CFLAGS) -c $(SRC)


函数DIR_TARGET = (subst(SRC))输出的结果是

将SRC中的所有.c文件描述的字符串都转换为.o文件描述的字符串

文件名操作函数

取文件名目录函数 $(dir …)

该函数是将类似地址的字符串中的目标文件以目录的形式剥离出来,类似地址的字符串是指带有反斜杠“/”的字符串,若没有遇到反斜杠,函数直接返回“./”,多个地址由空格间隔,返回的地址也是以空格间隔。

NAME1 = $(dir dir1/dir2/dir3/test1.c ./dir1/dir2/test2.c)
NAME2 = $(dir dir1dir2dir3test.c)

all:$(BIN_TARGET)
@echo "this is all project"
@echo "$(NAME1)"
@echo "$(NAME2)"


输出结果

ghost@ghost-machine:~/workspace/testMakefile$ make
this is all project
dir1/dir2/dir3/ ./dir1/dir2/
./


该函数的功能是处理类似地址的字符串功能,得到文件名的地址,该函数是为了方便转换,例如有些Makefile对源文件的写法

SRC = main.c ./src/module_func.c


利用该函数就可以得到这些源码文件的地址。

取目录文件名函数 $(notdir …)

该函数也是处理类似地址的字符串,类似地址的字符串中的目标文件以文件名形式剥离出来,与取文件名目录函数相反,函数返回的是文件名而不是目

DIR1 = $(notdir dir1/dir2/dir3/test1.c ./dir1/dir2/test2.c)
DIR2 = $(notdir dir1dir2dir3test.c)

all:$(BIN_TARGET)
@echo "this is all project"
@echo "$(DIR1)"
@echo "$(DIR2)"


执行结果

ghost@ghost-machine:~/workspace/testMakefile$ make
this is all project
test1.c test2.c
dir1dir2dir3test.c


取后缀函数 $(suffix …)

该函数处理类似有后缀的字符串,函数返回的是该字符串的后缀,该函数的判断标准是以字符串末尾的“.”结尾的后缀。

SUFFIX = $(suffix dir1/init.d/test.c test.tar.gz)

all:$(BIN_TARGET)
@echo "this is all project"
@echo "$(SUFFIX)"


执行结果

ghost@ghost-machine:~/workspace/testMakefile$ make
this is all project
.c .gz


取前缀函数 $(basename …)

该函数处理类似有后缀的字符串,函数返回的是该字符串的前缀,与取后缀函数相反,该函数的判断标准是字符串末尾的“.”为判断标准。如果是带有目录的字符串,返回的也是带有目录的,即该函数返回的是除后缀名以外的所有字符串。

BASENAME = $(basename dir1/init.d/test.c test.tar.gz)

all:$(BIN_TARGET)
@echo "this is all project"
@echo "$(BASENAME)"


执行结果

ghost@ghost-machine:~/workspace/testMakefile$ make
this is all project
dir1/init.d/test test.tar


加后缀函数 $(addsuffix , …)

该函数的作用是在字符串的末尾添加后缀名,后缀名与后面的文件名以逗号“,”间隔。

ADDSUF = $(addsuffix .c,dir1/dir2/test ./dir1/dir2/test.o)

all:
@echo "this is all project"
@echo "$(ADDSUF)"


执行结果

ghost@ghost-machine:~/workspace/testMakefile$ make
this is all project
dir1/dir2/test.c ./dir1/dir2/test.o.c


加前缀函数 $(addprefix , …)

该函数的作用是在字符串的开始添加前缀,前缀与后面的文件名以逗号“,”间隔。

ADDPRE1 = $(addprefix .c,dir1/dir2/test ./dir1/dir2/test.o)
ADDPRE2 = $(addprefix dir1/dir2/,test.c dir3/test)

all:
@echo "this is all project"
@echo "$(ADDPRE1)"
@echo "$(ADDPRE2)"


执行结果

ghost@ghost-machine:~/workspace/testMakefile$ make
this is all project
.cdir1/dir2/test .c./dir1/dir2/test.o
dir1/dir2/test.c dir1/dir2/dir3/test
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  makefile 设计