从头开始写项目Makefile(十):make内嵌函数及make命令显示【转】

转自:http://blog.csdn.net/shallnet/article/details/38314473#comments

版权声明:本文为博主原创文章,未经博主允许不得转载。如果您觉得文章对您有用,请点击文章下面“顶”。
   【版权声明:转载请保留出处:blog.csdn.net/gentleliu。Mail:shallnew at 163 dot com】
    这一节我们讲一下make的函数,在之前的章节已经讲到了几个函数:wildcard、patsubst、notdir、shell等。一般函数的调用格式如下:
$(funcname arguments)
或
$(funcname arguments)
其中funcname是需要调用函数的函数名称,应该是make内嵌函数;arguments是函数参数,参数和函数名之间使用空格分割,如果存在多个参数时,参数之间使用逗号“,”分开。函数调用以“$”开头,使用成对的圆括号或花括号把函数名和参数括起,一般使用圆括号。
下面来看一下常用的一些函数:
1.    获取匹配模式文件名函数—wildcard 。
用法:$(wildcard PATTERN)
该函数会列出当前目录下所有符合模式“PATTERN”格式的文件名。返回空格分割的、存在当前目录下的所有符合模式“PATTERN”的文件名。
例如:
[html] view plain copy

    SRC_FILES = $(wildcard src/*.c)  

返回src目录下所有.c文件列表。
2.    字符串替换函数—subst。
用法:$(subst FROM,TO,TEXT)
该函数把字串“TEXT”中的“FROM”字符替换为“TO”,返回替换后的新字符串。
3.    模式替换函数—patsubst。
用法:$(patsubst PATTERN,REPLACEMENT,TEXT)
该函数搜索“TEXT”中以空格分开的单词,将符合模式“TATTERN”替换为“REPLACEMENT” 。参数“PATTERN”中可以使用模式通配符“%”,来代表一个单词中的若干字符。如果参数“REPLACEMENT”中也包含一个“%” ,那么“REPLACEMENT”中的“%”将是“TATTERN”中的那个“%”所代表的字符串。
例如:
[html] view plain copy

    SRC_OBJ = $(patsubst %.c, %.o, $(SRC_FILES))  

将SRC_FILES中所有.c文件替换为.o返回给变量SRC_OBJ。
此函数功能类似之前讲过的变量替换,http://blog.csdn.net/shallnet/article/details/37529935
变量替换格式是“$(var:a=b)”或“${var:a=b}”,其意思是,把变量“var”中所有以“a”字串“结尾”的“a”替换成“b”字串。
例如我们存在一个代表所有.c 文件的变量。定义为“src_files = a.c b.c c.c” 。
为了得到这些.c文件所对应的.o源文件。如下两种使用可以得到同一种结果::
[html] view plain copy

    $(objects:.c=.o)
    $(patsubst %.c,%.o,$( src_files))  

4.    过滤函数—filter。
用法:$(filter PATTERN…,TEXT)
该函数过滤掉字串“TEXT”中所有不符合模式“PATTERN”的单词,保留所有符合此模式的单词。可以使用多个模式。模式中一般需要包含模式字符“%” 。存在多个模式时,模式表达式之间使用空格分割。返回空格分割的“TEXT”字串中所有符合模式“PATTERN”的字串。
5.    反过滤函数—filter-out。
用法:$(filter-out PATTERN...,TEXT)
和“filter”函数实现的功能相反。过滤掉字串“TEXT”中所有符合模式“PATTERN” 的单词, 保留所有不符合此模式的单词。 可以有多个模式。存在多个模式时,模式表达式之间使用空格分割。
6.    取目录函数—dir。
用法:$(dir NAMES…)
从文件名序列“NAMES…”中取出各个文件名的目录部分。文件名的目录部分就是包含在文件名中的最后一个斜线( “/” ) (包括斜线)之前的部分。返回空格分割的文件名序列“NAMES…”中每一个文件的目录部分。如果文件名中没有斜线,认为此文件为当前目录( “./” )下的文件。
7.    取文件名函数——notdir。
用法:$(notdir NAMES…)
从文件名序列“NAMES…”中取出非目录部分。目录部分是指最后一个斜线( “/” ) (包括斜线)之前的部分。删除所有文件名中的目录部分,只保留非目录部分。文件名序列“NAMES…”中每一个文件的非目录部分。
8.    取后缀函数—suffix。
用法:$(suffix NAMES…)
函数从文件名序列“NAMES…”中取出各个文件名的后缀。后缀是文件名中最后一个以点“.”开始的(包含点号)部分,如果文件名中不包含一个点号,则为空。 返回以空格分割的文件名序列“NAMES…”中每一个文件的后缀序列。
9.    取前缀函数—basename。
用法:$(basename NAMES…)
从文件名序列“NAMES…”中取出各个文件名的前缀部分(点号之后的部分) 。前缀部分指的是文件名中最后一个点号之前的部分。 返回空格分割的文件名序列“NAMES…”中各个文件的前缀序列。如果文件没有前缀,则返回空字串。

    这里仅仅讲到一些常用的函数,还有一些函数没有讲到,用到的时候可以去翻翻makefile手册。

    通常情况下make在编译时会打印出当前正在执行的命令,当编译链接选项很长时,会输出很多东西在屏幕上,如果我 不想再屏幕上看到很多东西,我们可以在命令前面加上@,这样命令就不会输出到屏幕了。我们这样尝试修改下:
[html] view plain copy

    # make
    make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/ipc'
    make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/ipc'
    make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/tools'
    make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/tools'
    make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/main'
    make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/main'
    #   

发现只有进入目录和退出目录的显示,这样很难知道目前编译过程。其实我们可以在规则命令处加入一行类似打印:
@echo "do something......"
这样可以输出目前正在做的事,又不会输出正在执行命令。现在将规则修改下如下:
[html] view plain copy

    $(OBJDIR) :
    >---@echo "   MKDIR $(notdir $@)..."
    >---@mkdir -p $@  

    ifneq ($(SRC_BIN),)
    $(BINDIR)/$(SRC_BIN) : $(SRC_OBJ)
    >---@echo "   LINK $(notdir $@)..."
    >---@$(CC) -o $@ $^ $(LDFLAGS)
    endif  

    ifneq ($(SRC_LIB),)
    $(LIBDIR)/$(SRC_LIB) : $(SRC_OBJ)
    >---@echo "    ARCHIVE $(notdir $@)..."
    >---@$(AR) rcs $@ $^
    >---@echo "    COPY $@ to $(SRC_BASE)/libs"
    >---@cp $@ $(SRC_BASE)/libs
    endif  

    $(SRC_OBJ) : $(OBJDIR)/%.o : %.c
    >---@echo "    COMPILE $(notdir $<)..."
    >---@$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@  

编译输出如下:
[html] view plain copy

    # make
    make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/ipc'
        COMPILE ipc.c...
        ARCHIVE libipc.a...
        COPY ../../build/unix_dbg/lib/libipc.a to ../../libs
    make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/ipc'
    make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/tools'
        COMPILE base64.c...
        COMPILE md5.c...
        COMPILE tools.c...
        ARCHIVE libtools.a...
        COPY ../../build/unix_dbg/lib/libtools.a to ../../libs
    make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/tools'
    make[1]: Entering directory `/home/Myprojects/example_make/version-3.1/src/main'
        COMPILE main.c...
       LINK target_bin...
    make[1]: Leaving directory `/home/Myprojects/example_make/version-3.1/src/main'
    #  

其中目录切换的输出仍然很多,我们可以将其关闭,这需要使用到make的参数,在make -C是指定--no-print-
directory参数。我们将顶层目录下Makefile规则修改如下:
[html] view plain copy

    $(BUILDDIR):
    >---@echo "    Create directory $@ ..."
    >---mkdir -p $(BUILDDIR)/bin $(BUILDDIR)/lib  

    $(MODULES):
    >---@$(MAKE) -C $(DIR)/$@ MODULE=$@ --no-print-directory  

    main:tools ipc  

    clean :
    >---@for subdir in $(MODULES); \
    >---do $(MAKE) -C $(DIR)/$$subdir MODULE=$$subdir $@ --no-print-directory; \
    >---done
    编译输出:
    # make
        COMPILE ipc.c...
        ARCHIVE libipc.a...
        COPY ../../build/unix_dbg/lib/libipc.a to ../../libs
        COMPILE base64.c...
        COMPILE md5.c...
        COMPILE tools.c...
        ARCHIVE libtools.a...
        COPY ../../build/unix_dbg/lib/libtools.a to ../../libs
        COMPILE main.c...
       LINK target_bin...
    # make clean
    rm -f  ../../build/unix_dbg/obj/ipc/ipc.o ../../build/unix_dbg/lib/libipc.a
    rm -f  ../../build/unix_dbg/obj/main/main.o ../../build/unix_dbg/bin/target_bin
    rm -f  ../../build/unix_dbg/obj/tools/base64.o  ../../build/unix_dbg/obj/tools/md5.o
    ../../build/unix_dbg/obj/tools/tools.o ../../build/unix_dbg/lib/libtools.a  

    #  

这样看上去输出清爽多了。其实我们也可以使用make -s 来全面禁止命令的显示。

 

时间: 2024-07-30 12:47:01

从头开始写项目Makefile(十):make内嵌函数及make命令显示【转】的相关文章

Makefile所有内嵌函数

一.文本处理函数以下是GNU make内嵌的文本(字符串)处理函数.1       $(subst FROM,TO,TEXT) 函数名称:字符串替换函数-subst. 函数功能:把字串"TEXT"中的"FROM"字符替换为"TO". 返回值:替换后的新字符串. 示例: $(subst ee,EE,feet on the street) 替换"feet on the street"中的"ee"为"E

php内嵌函数用法实例

 这篇文章主要介绍了php内嵌函数用法,实例分析了php内嵌函数的调用方法与使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了php内嵌函数用法.分享给大家供大家参考.具体分析如下: php中可以在函数内部内嵌一个函数,调用范围仅限于函数本身 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?php function msg() { echo("<center><

php 自己写扩展 内置函数 报错了 希望写过php扩展哥哥们来看些

问题描述 php 自己写扩展 内置函数 报错了 希望写过php扩展哥哥们来看些 PHP_FUNCTION(ccvita_string) { int *a; int argc = ZEND_NUM_ARGS(); int *result; if (zend_parse_parameters(argc TSRMLS_CC, "a", &a) == FAILURE) return; int i=0; int j; int t; for(i=0;i<10;i++) { for(j

关于js函数解释(包括内嵌,对象等)_javascript技巧

常用写法: function add(a,b) { return a + b; } alert(add(1,2)); // 结果 3 当我们这么定义函数的时候,函数内容会被编译(但不会立即执行,除非我们去调用它).而且,也许你不知道,当这个函数创建的时候有一个同名的对象也被创建.就我们的例子来说,我们现在有一个对象叫做"add"(要更深入了解,看底下函数:对象节.) 匿名函数: 我们也可以通过指派一个变量名给匿名函数的方式来定义它. var add = function(a,b) {

python 内部函数,以及lambda,filter,map等内置函数

1 #!/usr/bin/python 2 #encoding=utf-8 3 4 def back(): 5 return 1,2, "xxx" 6 7 #python 可变参数 8 def test(*param): 9 print "参数的长度是:%d" % len(param) 10 print "第二个参数是:%s" % param[1] 11 print "第一个参数是:%s" % param[0] 12 13 t

详解C++中的内联函数和函数重载_C 语言

内联函数(内嵌函数,内置函数) 调用函数时需要一定的时间和空间的开销.C++提供一种提高效率的方法,即在编译时将函数调用处用函数体替换,类似于C语言中的宏展开.这种在函数调用处直接嵌入函数体的函数称为内联函数(inline function),又称内嵌函数或内嵌函数. 指定内联函数的方法很简单,只需要在定义函数时增加 inline 关键字. 注意:是在函数定义时增加 inline 关键字,而不是在函数声明时.在函数声明时增加 inline 关键虽然没有错误,但是也没有任何效果 inline 关键

OpenGLES 如何在十天内掌握线性代数 - 希望这是真的!

OpenGLES 如何在十天内掌握线性代数 - 希望这是真的! 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 以下网易公开课相比较而言,可汗学院的视频更基础一些.字幕翻译也都不错,网易精品来着

我是怎样在十天内把百度权重1做到4的

  我是做医疗网站优化的,每天上班之前总喜欢查下,百度收录情况,还有排名,我只是站长大众里的一员,这篇文章也没什么有质量的话主要是和大家分享一下我的网站仅仅不到十天,百度权重从1到4的,到底我是怎么做的,下面我会详细的说下.毕竟谈的不是高质量的SEO知识,都是一些我的操作步骤,还请老生们,口下留德. 下面截张图给大家,希望大家看好快照日期,因为我的网站快照每天都是更新的,下面这两张图片,就很能证明,这个网站的权重和流量是在十天内上升起来的的.   其实呢,提升百度权重方法是很简单的,也没什么技巧

android studio 问题-android studio 写项目问题

问题描述 android studio 写项目问题 各位大神AS的项目包名命名格式是怎么样的 头一次用AS 求图 解决方案 Android Studio导入项目的问题Android Studio 编码设置,解决Android Studio项目运行时乱码问题用android studio导入项目的常见问题 解决方案二: 写包名按正常公司网址写就可以,项目创建后会自动变为和eclipse一样的倒序 解决方案三: 一般别用中文,就是字母和数字(别数字开头),有公司就写公司名倒着.