博客
关于我
Makefile系列--语法相关
阅读量:510 次
发布时间:2019-03-07

本文共 5190 字,大约阅读时间需要 17 分钟。

其他网址

Makefile的$@,$^,$<,$?,%

另见《Makefile手册中文版》=>10.5.3 自动化变量

例:

test : a.o b.o    gcc -o test $^%.o: %.c   b.c    gcc -c -o $@ $< clean:    rm *.o test

$^   :  所有的依赖  

         //所有通过目录搜索得到的依赖文件的完整路径名(目录 + 一般文件名)列表。
           因为通过目录搜索得到的依赖文件可能会在其他目录。
$@  :  规则的目标文件(: 左边的文件,可以是任意文件,不是只可以是.o文件)
$<: 第一个依赖文件。//规则中通过目录搜索得到的依赖文件列表的第一个依赖文件
       例:a.o : a.c a.S
                   gcc -c -o $@ $<    则$<指的是a.c而不是a.S
$?   : 表示比目标还要新的依赖文件列表
%  :  对于本处来说,到test : a.o b.o时,会发现a.o没有,然后寻找规则的目标文件,找到了%.o与其对应,
    于是,%.o对应a.o,也就是%等于a,也就是:a.o : a.c,到b.o的时候也是这样进行。
 
注意:
1.实际上,生成.o文件时,用的命令一般就是gcc -c -o $@ $< ,用gcc -c -o $@ $^会报错,显示最后那个只能是一个文件。
  示例:a.c中用到了a.h和b.c,那么需要这样写:
           a.o : a.c a.h b.c
                 gcc -c -o $@ $<</div>
           表面上看,$<表示的是第一个依赖文件,也就是a.c,看起来没用到a.h和b.c。其实将上边写为:
            a.o : a.c
                  gcc -c -o $@ $<</div>
           也是可以的。但是,当只修改了a.h或者a.c的时候,直接make,第二种方法不能识别到依赖的更新,
          而第一种方法可以。

本处

$^指的就是a.o , b.o。
会对所有的.o文件(本处是a.o, b.o)分别执行gcc -c -o $@ $<,执行a.o时,$@对应a.o,$<对应a.c

下边这样是错误的,因为如果没有指定输出项目的时候Make会自动找到makefile中第一个目标中没有通配符的目标进行构造。

test : %.o    gcc -o test $^%.o: %.c   b.c    gcc -c -o $@ $<clean:    rm *.o test

Makefile的文本转化函数

其他makefile的函数见网页收藏:

"GNU Make 使用手册(中译版)(于凤昌)" => 8 文本转换函数 
"Makefile手册中文版"

一、字符串替换和分析函数

$(subst form,to,text)

   在文本"text"中使用"to"替换每一处的"from"
    例:$(subst ee,EE,feet on the street)   结果为:"fEET on the strEET"
$(patsubst pattern,replacement,text)
   寻找‘text'中符合格式‘pattern'的字,用‘replacement'替换它们.
    例:$(patsubst %.c,%.o,a.c.c bar.c)   结果为:‘a.c.o bar.o'
    注意:foo := a.c.c bar.c
            var  := $(foo:.c=.o)    #或者var :=$(foo:%.c=%.o) 能达到一样的效果。 
$(filter pattern...,text)
   返回在‘text'中由空格隔开且匹配格式‘pattern...'的字
    例:$(filter %.c,%.s,foo.c bar.c baz.s ugh.h)    结果为:‘foo.c bar.c baz.s'
$(filter-out pattern...,text)
   返回在‘text'中由空格隔开且不匹配格式‘pattern...'的字
    例:$(filter-out %.c,%.s,foo.c bar.c baz.s ugh.h)   结果为:'ugh.h'
$(strip string)
   去掉前导和结尾空格,并将中间的多个空格压缩为单个空格。
    例:$(strip a b c )    结果为‘a b c'。
   注意:函数strip和条件语句连用非常有用。当使用ifeq或ifneq把一些值和空字符串比较时,通常要将一些
            仅由空格组成的字符串认为是空字符串
