LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: kingbo

makefile不支持子目录检查

[复制链接]
发表于 2008-1-25 19:30:25 | 显示全部楼层
$<@ 这个是什么意思?我从来没见过呀......或许是我孤陋寡闻?

source := *.c  这种形式是不会展开的
如果要在变量中展开通配符需要用到 wildcard 函数
比如:$(wildcard *.[ch])
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-1-25 23:24:56 | 显示全部楼层
$@是匹配的目标文件,$<是对应源文件

source := *.c 这种形式是不会展开的
你说的很对,所以应该用真实的源文件代入
回复 支持 反对

使用道具 举报

发表于 2008-1-25 23:45:14 | 显示全部楼层
晕,可你写的是 $<@

我的 make 笔记,借你用来快速参考吧
不过如果有时间的话,我还是建议你系统的学一下 make

参数
        make                        // If you have named your Makefile either Makefile or makefile, make will recognize it.
        make -f mymakefile
        make –p –f /dev/null        //查看执行 makefile 前的预设变量和规则
        make -n
       
        -B/--always-make                        //强制重新编译
        -C <DIRECTORY>                                // Change to DIRECTORY before doing anything.
        --debug[=FLAGS]
                FLAGS
                        a                // all,输出所有调试信息
                        b                // basic,只输出简单的调试信息;即输出不需要重编译的目标
                        i                // implicit,输出所有的隐含规则
                        j                // jobs,输出执行规则中命令的详细信息;如命令的 PID、返回码等
                        m                // makefile,输出 make 读取 makefile,更新 makefile,执行 makefile 的信息
                        v                // verbose,在 b 选项的级别之上
                                        // 输出的信息包括哪个 makefile 被解析,不需要被重编译的依赖文件(或是依赖目标)等
        -e/--environment-overrides        // Environment variables override makefiles.
                                                                //一般情况下,makefile 内部定义的变量覆盖外部传入的环境变量
        -i/--ignore-errors              // Ignore errors from commands.
        -k/--keep-going                 // Keep going when some targets can't be made.
        -l [N]                                                // Don't start multiple jobs unless load is below N.
                -l 2.5
        -n/--just-print                                //只是显示命令,但不会执行命令;用于调试 makefile 文件
        -q/--question                                // Run no commands; exit status says if up to date.
                                                                // Exit code 0 means need to update,2 means some error occured.
        -r/--no-builtin-rules                //禁止 make 使用任何隐含规则
        -R/--no-builtin-variabes        //禁止 make 使用任何作用于变量上的隐含规则
        -s/--silent/--quiet             // Don't echo commands.
        -t/--touch                                        //更新目标文件的时间,把目标变成已编译过的状态
        -w/--print-directory                   // Print the current directory.
        --no-print-directory
        -W <file>                                        // Make 会根据规则推导来运行依赖于这个文件的命令
                                                                //可以和 -n 参数一同使用,来查看这个依赖文件所发生的规则命令



退出码
        0                //成功执行
        1                //出现错误
        2                //如果你使用了 make 的 "-q" 选项,并且 make 使得一些目标不需要更新,那么返回 2



可能目标
        all                                //所有目标的目标,其功能一般是编译所有的目标
        check / test        //测试 makefile 的流程
        clean                        //删除所有被 make 创建的文件
        dist                        //创建一个压缩文件,一般是把tar文件压成 Z 文件
        distclean                //删除中间文件
        install                        //安装已编译好的程序,其实就是把目标执行文件拷贝到指定的目标中去
                make DESTDIR=/home/f95-build install
        print                        //列出改变过的源文件
        TAGS                        //更新所有的目标,以备完整地重编译使用
        tar                                //把源程序打包备份,也就是一个 tar 文件



