http://blog.sina.com.cn/s/blog_b3dc8bf301017e8g.html makefile是一个make的规则描述脚本文件,包括四种类型行: 目标行、命令行、宏定义行和make伪指令行(如“include”)。 makefile文件中注释以“#”开头。 当一行写不下时,可以用续行符“\”转入下一行。Makefile中的预定义变量:
- CC,C语言编译器的名称,cc
- CPP, C语言预处理器的名称,$(CC) -E
- CXX, C++语言的编译器名称,g++
- RM,删除文件程序的名称,rm -f
- CFLAGS, C语言编译器的编译选项,无默认值
- CPPFLAGS,C语言预处理器的编译选项,无默认值
- CXXFLAGS,C++语言编译器的编译选项,无默认值
注:在使用RM时,一般使用如下语句: -$(RM) $(TARGET) $(OBJS), 符号“-”表示在操作失败时不报错,而是继续执行。例如在不存在TARGET时将继续删除OBJS。
Makefile中的自动变量:
- $*, 表示目标文件的名称,不包含扩展名
- $@, 表示目标文件的名称,包含扩展名
- $+, 表示所有的依赖文件,以空格隔开,可能含有重复的文件
- $^, 表示所有的依赖文件,以空格隔开,不重复
- $<, 表示依赖性中第一个依赖文件的名称
- $?, 依赖项中,所有比目标文件新的依赖文件
赋值变量
1、使用“:=”操作符,使得前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。
2、使用”?=”操作符:例如foo ?=bar 如果foo没有被定义过,那么变量foo的值就是“bar”,否则此语句什么也不做,这段代码等同于:
搜索路径:
- VPATH,路径之间用:隔开
声明伪目标:
- .PHONY:clean
Makefile中的函数:一、函数的调用语法
函数调用,很像变量的使用,也是以“$”来标识的,其语法如下:
$(<function> <arguments>)
或是${<function> <arguments>}
这里 function 就是函数名,make支持的函数不多。* arguments*是函数的参数,参数间以逗号“,”分隔,而函数名和参数之间以“空格”分隔。函数调用以“$”开头,
以圆括号或花括号把函数名和参数括起。感觉很像一个变量,是不是?函数中的参数可以使用变量,为了风格的统一,函数和变量的括号最好一样,
如使用
"$(subst a,b,$(x))"
这样的形式,而不是"$(subst a,b,${x})"
的形式。因为统一会更清楚,也会减少一些不必要的麻烦。 还是来看一个示例:comma:= , empty:= space:= $(empty) $(empty) foo:= a b c bar:= $(subst $(space),$(comma),$(foo))
在这个示例中,
$(comma)
的值是一个逗号。$(space)
使用了$(empty)
定义了一个空格,$(foo)
的值是"abc"
,$(bar)
的定义用,调用了函数"subst"
,这是一个替换函数,这个函数有三个参数,第一个参数是被替换字串,第二个参数是替换字串,第三个参数是替换操作作用的字串。这个函数也就是把
$(foo)
中的空格替换成逗号,所以$(bar)
的值是
"a,b,c"
。
一、字符串处理函数
1..$(patsubst <pattern>,<replacement>,<text> )
函数名称:模式替换函数—patsubst。
函数功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否
符合模式<pattern>,如果匹配的话,则以<replacement>替换。这里,<pattern>可以包括
通配符“%”,表示任意长度的字串。如果<replacement>中也包含“%”,那么,
<replacement>中的这个“%”将是<pattern>中的那个“%”所代表的字串。(可以用“\”
来转义,以“\%”来表示真实含义的“%”字符)
返回值:替换后的新字符串。
函数说明:参数“TEXT”单词之间的多个空格在处理时被合并为一个空格,但前导和结尾空格忽略。
示例:
$(patsubst %.c,%.o,x.c.c bar.c)
把字串“x.c.cbar.c”符合模式[%.c]的单词替换成[%.o],返回结果是“x.c.obar.o”
备注:
这和我们前面“变量章节”说过的相关知识有点相似。
2.$(findstring FIND,IN)
函数名称:查找字符串函数—findstring。
函数功能:搜索字串“IN”,查找“FIND”字串。
返回值:如果在“IN”之中存在“FIND”,则返回“FIND”,否则返回空。
函数说明:字串“IN”之中可以包含空格、[Tab]。搜索需要是严格的文本匹配。
$(findstring a,a b c)
$(findstring a,b c)
第一个函数返回“a”字符串,第二个返回“”字符串(空字符串)
二、文件名处理函数
1.$(addprefix PREFIX,NAMES…)
函数名称:加前缀函数—addprefix。
函数功能:为“NAMES…”中的每一个文件名添加前缀“PREFIX”。参数“NAMES…”是空格分割的文件名序列,将“SUFFIX”添加到此序列的每一个文件名之前。
返回值:以单空格分割的添加了前缀“PREFIX”的文件名序列。示例:$(addprefixsrc/,foobar)返回值是“src/foosrc/bar”。2.$(wildcard PATTERN)
- INCLUDE_DIR=usr/java/jdk1.8.0_25/include \
- usr/java/jdk1.8.0_25/include/linux
- INCLUDE_FLAG=$(addprefix -I,${INCLUDE_DIR})
- all:
- ls ${INCLUDE_FLAG}
函数名称:获取匹配模式文件名函数—wildcard
函数功能:列出当前目录下所有符合模式“PATTERN”格式的文件名。
返回值:空格分割的、存在当前目录下的所有符合模式“PATTERN”的文件名。
函数说明:“PATTERN”使用shell可识别的通配符,包括“?”(单字符)、“*”(多字符)等。三、其它函数。
三、其它函数
1.$(foreach VAR,LIST,TEXT)
函数功能:函数“foreach”不同于其它函数。它是一个循环函数。
类似于Linux的shell中的循环(for语句)。这个函数的工作过程是这样的:如果必要(存在变量或者函数的引用),首先展开变量“VAR”和“LIST”;
而表达式“TEXT”中的变量引用不被展开。执行时把“LIST”中使用空格分割的单词依次取出赋值给变量“VAR”,然后执行“TEXT”表达式。重复直
到“LIST”的最后一个单词(为空时结束)。“TEXT”中的变量或者函数引用在执行时才被展开,因此如果在“TEXT”中存在对“VAR”的引用,那
么“VAR”的值在每一次展开式将会到的不同的值。
返回值:空格分割的多次表达式“TEXT”的计算的结果。
names := a b c dfiles := $(foreach n,$(names),$(n).o)
上面的例子中,$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根 据“$(n)”计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,
$(files)的值是“a.o b.o c.o d.o”。
注意,foreach中的<var>参数是一个临时的局部变量,foreach函数执行完后,参数 <var>的变量将不在作用,其作用域只在 foreach 函数当中。
2.shell函数(不同于除“wildcard”函数之外的其它函数。make可以使用它来和外部通信)
函数功能:函数“shell”所实现的功能和shell中的引用(``)相同。它和 反引号“`”是相同的功能。这就是说,shell函数把执行操作系统命令后的输出作为函数
返回。于是,我们可以用操作系统命令以及字符串处理命令awk,sed等等命令来生成 一个变量,如:
contents := $(shell cat foo)
files := $(shell echo *.c)
函数说明:函数本身的返回值是其参数的执行结果,没有进行任何处理。对结果的处理是由make进行的。当对函数的引用出现在规则的命令行中,命令行在执行
时函数引用才被展开。展开过程函数参数的执行时在另外一个shell进程中完成的,因此对于出现在规则命令行的多级“shell”函数引用需要谨慎处理,
否则会影响效率(每一级的“shell”函数的参数都会有各自的shell进程)。
注意,这个函数会新生成一个Shell程序来执行命令,所以你要注意其运行性能,如果 你的Makefile中有一些比较复杂的规则,并大量使用了这个函数,那么对于你的系统
性能是有害的。特别是Makefile的隐晦的规则可能会让你的shell函数执行的次数比你 想像的多得多。
CC = gcc
#CC = /opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-gcc
CFLAGS = -g -Wall -O3
#CFLAGS += -DSIPSI_DEBUG
#LDFLAGS = -lrt -lz
COMPILE = $(CC) $(CFLAGS) -c
LINKCC = $(CC) $(LDFLAGS)
SUBDIR := \
../src
INC := \
-I../include \
-I../src
LIB := \
SRC := $(wildcard $(SUBDIR)/*.c)
OBJDIR := ../obj
OBJS := $(patsubst %.c, %.o, $(SRC))
PRGM = sipsi_bat_parser
all: $(PRGM)
$(PRGM): $(OBJS)
@echo ""
@echo "link $^ ==> $@"
@$(LINKCC) $(OBJS) $(LIB) -o $(PRGM)
$(OBJS):%.o:%.c
@echo ""
@echo "compiling $< ==> $@"
@$(COMPILE) $(INC) -c $< -o $@
.PHONY: clean
clean:
@echo "do cleaning..."
rm -f $(PRGM) $(OBJS)
记录一些makefile 的规则、变量函数使用
最新推荐文章于 2023-05-20 23:33:03 发布