$(findstring find,in)
   在字串in中查找find字串。如果找到,那么返回find,否则返回空字符串。
    例: $(findstring a,a b c)   返回值:"a"
$(sort list)
   给字符串list中的单词排序(升序)。
    例: $(sort foo bar lose) 返回值:"bar foo lose"。
    注意:sort 函数会去掉list中相同的单词。
$(word n,text)
   取字符串text中第n个单词。(从一开始)
    例: $(word 2, foo bar baz)  返回值:"bar"。
   注意:如果n比text中的单词数要大,那么返回空字符串
$(wordlist s,e,text)
   从字符串text中取从s开始到e的单词串。s和e是一个数字
    例:$(wordlist 2, 3, foo bar baz)    返回值是"bar baz"
$(words text)
    统计text中字符串中的单词个数。
    例:$(words, foo bar baz)     返回值是"3"。
   备注:如果我们要取text中最后的一个单词,我们可以这样:$(word $(words text),text)
$(firstword text)
    取字符串text中的第一个单词。
    例:$(firstword foo bar) 返回值是"foo"。
    注意:这个函数可以用 word 函数来实现:$(word 1,text)。

二、文件名函数

$(dir names...)

   抽取‘names'中每一个文件名的路径部分
    例:$(dir src/foo.c hacks)      结果为: 'src/ ./'。
$(notdir names...)
   抽取‘names'中每一个文件名中除路径部分外一切字符(真正的文件名)
    例:$(notdir src/foo.c hacks)   结果为:'foo.c hacks'。
$(wildcard pattern)
   通配符在规则中可以自动扩展,但变量中在函数的参数中通配符不能正常扩展。在这些场合扩展通配符,使用函数wildcard
    例:当前目录有a.c b.c b.h,c_src = *.c表示c_src就是'*.c',而c_src = $(wildcard *.c),则c_src = a.c b.c
$(suffix names...)
   从文件名序列names中取出各个文件名的后缀,如果文件没有后缀,则返回空字串
    例:$(suffix src/foo.c src-1.0/bar.c hacks)   返回值:".c .c"。
$(basename names...)
   返回文件名序列names的前缀序列,如果文件没有前缀,则返回空字串。
    例:$(basename src/foo.c src-1.0/bar.c hacks)  返回值:"src/foo src-1.0/bar hacks"。
$(addsuffix suffix,names...)
   把后缀suffix加到names中的每个单词后面。
    例:$(addsuffix .c,foo bar)    返回值:"foo.c bar.c"。
$(addprefix prefix,names...)
   把前缀prefix加到names中的每个单词后面
    例:$(addprefix src/,foo bar)  返回值:"src/foo src/bar"。
$(join list1,list2)
   把list2中的单词对应地加到list1的单词后面。如果list1的单词个数要比list2的多,那么,
   list1中的多出来的单词将保持原样。如果list2的单词个数要比list1多,那么,list2多出
    来的单词将被复制到list2中。
    例:$(join aaa bbb , 111 222 333)   返回值:"aaa111 bbb222 333"

三、其他函数

