分享

makefile 自用经验总结

 fengr85 2011-06-11

$(subst <from>,<to>,<text>)

    名称:字符串替换函数——subst。
    功能:把字串<text>中的<from>字符串替换成<to>。
    返回:函数返回被替换过后的字符串。

    示例:
       
        $(subst ee,EE,feet on the street),
       
        把“feet on the street”中的“ee”替换成“EE”,返回结果是“fEEt on the strEEt”。


$(patsubst <pattern>,<replacement>,<text>)

    名称:模式字符串替换函数——patsubst。
    功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹 配的话,则以<replacement>替换。这里,<pattern>可以包括通配符“%”,表示任意长度的字串。如 果<replacement>中也包含“%”,那么,<replacement>中的这个“%”将 是<pattern>中的那个“%”所代表的字串。(可以用“\”来转义,以“\%”来表示真实含义的“%”字符)
    返回:函数返回被替换过后的字符串。

    示例:

        $(patsubst %.c,%.o,x.c.c bar.c)

        把字串“x.c.c bar.c”符合模式[%.c]的单词替换成[%.o],返回结果是“x.c.o bar.o”

    备注:

        这和我们前面“变量章节”说过的相关知识有点相似。如:

        “$(var:<pattern>=<replacement>)”
         相当于
        “$(patsubst <pattern>,<replacement>,$(var))”,

         而“$(var: <suffix>=<replacement>)”
         则相当于
         “$(patsubst %<suffix>,%<replacement>,$(var))”。

         例如有:objects = foo.o bar.o baz.o,
         那么,“$(objects:.o=.c)”和“$(patsubst %.o,%.c,$(objects))”是一样的。

$(dir <names...>)

    名称:取目录函数——dir。
    功能:从文件名序列<names>中取出目录部分。目录部分是指最后一个反斜杠(“/”)之前的部分。如果没有反斜杠,那么返回“./”。
    返回:返回文件名序列<names>的目录部分。
    示例: $(dir src/foo.c hacks)返回值是“src/ ./”。

$(notdir <names...>)

    名称:取文件函数——notdir。
    功能:从文件名序列<names>中取出非目录部分。非目录部分是指最后一个反斜杠(“/”)之后的部分。
    返回:返回文件名序列<names>的非目录部分。
    示例: $(notdir src/foo.c hacks)返回值是“foo.c hacks”。
 
$(suffix <names...>)
   
    名称:取后缀函数——suffix。
    功能:从文件名序列<names>中取出各个文件名的后缀。
    返回:返回文件名序列<names>的后缀序列,如果文件没有后缀,则返回空字串。
    示例:$(suffix src/foo.c src-1.0/bar.c hacks)返回值是“.c .c”。

$(basename <names...>)

    名称:取前缀函数——basename。
    功能:从文件名序列<names>中取出各个文件名的前缀部分。
    返回:返回文件名序列<names>的前缀序列,如果文件没有前缀,则返回空字串。
    示例:$(basename src/foo.c src-1.0/bar.c hacks)返回值是“src/foo src-1.0/bar hacks”。

$(addsuffix <suffix>,<names...>)

    名称:加后缀函数——addsuffix。
    功能:把后缀<suffix>加到<names>中的每个单词后面。
    返回:返回加过后缀的文件名序列。
    示例:$(addsuffix .c,foo bar)返回值是“foo.c bar.c”。

$(addprefix <prefix>,<names...>)

    名称:加前缀函数——addprefix。
    功能:把前缀<prefix>加到<names>中的每个单词后面。
    返回:返回加过前缀的文件名序列。
    示例:$(addprefix src/,foo bar)返回值是“src/foo src/bar”。

foreach 函数

foreach函数和别的函数非常的不一样。因为这个函数是用来做循环用的,Makefile中的foreach函数几乎是仿照于Unix标准Shell(/bin/sh)中的for语句,或是C-Shell(/bin/csh)中的foreach语句而构建的。它的语法是:
  $(foreach <var>,<list>,<text>)
这个函数的意思是,把参数<list>中的单词逐一取出放到参数<var>所指定的变量中,然后再执行<text>所包含的表达式。每一次<text>会返回一个字符串,循环过程中,<text>的所返回的每个字符串会以空格分隔,最后当整个循环结束时,<text>所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。
  所以,<var>最好是一个变量名,<list>可以是一个表达式,而<text>中一般会使用<var>这个参数来依次枚举<list>中的单词。举个例子:

names := d
files := $(foreach n,$(names),$(n).o)
上面的例子中,$(name)中的单词会被挨个取出,并存到变量“n”中,“
$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后作为
foreach函数的返回,所以,$(files)的值是“a.o b.o c.o d.o”。


自用例子Makefile:

一、自动输出目录和lib库名称

版本一:

这个例子的作用是根据所提供的lib全路径, 自动分拆成为-L和-l,以供GCC编译时指定

MYLIBS = /lib/lib2.a
MYLIBS += /lib/lib3.a
MYLIBS += /lib/lib4.a libb.a
PP = $(sort $(foreach lb,$(MYLIBS),-l$(patsubst lib%.a,%,$(notdir $(lb))) -L$(dir $(lb))))
ps2:
    @echo $(PP)

结果输出:

$ make ps2
-L./ -L/lib/ -l2 -l3 -l4 -lb

函数使用说明:

foreach 用于将每个全路径转换为-L和-l

patsubst 模式替换用于生成-l,取出lib名称

dir用于生成-L

sort主要用于排序,更重要的作用是用于去除重名,当然如果由于库的引用的依赖关系,比如上面的库b必须引用库2,按照gcc的要求,库2必须放在库b的后面,那么上面的排序结果就不是我们所想要的。那么就只有去除sort函数的调用,直接使用foreach的返回结果即可。

版本二:

下面的代码克服了上面所说的sort引起的问题。

MYLIBS = /lib/lib2.a
MYLIBS += /lib/lib4.a libb.a
MYLIBS += /lib/lib3.a
PPPATH = $(sort $(foreach lb,$(MYLIBS),-L$(dir $(lb))))
PPNAME = $(foreach lb,$(MYLIBS),-l$(patsubst lib%.a,%,$(notdir $(lb))))
ps2:
    @echo $(PPPATH) $(PPNAME)

二、MAKEFILE变量引用与SHELL变量引用区别

如果要引用SHELL中export的变量,则应该使用$$NAME的方式进行,

如果要引用MAKEFILE中定义的变量则应该用$(NAME)的方式进行

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多