记录一些makefile 的规则、变量函数使用

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”。

  
  
  1. INCLUDE_DIR=usr/java/jdk1.8.0_25/include \  
  2.     usr/java/jdk1.8.0_25/include/linux  
  3. INCLUDE_FLAG=$(addprefix -I,${INCLUDE_DIR})  
  4.   
  5. all:  
  6.     ls ${INCLUDE_FLAG} 
2.$(wildcard PATTERN)
函数名称:获取匹配模式文件名函数—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 d

files := $(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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值