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

来源:互联网 发布:win10 64位安装mysql 编辑:程序博客网 时间:2024/05/16 09:16
http://blog.sina.com.cn/s/blog_b3dc8bf301017e8g.htmlmakefile是一个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)

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 喝了红牛睡不着怎么办 球球大作战总是闪退怎么办解决方法 球球大作战手机号己绑定怎么办 弄的底窝中药味太大怎么办 锤子手机上不了网怎么办 ppt没保存就卡了怎么办 ppt卡了没保存怎么办 匡威鞋舌头跑偏怎么办 霍尼韦尔dcs cb锁死怎么办 谷歌身份验证器丢失 怎么办 叛乱2手雷没了怎么办 王者转移号封了怎么办? 电脑被入侵挖矿怎么办 我把exe删除了怎么办 大学图书馆借书超过期限了怎么办 win10更新完鼠标没有了怎么办 打开软件提示运行出错怎么办 电脑中了u盘病毒怎么办 电脑中病毒自动重启怎么办 病毒软件不断发信息买服务怎么办 qq被腾讯屏蔽了怎么办 电脑被u盘中毒怎么办 电脑一分钟重启怎么办 创维电视音量小怎么办 捷豹pin码忘记了怎么办 华为手机版本更新下载不了怎么办? 微信钱包没有钱怎么办 微信钱包里没有钱怎么办 微信没有收到退款怎么办 微信转账退款没有收到怎么办 礼物跟人家送重复怎么办 你已被steam封禁怎么办 武装突袭3被锁定怎么办 绝地求生右下角小地图变大怎么办 ctrl z 误删了怎么办 武装突袭3渴了怎么办 武装突袭3枪卡壳怎么办 玩武装突袭3CPU不好怎么办? 户户通001信号中断怎么办 电脑运行速度特别慢怎么办 win8.1电脑太卡怎么办