示例
        Listing dependencies
                object = data.o main.o io.o
                project:    $(object)                   //第一个文件 project 是最终的生成文件
                        cc $(object) -o project                                //命令一定要以一个 Tab 键作为开头
                data.o:     data.c data.h                                //依赖关系,make 命令将比较文件的新旧关系以决定是否执行下面的生成动作
                        cc -c data.c                                                //生成动作
                main.o:     data.h io.h main.c
                        cc -c main.c
                io.o:       io.h io.c
                        cc -c io.c
                clean:                                  //如果后面没有文件,则将 clean 解释为动作,直接执行下面的命令
                        rm project $(object) *.o                        //注意:*.o 是 shell 通配符,并不是 make 的通配符

        依赖关系的自动推导
                object = data.o main.o io.o
                project:    $(object)                   //第一个段是默认目标
                        cc $(object) -o project
                data.o:     data.h                      // make 命令将自动推导出 data.c 文件,cc 命令也将被自动推导
                main.o:     data.h io.h main.c
                io.o:       io.h io.c
                .PHONY:     clean                       // .PHONY 表示,clean 是个伪目标文件
                clean:                                  //如果后面没有文件,则将 clean 解释为动作,直接执行下面的命令
                        -rm project $(object)

        变量应用技巧
                a_objects := a.o b.o c.o
                1_objects := 1.o 2.o 3.o
                sources := $($(a1)_objects:.o=.c)                //注意:变量 $al 是可以延迟定义的

        子 make 也使用多线程编译
                +make b=a c=g

        重载                        //使用默认变量进行重载
                foo:
                        frobnicate > foo
                %: force
                        @$(MAKE) -f Makefile $@
                force:;



变量展开时机                // IMMEDIATE 表示在第一阶段展开,DEFERRED 在第二阶段展开
        IMMEDIATE = DEFERRED

        IMMEDIATE ?= DEFERRED

        IMMEDIATE := IMMEDIATE

        IMMEDIATE += DEFERRED or IMMEDIATE                //如果此前这个变量是一个简单变量(使用 := 定义的)则认为它是立即展开的
                                                                                        //其它情况时都被认为是“延后”展开的变量

        define IMMEDIATE
        DEFERRED
        Endef

        IMMEDIATE: IMMEDIATE; DEFERRED
        DEFERRED