$(foreach var,list,text)

   前两个参数‘var'和‘list',首先扩展,‘text'此时不扩展;接着,对每一个‘list'扩展产生的字,将用来为'var'扩展后命名的变量赋值;
   然后‘text'引用该变量扩展;因此它每次扩展都不相同。结果是由空格隔开的‘text' 在‘list'中多次扩展的字组成的新的'list'。
   ‘text'多次扩展的字串联起来,字与字之间由空格隔开,如此就产生了函数foreach的返回值。
    例:
      dirs := a b c d
      files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))
     这里‘text'是‘$(wildcard $(dir)/*)'。
     第一个为变量dir发现的值是‘a',所以产生函数foreach结果的第一个字为‘$(wildcard a/*)';
     第二个重复的值是‘b',所以产生函数foreach结果的第二个字为‘$(wildcard b/*)';
     第三个重复的值是‘c',所以产生函数foreach结果的第三个字为‘$(wildcard c/*)';
     例子和下例有共同的结果:
      files := $(wildcard a/* b/* c/* d/*)

另外还有:$(if ...) $(value ...) $(eval ...) $(call ...)  $(origin ...)  $(shell ...),见"Makefile手册中文版"

.PHONY

test : a.o b.o    gcc -o test $^%.o : %.c    gcc -c -o $@ $<
clean: rm *.o test

若有一个clean文件,则已经有了目标文件,执行make clean就会失败。

解决方法: (用假想目标 .PHONY)
.PHONY: clean
// 此语句写在clean前边或者后边都可以。

Makefile的命令之前加@

通常,make会把其要执行的命令行在命令执行前输出到屏幕上。当我们用“@”字符在命令

行前,那么,这个命令将不被make显示出来,例:
@echo 正在编译XXX模块......
运行结果:
    正在编译XXX模块......
echo 正在编译XXX模块.....
运行结果:
    echo 正在编译XXX模块......
    正在编译XXX模块......
其他注意:
1. 如果make执行时,带入make参数“-n”或“--just-print”,那么其只是显示命令,但不会执行命令,这
    功能可用来调试Makefile
2. make参数“-s”或“--slient”可以全面禁止命令的显示。

:= , = , ?= , +=

:=     # 即时变量。例:  A := abc    # A的值即刻确定,在定义时即确定

=     # 延时变量。例:  B = 123    # B的值使用到时才确定
?=    # 延时变量, 如果是第1次定义才起效, 如果在前面该变量已定义则忽略这句
+=   # 附加, 它是即时变量还是延时变量取决于前面的定义
例1:

A := $(C)

B = $(C)
C = abc
all:
    @echo A = $(A)
    @echo B = $(B)
运行结果:
A =
B = abc
例2:

A := $(C)

B = $(C)
C = abc
all:
    @echo A = $(A)
    @echo B = $(B)
C = 123

运行结果:

A =
B = 123
例3:

A := $(C)

B = $(C)
C = abc
all:
    @echo A = $(A)
    @echo B = $(B)
C ?= 123
运行结果:
A =
B = abc

Makefile常用变量

详见《Makefile手册中文版》 => 搜索“GNU make环境变量”

MAKEFILES 
MAKEFILES_LIST 
VPATH 
SHELL 
MAKESHELL 
MAKE 
MAKELEVEL 
MAKEFLAGS 
MAKECMDGOALS 
CURDIR 
SUFFIXES 
.LIBPATTERNS 

转载地址:http://zgvjz.baihongyu.com/

你可能感兴趣的文章
MySQL 调优/优化的 101 个建议!
查看>>
mysql 转义字符用法_MySql 转义字符的使用说明
查看>>
mysql 输入密码秒退
查看>>
mysql 递归查找父节点_MySQL递归查询树状表的子节点、父节点具体实现
查看>>
mysql 通过查看mysql 配置参数、状态来优化你的mysql
查看>>
mysql 里对root及普通用户赋权及更改密码的一些命令
查看>>
Mysql 重置自增列的开始序号
查看>>
mysql 锁机制 mvcc_Mysql性能优化-事务、锁和MVCC
查看>>
MySQL 错误
查看>>
mysql 随机数 rand使用
查看>>
MySQL 面试题汇总
查看>>
MySQL 面试,必须掌握的 8 大核心点
查看>>
MySQL 高可用性之keepalived+mysql双主
查看>>
MySQL 高性能优化规范建议
查看>>
mysql 默认事务隔离级别下锁分析
查看>>
Mysql--逻辑架构
查看>>
MySql-2019-4-21-复习
查看>>
mysql-5.6.17-win32免安装版配置
查看>>
mysql-5.7.18安装
查看>>
MySQL-Buffer的应用
查看>>