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)
该函数判断的条件是判断condition是否非空,非空函数返回then-part的部分,空值则返回else-part的部分。该函数if没有判断condition里面逻辑是否为真假的能力,如果condition的值为1>2,对于Makefile来说,这个就是一个字符串,为非空值,所以判断为真。若不需要执行else-part部分,可以省略不写。
执行结果
对于ifdef与ifndef,条件需要endif来约束,其判断的条件与上面的判断不同,但变量的标准是一致的。
执行结果:
ifdef $(TESTIF1)
编译过程中展开:ifdef string
在Makefile文件中没有定义到“string”这个变量,执行else选项。
ifdef TESTIF1
在Makefile文件中定义了这个变量,并且这个变量的值非空,执行if选项。
ifdef TESTIF2
在Makefile文件中定义了这个变量,但这个变量的值为空,执行else选项。
相等判断:ifeq (string1,string2)
不等判断:ifneq (string1,string2)
该函数严格来说不是Makefile专用的函数,仅仅作为脚本判断语句,该函数是判断字符串string1与string2是否相等,根据相等或不等来执行下面的脚本,if执行脚本的范围由endif约束。
函数中可以不需要else的部分,但是不能去掉if的结尾部分endif来约束范围。
执行结果
这些都是可以直接运行的,但这个赋值shell命令函数是将系统执行shell语句后,将结果返回给变量,最常见的是返回地址“pwd”的内容。
test.sh内容
执行结果:
纯粹的字符串在Makefile有两种写法
1、带引号的字符串
2、不带引号的变量
输出的结果都是一样的
通过变量可以被替换,那么在实际应用中,最多使用的是源码与目标文件的变换,例如将.c替换为.o
以Makefile书写风格为例工程的书写为
函数DIR_TARGET = (subst(SRC))输出的结果是
将SRC中的所有.c文件描述的字符串都转换为.o文件描述的字符串
输出结果
该函数的功能是处理类似地址的字符串功能,得到文件名的地址,该函数是为了方便转换,例如有些Makefile对源文件的写法
利用该函数就可以得到这些源码文件的地址。
执行结果
执行结果
执行结果
执行结果
执行结果
条件判断函数
非空判断函数 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构建工程设计——工程组织Makefile的嵌套
- Makefile构建工程设计——工程构建与编写规则
- arm-none-eabi-gcc,makefile,stm官方库构建stm32f4xx工程
- Makefile 构建工程,如果加载opencv等第三方库
- CMake 工程调用 Makefile 编译项目
- 多目录工程构建Makefile的编写
- [转]用makefile脚本方式调用vs 2010 的nmake来编译工程的实例
- xcode7 ios9 iOS中设计模式中委托模式(同一工作空间不同工程)异步调用
- vcxproj2makefile 将VC的工程文件 转换成makefile,让nmake来调用。
- Eclipse CDT 导入 Makefile 构建的 C/C++ 工程
- 如何将makefile构建的工程导入C++test?
- 使用Makefile构建工程
- 建立工程时,静态库分层的调用关系,一开始就要设计好
- 一步一步写MP3项目的Makefile--构建MP3项目工程
- 图像显示特效工程GraphShow构建(一):概要设计
- 如何将makefile构建的工程导入C++test?
- vcxproj2makefile工具 将VC的工程文件转换成makefile,让nmake来调用
- 工程设计和实现构建文件的方法--提出一组问题
- linux嵌入式编程高手历程系列7-用qmake快速构建工程makefile
- 用makefile脚本方式调用vs 2010 的nmake来编译工程的实例