变量                //为了保证正确,变量的定义在任何情况下应该顶格写
        预设变量        //可用于隐含规则
                CFLAGS
                CPPFLAGS
                CXXFLAGS

        自动变量                //属于规则型变量,变量值依赖于规则的目标和依赖目标的定义
                $@                // Full name of the current target.
                        bigoutput littleoutput:         text.g
                                generate text.g -$(subst output,,$@) > $@                // $@ 表示 bigoutput littleoutput,"$@" 依次取出目标,并执于命令

                        bigoutput:         text.g
                                generate text.g -big > bigoutput
                        littleoutput:        text.g
                                generate text.g -little > littleoutput
                $%                //仅当目标是函数库文件的情况下,表示规则中的目标成员名
                $(<)          //依赖目标中的第一个目标名字
                $?          //所有比目标新的依赖目标的集合,以空格分隔
                        print: foo.c bar.c
                          lpr -p $?                //只打印出那些变化了的文件
                          touch print
                $^                //所有的依赖目标的集合,以空格分隔;如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份
                $+                //很像 $^ ,也是所有依赖目标的集合,只是它不去除重复的依赖目标
                $*                //表示目标模式中 % 及其之前的部分,如果目标是 dir/a.foo.b,并且目标的模式是 a.%.b,那么 $* 的值就是 dir/a.foo

                $@ $(<) $% $*        //扩展值只会有一个文件
                $? $^ $+                //扩展值是一个文件列表

                $(@D)                        //表示 $@ 的目录部分并不以斜杠作为结尾,如果 $@ 中没有包含斜杠的话,其值就是 . 当前目录
                $(@F)                        //表示 $@ 的文件部分,如果 $@ 值是 dir/foo.o,那么 $(@F) 就是 foo.o

        特殊变量                //属于全局变量,整个文件中都可以访问的到
                .LIBPATTERNS        //在规则中出现 -lNAME 格式的的依赖时,首先使用这里的 NAME 代替变量 .LIBPATTERNS 的第一个字的模式字符
                                                // % 而得到第一个库文件名根据这个文件名在搜索目录下查找,如果能够找到、就是用这个文件,
                                                //否则使用 NAME 代替第二个字的模式字符,进行同样的查找
                                                //查找目标时的优先级为:当前目录、VPATH vpath 指定的目录、系统默认目录 /lib /usr/lib /usr/local/lib
                        .LIBPATTERNS := lib%.a lib%.so
                .VARIABLES                //此引用点之前,makefile 文件中所定义的所有全局变量列表。包括:空变量(未赋值的变量)和 make 的内嵌变量

        变量
                GPATH                        //如果通过目录搜寻得到一个过时的(即需要被更新的)完整的目标文件路径名
                                                //而目标存在的目录又出现在 GPATH 变量的定义列表中,则该目标的完整路径将不废弃,目标将在该路径下被重建
                MAKE                        //变量 MAKE 的值是 make 程序的文件名以及 make 的启动选项
                                                //它所实现的功能和在规则中命令行首使用字符 + 的效果相同
                MAKECMDGOALS        //存放你所指定的终极目标的列表;如果在命令行上,你没有指定目标,那么这个变量是空值
                        sources = foo.c bar.c
                        ifneq ($(MAKECMDGOALS),clean)
                        include $(sources:.c=.d)
                        endif
                MAKEFILE_LIST        //可以获得刚才处理了哪一个 makefile 的信息
                        name1 := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
                        include inc.mk
                        name2 := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
                        all:
                                @        echo name1 = $(name1)
                                @        echo name2 = $(name2)
                        输出为:
                                name1 = Makefile
                                name2 = inc.mk
                MAKEFILES                //如果你的当前环境中定义了环境变量 MAKEFILES,那么,make 会把这个变量中的值做一个类似于 include 的动作
                MAKEFLAGS                //执行 make 时的命令行选项参数被通过一个变量 MAKEFLAGS 传递给子目录下的 make 程序
                                                //在主控执行 make 时使用 -k 和 -s 选项,那么 MAKEFLAGS 的值就为 "ks"
                        subsystem:                //如果不希望 MAKEFLAGS 的值传递给子 make,就需要在执行子 make 时对它重新进行赋值
                                cd subdir && $(MAKE) MAKEFLAGS=
                MAKELEVEL                //记录了当前 Makefile 的调用层数
                                                //最上一级时 MAKELEVEL 的值为 0,下一级时为 1,再下一级为 2
                SHELL                        // make 对所有规则命令的解析使用环境变量 SHELL 所指定的那个程序
                VPATH                        //依赖文件和目标文件搜索路径;当前目录拥有最高的搜索优先级
                                                // VPATH 会废弃目标完整路径名
                        VPATH = src:../headers



技巧
        执行命令
                exec:
                        cd /home/hchen
                        pwd                                                //每次命令的执行都从当前目录开始

                exec:;cd /home/hchen; pwd

        变量值替换
                $(var: <suffix>=<replacement>)        // $(patsubst %<suffix>,%<replacement>,$(var))
                        foo := a.o b.o c.o
                        bar := $(foo:.o=.c)
                $(var: <pattern>=<replacement>)        // $(patsubst <pattern>,<replacement>,$(var))

        指针
                x = y
                y = z
                a := $($(x))

                first_second = Hello
                a = first
                b = second
                all = $($a_$b)

        子模块的处理                //在使用 make 的递归调用时,在 Makefile 中规则的命令行中应该使用变量 MAKE 来代替直接使用 make
                SUBDIRS = foo bar baz
                .PHONY: subdirs $(SUBDIRS)
                subdirs: $(SUBDIRS)
                $(SUBDIRS):
                        $(MAKE) -C $@
                foo: baz                                //用于限制子模块的处理顺序



依赖对象                //依赖对象可以是普通文件、库文件、伪目标、空
                                //其中,伪目标总被认为是最新的,因为不存在与伪目标相对应的文件
                                //空则被认为是最旧的
                                //依赖对象的查找:VPATH 变量或者 vpath 命令指定
        foo : foo.c -lcurses                //如果 libcurses.a 需要在执行 make 的时生成,那么就不能这样写
                cc $^ -o $@



