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

来源:互联网 发布:cad软件手机版 编辑:程序博客网 时间:2024/05/16 16:18

  • 变量定义展开通配符函数 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 = stringTESTIF2 =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$ makethis is all projectturethen-partelse-part

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

TESTIF1 = stringTESTIF2 =all:    @echo "this is all project"ifdef $(TESTIF1)    @echo "test if 1 call true"else    @echo "test if 1 call salse"endififdef TESTIF1    @echo "test if 1 true"else    @echo "test if 1 salse"endififdef TESTIF2    @echo "test if 2 true"else    @echo "test if 2 salse"endif

执行结果:

ghost@ghost-machine:~/workspace/testMakefile$ makethis is all projecttest if 1 call salsetest if 1 truetest 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 = testSTRINFG2 = testall:    @echo "this is all project"ifeq ($(STRING1),$(STRING2))    @echo "true"else    @echo "salse"endififneq ($(STRING1),$(STRING2))    @echo "true"else    @echo "salse"endif

执行结果

ghost@ghost-machine:~/workspace/testMakefile$ makethis is all projecttruesalse

赋值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/bashecho "this is shell test!!!"

执行结果:

ghost@ghost-machine:~/workspace/testMakefile$ makethis is all project./src/module/module_func.c ./src/module/module_system.c/home/ghost/workspace/testMakefilethis 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$ makethis is all projectdef 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$ makethis is all projectdir1/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$ makethis is all projecttest1.c test2.cdir1dir2dir3test.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$ makethis 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$ makethis is all projectdir1/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$ makethis is all projectdir1/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$ makethis is all project.cdir1/dir2/test .c./dir1/dir2/test.odir1/dir2/test.c dir1/dir2/dir3/test
原创粉丝点击