zoukankan      html  css  js  c++  java
  • Makefile学习之路6————通过函数增强功能

    通过函数能显著增强Makefile的功能。对于simple项目的Makefile,尽管使用了模式规则,但还是有一件比较麻烦的事情,就是要在Makefile中指明每一个项目源文件。下面介绍几个后期会使用到的函数,更多请参考《GUN Make》。

    1.abspath函数

    从命名就应该能够猜出它的作用。abspath函数用于将_name中的各路径名转化成绝对路径,并将转化后的结果返回。调用形式为:

    $(abspath _name)

    .PHONY: all
     root :=$(abspath /uer/../lib)
     all:
         @echo $(root)
    

     

    2.addprefix函数

    addprefix函数用于给名字列表_names中的每一个名字增加前缀_prefix,并将增加了前缀的名字列表返回,调用形式为:

    $(addprefix _prefix, _names)

     .PHONY: all
     without_dir=main.c foo.c
     with_dir :=$(addprefix objs/,$(without_dir))
     all:
         @echo $(with_dir)
    

    3.addsuffix函数

    和前面addprefix刚好相反,addsuffix函数用于给名字列表_names中的每一个名字增加后缀_suffix,调用形式为:

    $(addsuffix _suffix, _names)

     .PHONY: all
     without_dir=main foo
     with_dir :=$(addsuffix .c,$(without_dir))
     all:
         @echo $(with_dir)
    

    4.filter函数

    filter函数被用于从一个名字列表_text中根据模式_patterm得到满足需要的名字列表并返回,其形式是:

    $(filter _pattern,_text) 

     .PHONY: all
     sources =foo.o bar.c main.c hell.s
    sources :=$(filter %.c %.s,$(sources)) all: @echo $(sources)

    从结果来看,调用filter函数后source变量中只存在.c文件和.s文件,而.o文件因为不满足所指定的模式而被过滤掉了。

    5.eval函数

    eval函数的存在使得Makefile具有动态语言的特征。eval函数使得make将再一次解析_text语句。eval返回空字符串,调用形式为:

    $(eval _text)

     .PHONY: all
     sources =foo.o bar.c main.c hell.s
     $(eval sources :=$(filter %.c %.s,$(sources)))
     all:
         @echo $(sources)
    

    虽然它和上面第四个函数运行结果完全一样,但是在某些场合却必须用eval。

    可参考:http://bbs.chinaunix.net/thread-2321462-3-1.html

    eval的二次展开,是递归的一种形式,因为有时候在Makefile的表达式中,最后得出来的可能还是Makefile的表达式而非真正我们想要传递的值,需要再展开Makefile的表达式得到最终的结果。

    6.filter-out函数

    该函数用于从名字列表_text中根据模式_pattern滤除一部分名字并将滤除后的列表返回,其形式为:

    $(filter-out _pattern,_text)

     .PHONY: all
     objs =foo.o main.o main1.o main2.o
     result :=$(filter-out main%.o,$(objs))
     all:
         @echo $(result)
    

     

    7.notdir函数

    该函数用来从路径_name中抽取文件名,并将文件名返回。其形式为:

    $(notdir _name)

     .PHONY: all
     file_name :=$(notdir c/d/e/f/a.c q/w/e/r/b.c)
     all:
         @echo $(file_name)
    

     

    8.patsubst函数

    该函数用来将名字列表_text中符合_pattern模式的名字替换成_replacement,并将替换后的名字列表返回。其形式为:

    $(patsubst _pattern,_replacement,_text)

     .PHONY: all
     mixed=foo.c bar.c main.o
     objs :=$(patsubst %.c,%.o,$(mixed))
     all:
         @echo $(objs)
    

    9.realpath函数

    该函数用于获取_name所对应的真实路径名。其形式为:

    $(realpath _name)

     .PHONY: all
     root :=$(realpath ./)
     all:
         @echo $(root)
    

     

    10.strip函数

    如果希望清除名字列表中的多余空格,strip函数是最佳选择,它将_string中的多余空格去除后返回。其形式为:

    $(strip _string)

    .PHONY: all
    ori=foo.c        main.c
    res:=$(strip $(ori))
    all:
        @echo "$(ori)"
        @echo "$(res)"

     

    这里对echo命令做了一点变动,细心的人已经发现加了一个双引号,如果不加双引号,这里的两个输出将是相同的。

    双引号用于保持引号内所有字符的字面值(回车和空格也不例外)。

    11.wildcard函数

    该函数是通配符函数,通过它可以得到当前工作目录中满足_pattern模式的文件或目录名列表。其形式为:

    $(wildcard _pattern)

     .PHONY:all
     srcs=$(wildcard *.c)
     all:
         @echo $(srcs)
    

      

    有了上面函数的基础之后,我们来看看之前的simple项目,对它进行改进:

    之前的代码:

    .PHONY: clean
    
    CC = gcc
    RM = rm
    
    EXE =simple
    OBJS =main.o foo.o
    
    $(EXE): $(OBJS)
        $(CC) -o $@ $^
    %.o : %.c
        $(CC) -o $@ -c $^
    clean:
        $(RM) -rf $(EXE) $(OBJS)

    还是要手动添加源文件,麻烦,运用函数之后,改进如下:

     

    .PHONY: clean
    
    CC = gcc
    RM = rm
    
    EXE =simple
    SRCS =$(wildcard *.c)
    OBJS =$(patsubst %.c, %.o, $(SRCS))
    $(EXE): $(OBJS)
        $(CC) -o $@ $^
    %.o : %.c
        $(CC) -o $@ -c $^
    clean:
        $(RM) -rf $(EXE) $(OBJS)
    

      

    此时我们增加一个源文件,touch bar.c,看看我们的Makefile需不需要修改。

    从结果看,不用修改Makefile就可以增加源文件了,同理,删除也一样,这样的Makefile具有更好的鲁棒性。 

       

     

  • 相关阅读:
    37. Sudoku Solver(js)
    36. Valid Sudoku(js)
    35. Search Insert Position(js)
    34. Find First and Last Position of Element in Sorted Array(js)
    33. Search in Rotated Sorted Array(js)
    32. Longest Valid Parentheses(js)
    函数的柯里化
    俞敏洪:我和马云就差了8个字
    vue路由传值params和query的区别
    简述vuex的数据传递流程
  • 原文地址:https://www.cnblogs.com/Liu-Jing/p/8270625.html
Copyright © 2011-2022 走看看