依赖规则                //注意:模式匹配只匹配文件名,并不匹配路径
        order-only 依赖                        // ORDER-ONLY-PREREQUISITES 仅仅用于产生目标,不作为更新 TARGET 的标准
                TARGETS: NORMAL-PREREQUISITES | ORDER-ONLY-PREREQUISITES

        Macro feature
                .SUFFIXES:  .C .f .c .o                // Gives a list of file extensions that will be used in the final compilation.
                        .f.o:                   // Show how to turn a file with a .f extension into a file with a .o extension.
                                        g77 -c $<       // Make absolutely certain you prefix each command line with a TAB character, not spaces.
                        .C.o:
                                        g++ -c $<
                        .c.o:
                                        gcc -c $<

        多目标                                        //每一个目标将被依次生成
                bigoutput littleoutput: text.g
                        generate text.g -$(subst output,,$@) > $@
                等价于
                bigoutput: text.g
                        generate text.g -big > bigoutput
                littleoutput: text.g
                        generate text.g -little > littleoutput

        静态模式                //限定了针对哪些 target 使用你给定的命令
                objects = foo.o bar.o
                $(objects): %.o: %.c
                        $(CC) -c $(CFLAGS) $< -o $@
                等价于
                foo.o:        foo.c
                        $(CC) -c $(CFLAGS) foo.c -o foo.o
                bar.o:        bar.c
                        $(CC) -c $(CFLAGS) bar.c -o bar.o

                files = foo.elc bar.o lose.o
                $(filter %.o, $(files)): %.o: %.c
                        $(CC) -c $(CFLAGS) $< -o $@
                $(filter %.elc, $(files)): %.elc: %.el
                        emacs -f batch-byte-compile $<

        双冒号规则                //一个目标可以出现在多个规则中,但是这些规则必须是同一种规则,要么都是普通规则,要么都是双冒号规则
                                        //当同一个文件作为多个双冒号规则的目标时,这些不同的规则会被独立的处理
                                        //而不是像普通规则那样合并所有的依赖到一个目标文件
                                        //对于一个没有依赖而只有命令行的双冒号规则,当引用此目标时,规则的命令将会被无条件执行
                                        //对于一个没有依赖而只有命令行的单引号规则,当引用此目标时,如果目标对象文件存在,则不执行
                                        //注意:双冒号规则不能用于生成 inlcude 的 makefile,因为那样会引起递归
                Newprog :: foo.c
                        $(CC) $(CFLAGS) $< -o $@
                Newprog :: bar.c
                        $(CC) $(CFLAGS) $< -o $@

        空命令
                %.obj:        .%.$(PROJECT_ID).obj;

        Target-specific-Variable
                <target ...> : <variable-assignment>
                        prog : CFLAGS = -g
                        prog : prog.o foo.o bar.o
                                $(CC) $(CFLAGS) prog.o foo.o bar.o
                        prog.o : prog.c
                                $(CC) $(CFLAGS) prog.c
                        foo.o : foo.c
                                $(CC) $(CFLAGS) foo.c
                        bar.o : bar.c
                                $(CC) $(CFLAGS) bar.c

                        %.o : CFLAGS = -O
                <target ...> : overide <variable-assignment>



通配符                //出现在 targets、prerequisites 中的通配符由 Make 展开,而出现在 commands 中的通配符由 shell 展开
                        //若想使用通配符所代表字符的原意,在它之前加上转义字符 \;比如 \? 表示问号,而非任意单个字符
                        //在规则中,通配符会被自动展开;但在变量的定义和使用函数时,通配符不会被自动的展开
                        //注意:只能表示单一的文件名
        ~                                 //当前用户的 home 目录
        ~zp                                //用户 zp 的 home 目录
        *.o                                //所有的目标文件
                print: *.c
                        lpr -p $?
                        touch print
        ?                                //单个字符
        [abc]                        // a 或 b 或 c
        [a-zA-Z]                //所有大小写字母
        [!0-9]                        //所有的非数字



赋值
        =        //这种定义允许使用未经地定义的变量的值,未经定义的变量的值是该变量的最终值
                foo = $(bar)
                bar = $(ugh)
                ugh = Huh?
                ugh = mm?
                all:
                        @echo $(foo)

        :=        //这种定义允许使用未经定义的变量的值,但是未经定义的变量的值是空
                y := $(x) bar
                x := foo

                empty:=
                space:= $(empty) $(empty)        //定义一个空格

        ?=
                FOO ?= bar        //如果 FOO 没有被定义过,那么变量 FOO 的值就是 "bar",如果 FOO 先前被定义过,那么这条语将什么也不做
                                        //注意:空值也算被定义过

        +=        //给变量追加值
                objects = main.o foo.o bar.o utils.o
                objects += another.o

                variable := value
                variable += more

                variable = value
                variable += more



