zoukankan      html  css  js  c++  java
  • Makefile系列之二 : 命令

    一、显示命令 echo
      “@”字符可以控制命令是否在屏幕上显示,如
        @echo 正在编译XXX模块...... 

      输出:

        正在编译XXX模块......

      如果没有“@"则输出 :

        echo 正在编译XXX模块......

        正在编译XXX模块......

    二、make参数

      下面列举了所有GNU make 3.80版的参数定义。
      1)make  “-n”或“--just-print”

        ——只显示命令,但不会执行命令。

      make  “-s”或“--slient”  

        ——全面禁止命令的显示。

      2)make  “-i”或“--ignore-errors”

        ——Makefile中所有命令都会忽略错误。而如果某规则是以“.IGNORE”作为目标的,那么该规则中的所有命令将会忽略错误。

      注意 : makefile是由许多规则组成,而规则又由目标、依赖及命令组成,每当命令运行完后,make会检测每个命令的返回码,如果命令返回成功,那么make会执行下一条命令,当规则中所有的命令成功返回后,这个规则就算是成功完成了。如果一个规则中的某个命令出错了(命令退出码非零),那么make就会终止执行当前规则,这将有可能终止所有规则的执行。而有些命令执行不成功并不会影响后续命令的执行,所以为了让命令继续执行,可以通过在命令前加“-”来忽略执行命令的错误,如

          clean:
            -rm -f *.o   #忽略删除文件时遇到的错误,让命令继续执行

      3)make “-w”或“--print-directory”

        ——会在make的过程中输出目前的工作目录的信息。比如,如果下级make目录是“/home/hchen/gnu/make”,当使用“make -w”来执行时,那么当进入该目录时,屏幕会输出

          make: Entering directory `/home/hchen/gnu/make'.
      而在完成下层make后离开目录时,屏幕会输出:
          make: Leaving directory `/home/hchen/gnu/make'
      当你使用“-C”参数来指定make下层Makefile时,“-w”会被自动打开的。如果参数中有“-s”(“--slient”)或是“--no-print-directory”,那么,“-w”总是失效的。

      4)“-b” “-m”
        ——这两个参数的作用是忽略和其它版本make的兼容性。
      5)“-B” “--always-make”
        ——认为所有的目标都需要更新(重编译)。
      6) “-C <dir>” “--directory=<dir>”
        ——指定读取makefile的目录。如果有多个“-C”参数,make的解释是后面的路径以前面的作为相对路径,并以最后的目录作为被指定目录。如:

          “make –C ~hchen/test –C prog” 等价于 “make –C ~hchen/test/prog”。

      7) “--debug[=<options>]”
        ——输出make的调试信息。它有几种不同的级别可供选择,如果没有参数,那就是输出最简单的调试信息。下面是<options>的取值:
          a —— 也就是all,输出所有的调试信息。(会非常的多)
          b —— 也就是basic,只输出简单的调试信息。即输出不需要重编译的目标。
          v —— 也就是verbose,在b选项的级别之上。输出的信息包括哪个makefile被解析,不需要被重编译的依赖文件(或是依赖目标)等。
          i —— 也就是implicit,输出所以的隐含规则。
          j —— 也就是jobs,输出执行规则中命令的详细信息,如命令的PID、返回码等。
          m —— 也就是makefile,输出make读取makefile,更新makefile,执行makefile的信息。
        “-d” 相当于 “--debug=a”。
      8)“-e” “--environment-overrides”
        ——指明环境变量的值覆盖makefile中定义的变量的值。
      9)“-f=<file>” “--file=<file>” “--makefile=<file>”
        ——指定需要执行的makefile。
      10) “-h” “--help”
        ——显示帮助信息。
      11)“-i” “--ignore-errors”
        ——在执行时忽略所有的错误。
      12)“-I <dir>” “--include-dir=<dir>”
        ——指定一个被包含makefile的搜索目标。可以使用多个“-I”参数来指定多个目录。
      13) “-j [<jobsnum>]” “--jobs[=<jobsnum>]”
        ——指同时运行命令的个数。如果没有这个参数,make运行命令时能运行多少就运行多少。如果有一个以上的“-j”参数,那么仅最后一个“-j”才是有效的。(注意这个参数在MS-DOS中是无用的)
      14) “-k” “--keep-going”
        ——出错也不停止运行。如果生成一个目标失败了,那么依赖于其上的目标就不会被执行了。
      15)“-l <load>” “--load-average[=<load]” “—max-load[=<load>]”
        ——指定make运行命令的负载。
      16)“-n” “--just-print” “--dry-run” “--recon”
        ——仅输出执行过程中的命令序列,但并不执行。
      17)“-o <file>” “--old-file=<file>” “--assume-old=<file>”
        ——不重新生成的指定的<file>,即使这个目标的依赖文件新于它。
      18)“-p” “--print-data-base”
        ——输出makefile中的所有数据,包括所有的规则和变量。这个参数会让一个简单的makefile都会输出一堆信息。如果你只是想输出信息而不想执行makefile,你可以使用“make -qp”命令。如果你想查看执行makefile前的预设变量和规则,你可以使用“make –p –f /dev/null”。这个参数输出的信息会包含着你的makefile文件的文件名和行号,所以,用这个参数来调试你的makefile会是很有用的, 特别是当你的环境变量很复杂的时候。
      19)“-q” “--question”
        ——不运行命令,也不输出。仅仅是检查所指定的目标是否需要更新。如果是0则说明要更新,如果是2则说明有错误发生。
      20)“-r” “--no-builtin-rules”
        ——禁止make使用任何隐含规则。
      21)“-R” “--no-builtin-variabes”
        ——禁止make使用任何作用于变量上的隐含规则。
      22)“-s” “--silent” “--quiet”
        ——在命令运行时不输出命令的输出。
      23)“-S” “--no-keep-going” “--stop”
        ——取消“-k”选项的作用。因为有些时候,make的选项是从环境变量“MAKEFLAGS”中继承下来的。所以你可以在命令行中使用这个参数来让环境变量中的“-k”选项失效。
      24)“-t” “--touch”
        ——相当于UNIX的touch命令,只是把目标的修改日期变成最新的,也就是阻止生成目标的命令运行。
      25)“-v” “--version”
        ——输出make程序的版本、版权等关于make的信息。
      26)“-w” “--print-directory”
        ——输出运行makefile之前和之后的信息。这个参数对于跟踪嵌套式调用make时很有用。
      27)“--no-print-directory”
        ——禁止“-w”选项。
      28) “-W <file>” “--what-if=<file>” “--new-file=<file>” “--assume-file=<file>”
        ——假定目标<file>需要更新,如果和“-n”选项使用,那么这个参数会输出该目标更新时的运行动作。如果没有“-n”那么就像运行UNIX的“touch”命令一样,使得<file>的修改时间为当前时间。
      29)“--warn-undefined-variables”
        ——只要make发现有未定义的变量,那么就输出警告信息。

    三、执行命令

      如果要让上一条命令的结果应用在下一条命令时,必须用分号分隔这两条命令。比如你的第一条命令是cd命令,如:
    示例一:
      exec:
        cd /home/hchen
        pwd
    示例二:
      exec:
        cd /home/hchen; pwd
      当执行“make exec”时,第一个例子中的cd没有作用,pwd会打印出当前的Makefile目录,而第二个例子中,cd就起作用了,pwd会打印出“/home/hchen”。

    四、命令包定义

      如果Makefile中出现一些相同命令序列,那么我们可以为这些相同的命令序列定义一个变量。定义这种命令序列的语法以“define”开始,以“endef”结束,如:
          define run-yacc
            yacc $(firstword $^)
            mv y.tab.c $@
          endef
       “run-yacc”是这个命令包的名字,不能与Makefile中的变量重名。在
    “define”和“endef”中的两行就是命令序列。这个命令包中的第一个命令是运行Yacc程序,因为Yacc程序总是生成“y.tab.c”的文件,所以第二行的命令就是把这个文件改改名字。
    五、嵌套执行make

      在一些大的工程中,我们会把我们不同模块或是不同功能的源文件放在不同的目录中,我们可以在每个目录中都书写一个该目录的Makefile,这有利于让我们的Makefile变得更加地简洁,而不至于把所有的东西全部写在一个Makefile中,这样会很难维护我们的Makefile,这个技术对于我们模块编译和分段编译有着非常大的好处。
      例如,我们有一个子目录叫subdir,这个目录下有个Makefile文件,来指明了这个目录下文件的编译规则。那么我们总控的Makefile可以这样书写:
          subsystem:
            cd subdir && $(MAKE)
      
    其等价于:
          subsystem:
            $(MAKE) -C subdir
      
    定义$(MAKE)宏变量可以让我们更方便地为make添加一些参数,这样比较利于维护。这两个例子的意思都是先进入“subdir”目录,然后执行make命令。
      
    我们把这个Makefile叫做“总控Makefile”,总控Makefile的变量可以传递到下级的Makefile中(如果你显式的声明),但是不会覆盖下层的Makefile中所定义的变量,除非指定了“-e”参数。
      如果你要传递变量到下级Makefile中,那么你可以使用这样的声明:
          export <variable ...>
      
    如果你不想让某些变量传递到下级Makefile中,那么你可以这样声明:
          unexport <variable ...>
      

          export variable = value
      其等价于:
          variable = value
          export variable
      其等价于:
          export variable := value
      传递所有的变量,那么,只要一个export就行了。后面什么也不用跟,表示传递所有的变量。
    六、检查规则

      1)不想makefile中的规则执行起来,只是检查一下命令或是执行的序列。
              
    “-n”
              “--just-print”
              “--dry-run”
              “--recon”
        不执行参数,这些参数只是打印命令,不管目标是否更新,把规则和连带规则下的命令打印出来,但不执行,这些参数对于我们调试makefile很有用处。
      
    2)

              “-t”
              “--touch”
        这个参数的意思就是把目标文件的时间更新,但不更改目标文件。也就是说,make假装编译目标,但不是真正的编译目标,只是把目标变成已编译过的状态。
      
    3)

              “-q”
              “--question”
        这个参数的行为是找目标的意思,如果目标存在,那么其什么也不会输出,当然也不会执行编译,如果目标不存在,其会打印出一条出错信息。
      
    4)

              “-W <file>”
              “--what-if=<file>”
              “--assume-new=<file>”
              “--new-file=<file>”
      这个参数需要指定一个文件。一般是是源文件(或依赖文件),Make会根据规则推导来运行依赖于这个文件的命令,一般来说,可以和“-n”参数一同使用,来查看这个依赖文件所发生的规则命令。

  • 相关阅读:
    Sharding-JDBC(三)3.1.0版本实践
    Sharding-JDBC(二)2.0.3版本实践
    Sharding-JDBC(一)简介
    Java并发(六)线程池监控
    Java并发(五)线程池使用番外-分析RejectedExecutionException异常
    Java并发(四)线程池使用
    Java并发(三)线程池原理
    Java并发(二)异步转同步
    tarjan+概率
    线段树(种树)
  • 原文地址:https://www.cnblogs.com/lovemo1314/p/3485303.html
Copyright © 2011-2022 走看看