zoukankan      html  css  js  c++  java
  • makefile详解 嵌套执行make,定义命令包

    嵌套执行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 

            其等价于: 

            variable := value 
            export variable 

        示例二: 

            export variable += value 

            其等价于: 

            variable += value 
            export variable 

    如果你要传递所有的变量,那么,只要一个export就行了。后面什么也不用跟,表示传递所有的变量。 

    需要注意的是,有两个变量,一个是SHELL,一个是MAKEFLAGS,这两个变量不管你是否export,其总是要传递到下层Makefile中,特别是MAKEFILES变量,其中包含了make的参数信息,如果我们执行“总控Makefile”时有make参数或是在上层Makefile中定义了这个变量,那么MAKEFILES变量将会是这些参数,并会传递到下层Makefile中,这是一个系统级的环境变量。 

    但是make命令中的有几个参数并不往下传递,它们是“-C”,“-f”,“-h”“-o”和“-W”(有关Makefile参数的细节将在后面说明),如果你不想往下层传递参数,那么,你可以这样来: 

        subsystem: 
                cd subdir && $(MAKE) MAKEFLAGS= 

    如果你定义了环境变量MAKEFLAGS,那么你得确信其中的选项是大家都会用到的,如果其中有“-t”,“-n”,和“-q”参数,那么将会有让你意想不到的结果,或许会让你异常地恐慌。 

    还有一个在“嵌套执行”中比较有用的参数,“-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”总是失效的。 

    五、定义命令包 

    如果Makefile中出现一些相同命令序列,那么我们可以为这些相同的命令序列定义一个变量。定义这种命令序列的语法以“define”开始,以“endef”结束,如: 

        define run-yacc 
        yacc $(firstword $^) 
        mv y.tab.c $@ 
        endef 

    这里,“run-yacc”是这个命令包的名字,其不要和Makefile中的变量重名。在“define”和“endef”中的两行就是命令序列。这个命令包中的第一个命令是运行Yacc程序,因为Yacc程序总是生成“y.tab.c”的文件,所以第二行的命令就是把这个文件改改名字。还是把这个命令包放到一个示例中来看看吧。 

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

    我们可以看见,要使用这个命令包,我们就好像使用变量一样。在这个命令包的使用中,命令包“run-yacc”中的“$^”就是“foo.y”,“$@”就是“foo.c”(有关这种以“$”开头的特殊变量,我们会在后面介绍),make在执行命令包时,命令包中的每个命令会被依次独立执行。

  • 相关阅读:
    upstream实现内网网站在公网访问
    ifconfig筛选出IP
    ansible安装及配置
    ansible puppet saltstack三款自动化运维工具的对比
    upstream(负载均衡)
    nginx反代及后端web配置
    centos7 安装gdb (调试nginx)
    centos 7搭建 strongSwan
    MySQL主从及读写分离配置
    Python中的用open打开文件错误,FileNotFoundError: [Errno 2] No such file or directory:
  • 原文地址:https://www.cnblogs.com/lidabo/p/6187581.html
Copyright © 2011-2022 走看看