内部命令
        define                //定义多行变量
                define two-lines        // two-lines 是变量名
                        echo foo                //命令必须以 [Tab] 键开头
                        echo $(bar)
                endef

                //该技术可以用于定义 "命令包"
                define run-yacc
                        yacc $(firstword $^)
                        mv y.tab.c $@
                endef

                foo.c:        foo.y
                $(run-yacc)

        export/unexport                //传递或者不传递变量到下级 Makefile
                                                // make 命令行带入的变量,或是系统环境变量默认 export
                                                //注意:SHELL、MAKEFLAGS 这两个变量不管你是否 export,总是要传递到下层 Makefile,因为它们是系统变量
                export variable = value
                export variable += value
                export                                //传递所有变量,在新版本的 GNU make 中取消了这一默认的行为,因此在编写和老版本 GNU                        
                                                        // make 兼容的 Makefile 时,需要使用特殊目标 .EXPORT_ALL_VARIABLES 来代替 export

        include
                include foo.make *.mk $(bar)                        //在 include 前面可以有一些空字符,但是绝不能是 [Tab] 键开始
                -include foo.make *.mk $(bar)                        // - 表示出错后不报错,无论命令成功与否都认为命令成功

                #        将当前目录下所有 flags 文件嵌入
            files_flags_exist := $(wildcard .*.flags)
          ifneq ($(files_flags_exist),)
          include $(files_flags_exist)
          endif

        override                //重新设置由命令行参数设置的变量以及系统环境变量
                override <variable> = <value>
                override <variable> := <value>
                override <variable> += <more text>

        vpath                        //只用于搜索依赖关系中的文件
                vpath <pattern> <directories>                        //为符合模式 <pattern> 的文件指定搜索目录 <directories>
                        vpath %.h ../headers                                        // "%" 是通配符
                vpath <pattern>                                                        //清除符合模式 <pattern> 的文件的搜索目录
                vpath                                                                        //清除所有已被设置好了的文件搜索目录



特殊目标
        .DEFAULT                        //一个文件作为某个规则的依赖,但却不是另外一个规则的目标时
                                                // Make 程序无法找到重建此文件的规则,就执行 ".DEFAULT" 所指定的命令

        .DELETE_ON_ERROR        //如果在 Makefile 中存在特殊目标 ".DELETE_ON_ERROR"
                                                //则规则的命令执行错误,将删除已经被修改的目标文件

        .EXPORT_ALL_VARIABLES        //此目标应该作为一个简单的没有依赖的目标,它的功能含义是将之后所有的变量传递给子 make 进程

        .IGNORE                                //如果给目标 .IGNORE 指定依赖文件,则忽略创建这个文件所执行命令的错误;给此目标指定命令是没有意义的
                                                //当此目标没有依赖文件时,将忽略所有命令执行的错误

        .INTERMEDIATE                //目标 .INTERMEDIATE 的依赖文件在 make 时被作为中间过程文件对待

        .LOW_RESOLUTION_TIME        //目标 .LOW_RESOLUTION_TIME 的依赖文件被 make 认为是低分辨率时间戳文件
                .LOW_RESOLUTION_TIME: dst
                dst: src
                        cp -p src dst

        .NOTPARALLEL                // Makefile 中,如果出现目标 .NOPARALLEL,则所有命令按照串行方式执行,即使存在 make 的命令行参数 -j
                                                //但在递归调用的子 make 进程中,命令可以并行执行
                                                //此目标不应该有依赖文件,所有出现的依赖文件将被忽略

        .PHONY                                // .PHONY的作用:
                                                // 1.        告知 Make,该伪目标并不是真正的文件,不遵循由源代码生成目标文件的规则
                                                // 2.        告诉 Make,该伪目标始终需要被更新
                .PHONY:        clean
                clean:
                        rm *.o temp

                all:        prog1 prog2                        //伪目标同样可以作为 "默认目标",只要将其放在第一个;也可以为伪目标指定所依赖的文件
                .PHONY:        all
                prog1:        prog1.o utils.o
                        cc -o prog1 prog1.o utils.o
                prog2:        prog2.o
                        cc -o prog2 prog2.o

                .PHONY:                cleanall cleanobj cleandiff
                cleanall:        cleanobj cleandiff                //伪目标同样也可成为依赖
                        rm program
                cleanobj:
                        rm *.o
                cleandiff:
                        rm *.diff

        .PRECIOUS                        //通过伪目标保存中间临时文件
                .PRECIOUS %.o

        .SECONDARY                        //目标 .SECONDARY 的依赖文件被作为中间过程文件对待
                                                //没有任何依赖文件的目标 .SECONDARY 的含义是:将所有的文件作为中间过程文件



