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

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

    1.abspath函数

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

    $(abspath _name)

    1 .PHONY: all
    2 root :=$(abspath /uer/../lib)
    3 all:
    4     @echo $(root)

    2.addprefix函数

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

    $(addprefix _prefix,_name)

    1 .PHONY: all
    2 without_dir=main.c foo.c
    3 with_dir :=$(addprefix objs/,$(without_dir))
    4 all:
    5     @echo $(with_dir)

    3.addsuffix函数

    和前面addprefix刚好相反,addsuffix函数为_name增加后缀_suffix,调用形式为:

    $(addsuffix _suffix,_name)

    1 .PHONY: all
    2 without_dir=main foo
    3 with_dir :=$(addsuffix .c,$(without_dir))
    4 all:
    5     @echo $(with_dir)

    4.filter函数

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

    $(filter _pattern,_text)

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

    5.eval函数

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

    $(eval _text)

    1 .PHONY: all
    2 sources =foo.o bar.c main.c hell.s
    3 $(eval sources :=$(filter %.c %.s,$(sources)))
    4 all:
    5     @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)

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

    7.notdir函数

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

    $(notdir _name)

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

    8.patsubst函数

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

    $(patsubst _pattern,_replacement,_text)

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

    9.realpath函数

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

    $(realpath _name)

    1 .PHONY: all
    2 root :=$(realpath ./)
    3 all:
    4     @echo $(root)

    10.strip函数

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

    $(strip _string)

    1 .PHONY: all
    2 ori=foo.c        main.c
    3 res:=$(strip $(ori))
    4 all:
    5     @echo "$(ori)"
    6     @echo "$(res)"

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

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

    11.wildcard函数

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

    $(wildcard _pattern)

    1 .PHONY:all
    2 srcs=$(wildcard *.c)
    3 all:
    4     @echo $(srcs)

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

    之前的代码:

     1 .PHONY: clean
     2 
     3 CC = gcc
     4 RM = rm
     5 
     6 EXE =simple
     7 OBJS =main.o foo.o
     8 
     9 $(EXE): $(OBJS)
    10     $(CC) -o $@ $^
    11 %.o : %.c
    12     $(CC) -o $@ -c $^
    13 clean:
    14     $(RM) -rf $(EXE) $(OBJS)

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

     1 .PHONY: clean
     2 
     3 CC = gcc
     4 RM = rm
     5 
     6 EXE =simple
     7 SRCS =$(wildcard *.c)
     8 OBJS =$(patsubst %.c, %.o, $(SRCS))
     9 $(EXE): $(OBJS)
    10     $(CC) -o $@ $^
    11 %.o : %.c
    12     $(CC) -o $@ -c $^
    13 clean:
    14     $(RM) -rf $(EXE) $(OBJS)

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

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

  • 相关阅读:
    chrome手动同步书签
    MySQL(5.6/5.7版本)卸载方法
    Windows 搭建IIS+PHP+MySQL环境
    按照innode删除结点
    wsl区分大小win10不区分大小写解决方案
    Docker容器里的centos疑难杂症
    [UGUI]源码调试和修改
    [UnityAPI]EditorWindow类 & Editor类
    [UnityAPI]Selection类
    [Lua]require
  • 原文地址:https://www.cnblogs.com/yangguang-it/p/6752998.html
Copyright © 2011-2022 走看看