zoukankan      html  css  js  c++  java
  • Makefile小结

    Makefile最基本的规则:target....:prerequisites.....

                                    command

                              或:target....:prerequisites.....;command

    target:目标文件,prerequisites:依赖文件,command:要执行的操作。命令太长可以使用“”来换行不断行,其中的命令使用UNIX的标准shell,/bin/sh来执行。

                                              基本等同于直接在terminal中输入命令的效果。

    伪目标一般指不需要依赖文件的一类目标,可以使用“.PHONY”来显式的指出。

    Makefile中的注释以“#”开头,命令以“[Tab]键开头”。注意加注释时,不要直接加在变量定义后边,因为这是Makefile会将空格也计算在变量内。

    Makefile默认会将第一个目标设置为最终的目标。 

    在命令行输入make命令时,默认会在当前目录按“GNUmakefile”,“makefile”,“Makefile”的文件来顺序搜索。如果需要指定特定的Makefile,可以使用make的参数

                 “-f”,"--file"。在Makefile中可以使用“include”关键字将别的Makefile包含进来。在include前加“-”号,可以让make继续执行,而不论文件是否能读取

        所有的make命令之前加-号,都是忽略函数返回值的。   -rm -rf ./

    makefile中的include,有三种形式,

    1) include,  2) -include,3) sinclude,sinclude与-include类似,但是兼容性好一些。

    Makefile中调用include的方式:

    1) 首先在当前或者指定的目录下寻找被调用文件;

    2) 如果没有找到,从-I所指定的include目录中寻找,

    3) 仍然没有找到,makefile试图寻找匹配规则来生成对应的文件

      常见的应用模式,生成dependence文件 .d文件:

      sinclude $(SOURCE:.c = .d)  #include .d文件:

      %.d:%.c

        @set -e;

        $(CC) -MM $(INC_FLAG) $(DEF_FLAG) $< > $@.$$$$;

    环境变量MAKEFILES,make会把这个变量的值做成一个类似include的动作,其中有一个区别是,从这个环境变量引入的Makefile的目标不会被识别。这个变量中的值,

                用空格分隔。

    make中的命令执行时,如果需要之后的一条命令,在前一条的基础上执行,则这两条命令必须写在同一行上,并且用分号隔开

        exec:

          cd /home/hchen;   pwd;

    在描述Makefile中的规则时,make支持三种通配符“*”,“?”,“[...]”

      objects = *.o

      当变量中定义了通配符时,makefile并不会展开,变量的值就是*.o

      objects := $(wildcard *.o)

      需要展开时,需要加入wildcard关键字,这时,变量中的值就是所有.o文件的集合

    在寻找目标文件和依赖文件的时候,在当前文件中找不到的情况下,make命令会自动搜索“VPATH”所指定的路径。“VPATH”变量中的值用“冒号”分隔。

      VPATH = src:../headers

      makefile会按顺序,一次搜索./src文件夹和../headers文件夹;

    Makefile还有一种关键字“vpath”,用来指定符合模式的文件的所搜路径。 Eg  vpath %.c ../foo   makefile会在../foo中搜索所有的.c文件

    静态模式:<targets...>:<target-pattern>:<prereq-patterns....>

                  <command>

    适用于使用“%”来定义一个目标集模式。prereq-patterns一般也是用“%”来表示某种依赖文件。

    可以有两个target,相同的依赖关系以及操作;

      bigoutput  littleoutput : text.g

        generate text.g -$(subst  output, , $@) > $@

    $@中有几个目标,便等同于几个target

    -MM自动生成依赖关系,gcc -MM main.c文件

    Makefile中的变量,是大小写敏感的,传统的Makefile的变量名全是大写的命名方式。变量在声明时需要给予初值,在使用时,需要在前边加上“$”符号。可以用“()”

               和“{}”来括起变量。如果要表示真实的“$”字符,需要使用“$$”表示。

    几种定义方式:A=1234

                        A:=1234    前边的变量不能使用后边才定义的变量,这样防止上一种定义方式可能发生的变量嵌套时的死锁。

                        A?=1234    如果A前边没有定义过,这条语句才会有效。

                        A+=1234    为变量A追加值,以空格隔开,如果变量之前有定义,“+=”会自动继承前次操作的赋值符。“=” “:=” "+="

    如果有变量是通过命令行参数来定义的,同时Makefile内部也对它进行了定义,则默认忽略Makefile中的定义。除非加“override”关键字在变量定义时

      对变量列表中的变量可以直接进行替换: $(sources:.c = .d)将之前source中的.c文件都替换为.d文件。

    Makefile中还有针对目标的变量和针对模式的变量。

    从terminal中将变量传入makefile, 直接make   var=2接口,makefile内部直接将var作为一个为赋值的变量就可以。该var的值也可以作为target,来从外部控制makefile流程。

    Makefile中的条件判断:make是在读取Makefile时就计算表达式的值,并根据条件表达式的值来选择语句,所以不应该吧自动化变量如($@)放在条件表达式中。

    1)ifeq, else, endif

    2)ifneq

    3)ifdef

    4)ifndef

    for循环:必须使用$$(),来调用循环变量。

    rule1:

      for i in $(SOURCE); do echo $$(i); done

    Makefile默认会将要执行的命令,在执行前输出到屏幕,当我们用“@”字符在命令前时,这个命令就不会被显示出来了用“-”在命令前,则该命令即使出现问题,make

               也不会退出。

    在Makefile中执行命令时,如果要让上一条命令的结果应用于下一条命令时,应该使用“分号”来分隔这两条命令。

              Eg: cd /home/hchen         cd /home/hchen;

                    pwd                          pwd

    在Makefile间传递变量,直接在当前环境生成环境变量,在定义变量时,使用“export”关键字。只加一个export后没有变量,则传递所有变量。如果有从命令过来的变量,Makefile会自动在嵌套式的

              Makefie中传递。也可以使用unexport来拒绝传递变量;

     Makefile中的字符串处理函数:函数调用与变量的使用很像,也是使用“$”来标识。

    1)$(subst <from>,<to>,<text>):字符串替换函数。

    2)$(patsubst <%from>,<%to>,<text>):模式字符串替换函数。

    3)$(strip <string>):去掉字符串的前后空格。

    4)$(findstring <fing>,<in>):查找字符串并返回。

    5)$(filter <pattern.....>, <text>):过滤函数,返回符合模式的单词。

    6)$(filter-out <pattern.....>, <text>):反过滤函数,返回不符合模式的单词。

    7)$(sort <list>):给字符串<list>中的单词排序,去除相同的单词。

    8)$(word <n>, <text>):取单词函数。

    9)$(wordlist <s>, <n>, <text>):取多个单词函数。

    10)$(words <text>):统计单词个数函数。

    11)$(firstword <text>):取首个单词函数。

    Makefile中的文件名操作函数:

    1)$(dir <name....>) 取目录函数,可以是多个数据的列表,返回多个。

    2)$(notdir <name....>) 取文件函数,与上一函数相反。

    3)$(suffix <name.....>) 取后缀函数,如文件后缀。

    4)$(basename <name....>) 取前缀函数,除了文件后缀的其他部分。

    5)$(addsuffix <suffix>, <name....>) 加后缀函数,加文件后缀。

    6)$(addprefix <prefix>, <name....>) 加前缀函数,加除了文件后缀之外的部分。

    7)$(join <list1>, <list2>) 连接函数,将<list2>的单词对应的加到<list1>的后边。

    Makefile中的其他函数:

    1)$(if <condition>, <then-part>, <else_part>)

    2)$(origin <variable>) 返回变量的来历

      返回值是固定的几个,undefined,default,file,command line,override,automatic,environment,

        一般用在变量是否被重新定义,override太过暴力,可以在来自env的进行重定义;

        ifeq “$(origin bletch)"  "environment"

          bletch = barf, 

    3)$(shell xxx) 引用UNIX的shell命令,与“反引号”作用相同。

      contents := $(shell  cat foo)

    4)$(error <text...>) 表示出现错误,打出text,退出。

    5)$(warning <text...>) 表示出现warning,打出text。

    6)   $(call <expression>, <param1>, <param2> ....)自定义一个参数化的函数

        reverse  = $(1) $(2)   ##首先自定义一个复杂的表达式

        foo = $(call reverse , a, b)  ##直接调用

        ##返回a b。

    Makefile中的参数“-w”或是“--print-directory”,在切换目录时,输出信息。

                           “-n”或是“--just-print",只打印出命令及其规则,但是不执行,适合调试。

                           “-C”或是“--directory”,指定读取makefile的目录。

            "-s" make时的参数,全面禁止命令的显示。

            “-i” 执行过程中,忽略所有的error;

            “-k” 执行过程中,一个target执行错误之后,执行其他的target;

    1)嵌套式的makefile,一般讲make和makefiag定义为变量,这样方便一些  make 参数的传递, 

    2)makefile中定义命令包,命名空间与变量相同,调用也相同;以define开头, endef结束;

       define run-yacc

        yacc $(firstword $^)

        mv y.tab.c $@

       endef

    自动化变量$@,表示规则中的目标文件集合,用于匹配目标模式中定义的集合;

         $<,依赖目标中的第一个目标的名字,如果依赖目标是以%来定义的,那么$< 表示符合模式的一系列的文件集合,是一一取出来的。

         $*,目标模式 %,及其之前的部分;

            %.d : %.c

              gcc $(INC_FLAG) -o $*.o  //其中的$*表示.d文件名  

    $(shell pwd | sed 's///');来进行目录的操作。

  • 相关阅读:
    关于Java中System.currentTimeMillis和System.nanoTime的错误认识
    多线程以外
    vim 小技巧
    Virtual Box HostOnly网络模式配置
    How 30 Minutes a Day Can Increase Your Intelligence
    YUM命令使用
    Hash算法及其应用
    jetty + apache httpd 反向代理配置
    使用SCTP优化网络
    .NET书籍推荐
  • 原文地址:https://www.cnblogs.com/-9-8/p/4468894.html
Copyright © 2011-2022 走看看