相等测试                //注意:ifdef、else、endif 等等不能以 [Tab] 开头
        ifdef                        //实际上是用于判断变量是不是空值
                ifdef do_sort
                        func := sort
                else
                        func := strip
                endif
                bar := a d b g q c
                foo := $($(func) $(bar))

                bar =
                foo = $(bar)        // foo 定义了

                foo =                        // foo 没有进行定义
        ifeq
                ifeq ($(CC),gcc)
                        $(CC) -o foo $(objects) $(normal_libs)
                endif

                ifeq ($(CC),gcc)
                        $(CC) -o foo $(objects) $(libs_for_gcc)
                else
                        $(CC) -o foo $(objects) $(normal_libs)
                endif
        ifneq
        ifndef



函数        //调用规则:$(<function> <arg1>,<arg2>,<arg3>),参数之间以 "," 分割;注意:空格不是乱加的
        shell 函数                                                                                //把执行操作系统命令后的输出作为函数返回
                                                                                                        //这个函数会新生成一个 Shell 程序来执行命令,所以你要注意其运行性能
                contents := $(shell cat foo)
                files := $(shell echo *.c)
        字符串处理函数
                filter <pattern...>,<text>                                        //以 <pattern> 模式过滤 <text> 字符串中的单词,保留符合模式 <pattern> 的单词
                                                                                                        //可以有多个模式
                        sources := foo.c bar.c baz.s ugh.h
                        foo: $(sources)
                        cc $(filter %.c %.s,$(sources)) -o foo
                filter-out <pattern...>,<text>                                //以 <pattern> 模式过滤 <text> 字符串中的单词,去除符合模式 <pattern> 的单词
                        objects=main1.o foo.o main2.o bar.o
                        mains=main1.o main2.o
                        $(filter-out $(mains),$(objects))
                findstring <find>,<in>                                                //在字串 <in> 中查找 <find> 字串;如果找到,那么返回 <find>,否则返回空字符串
                        $(findstring a,b c)
                firstword <text>                                                        //取字符串 <text> 中的第一个单词
                        $(firstword foo bar)
                patsubst <pattern>,<replacement>,<text>                //模式字符串替换函数;返回被替换过后的字符串
                        $(patsubst %.c,%.o,x.c.c bar.c)
                sort <list>                                                                        //给字符串 <list> 中的单词排序(升序);注意:会去掉 <list> 中相同的单词
                        $(sort foo bar lose)
                strip <string>                                                                //去掉 <string> 字串中开头和结尾的空字符
                        $(strip a b c)
                subst <from>,<to>,<text>                                        //字符串替换函数,返回被替换过后的字符串
                        $(subst ee,EE,feet on the street)
                        override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))
                wildcard                                                                        // make 支持三个通配符:"*"、"?"、"[...]"
                                                                                                        //注意:只在工作目录下展开
                        ~                                                                //当前用户的 $HOME 目录
                        objects = *.o                                        //不展开通配符 *
                        objects := $(wildcard *.[chS])        //展开通配符 *
                word <n>,<text>                                                                //取字符串 <text> 中第 <n> 个单词
                        $(word 2, foo bar baz)
                wordlist <n>,<m>,<text>                                                //从字符串 <text> 中取从 <n> 开始到 <m> 的单词串
                        $(wordlist 2, 3, foo bar baz)
                words <text>                                                                //统计 <text> 中字符串中的单词个数
                        $(words foo bar baz)
                        $(word $(words <text>),<text>)

        文件名操作函数
                addprefix <prefix>,<names...>        //把前缀 <prefix> 加到 <names> 中的每个单词前面
                        $(addprefix src/,foo bar)
                addsuffix <suffix>,<names...>        //把后缀 <suffix> 加到 <names> 中的每个单词后面
                        $(addsuffix .c,foo bar)
                basename <names...>                                //从文件名序列 <names> 中取出各个文件名的前缀部分;如果文件没有前缀,则返回空字符串
                        $(basename src/foo.c src-1.0/bar.c hacks)
                dir <names...>                                        //从文件名序列 <names> 中取出目录部分
                                                                                //目录部分是指最后一个反斜杠 "/" 之前的部分;如果没有反斜杠,那么返回 "./"
                        $(dir src/foo.c hacks)
                join <list1>,<list2>                        //把 <list2> 中的单词对应地加到 <list1> 的单词后面
                        $(join aaa bbb , 111 222 333)        //返回值: "aaa111 bbb222 333"
                notdir <names...>                                //从文件名序列 <names> 中取出非目录部分;非目录部分是指最后一个反斜杠 "/" 之后的部分
                        $(notdir src/foo.c hacks)
                suffix <names...>                                //从文件名序列 <names> 中取出各个文件名的后缀;如果文件没有后缀,则返回空字符串
                        $(suffix src/foo.c src-1.0/bar.c hacks)

        其它函数
                call <expression>,<parm1>,<parm2>,<parm3>...
                        reverse = $(1) $(2)                        // $(1) 是位置参数
                        foo = $(call reverse,a,b)
                error <text ...>                                //输出错误信息并退出
                        ifdef ERROR_001
                        $(error error is $(ERROR_001))                //注意:不能顶格书写,会被当作命令处理
                        endif

                        ERR = $(error found an error!)
                        .PHONY: err
                        err: ; $(ERR)                                        //注意:makefile 中的变量其实是宏;即使用缓式评估策略
                foreach <var>,<list>,<text>                // foreach 中的 <var> 参数是一个临时的局部变量,其作用域只在 foreach 函数当中
                                                                                // foreach 函数执行完后,参数 <var> 的变量将不在作用
                        names := a b c d
                        files := $(foreach n,$(names),$(n).o)        //返回值: "a.o b.o c.o d.o"
                if <condition>,<then-part>                // <condition> 参数返回的为非空字符串,那么这个表达式就相当于返回真
                if <condition>,<then-part>,<else-part>
                origin <variable-name>
                        ifeq "$(origin bletch)" "environment"

                        返回值
                                automatic                //自动化变量
                                command line        //变量是被命令行定义的
                                default                        //默认变量
                                environment                //环境变量,并且当 Makefile 被执行时,"-e" 参数没有被打开
                                file                        //变量被定义在 Makefile 中
                                override                //变量被 override 指示符重新定义
                                undefined                //没有定义过
                warning <text ...>                                //输出警告信息并退出
回复 支持 反对

使用道具 举报

发表于 2008-1-26 03:55:57 | 显示全部楼层
Post by kingbo;1810646
这里没有人有义务帮助你,更没有人有义务按照你希望的方式帮助你。问个问题还牛逼轰轰的……
又是老样子的话,听多了,要起茧了.......

我的意思很明白,就是不要误导新人,不想回答的真的路过就行
很多问题都是问了又答,答了又问的,要不google没那么容易找得到解决方法,所以也不要那么烦燥,真的对身体不好
我不是高手但也不是新手了,摸了这么多年的linux,想来这牛脾气也多多少少跟前辈们有点关系,现在走向编程,又开始问些新手问题看来是要得罪不少人了,还请多多原谅


你让人烦的并非你所问的问题,而是你问问题的口气。这跟你用了多长时间的linux无关,这种语气放在哪都让人气愤:好心回答你的帖子,还被你说成误导。

好了,你的帖子,我再也不会回了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表