zoukankan      html  css  js  c++  java
  • Makefile备忘

    本文摘自 : 跟我一起写 Makefile     

    makefile文件一般保存名称为makefile或者Makefile,没有后缀。

    make 会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。 

    在 Makefile 中,规则的顺序是很重要的,因为,Makefile 中只应该有一个最终目标,其它的目标都是被这个目标所连带出来的,所以一定要让 make 知道你的最终目标是什么。一般来说,定义在 Makefile 中的目标可能会有很多,但是第一条规则中的目标将被确立为最终的目标。如果第一条规则中的目标有很多个,那么,第一个目标会成为最终的目标。make 所完成的也就是这个目标。


     Makefile 里主要包含了五个东西:  显式规则隐晦规则变量定义文件指示    和   注释

    1. 显式规则。显式规则说明了,如何生成一个或多个目标文件。这是由 Makefile 的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。

    2. 隐晦规则。由于我们的 make 有自动推导的功能,所以隐晦的规则可以让我们比较简略地书写 Makefile,这是由 make 所支持的。

    3. 变量的定义。在 Makefile 中我们要定义一系列的变量,变量一般都是字符串,这个有点像你 C 语言中的宏,当 Makefile 被执行时,其中的变量都会被扩展到相应的引用位置上。

    4. 文件指示。其包括了三个部分,一个是在一个 Makefile 中引用另一个 Makefile,就像C 语言中的 include 一样;另一个是指根据某些情况指定 Makefile 中的有效部分,就像 C 语言中的预编译 #if 一样;还有就是定义一个多行的命令。

    5. 注释。Makefile 中只有行注释,和 UNIX 的 Shell 脚本一样,其注释是用“#”字符。这个就像 C/C++ 中的“//”一样。如果你要在你的 Makefile 中使用“#”字符,可以用反斜框进行转义,如:# 。

        最后,还值得一提的是,在 Makefile 中的命令,必须要以 Tab 键开始。

    make的执行过程:

    1. 读入所有的 Makefile。

    2. 读入被 include 的其它 Makefile。

    3. 初始化文件中的变量。

    4. 推导隐晦规则,并分析所有规则。

    5. 为所有的目标文件创建依赖关系链。

    6. 根据依赖关系,决定哪些目标要重新生成。

    7. 执行生成命令。


    makefile的语法规则(注意在makefile中指令必须以tab键开头,在vim中设定:set tabstop=4):  

    在 Makefile 使用 include 关键字可以把别的 Makefile 包含进来,这很像 C 语言的#include,被包含的文件会原模原样的放在当前文件的包含位置。 

    在 include 前面可以有一些空字符,但是绝不能是 Tab 键开始。include是make保留的关键字不是shell中可执行的指令:include foo.make a.mk b.mk c.mk e.mk f.mk 

    环境变量 MAKEFILES,尽量不用这个特性。当 Makefile 出现了怪事,可以看看当前环境中有没有定义这个变量。

    一般来说,makefile的目标基本上是一个文件,但也有可能是多个文件:

    targets : prerequisites ; command          #冒号前是需要生成的文件,冒号后面是生成这个文件所需要的文件(文件依赖) 。只有在冒号后面的文件比冒号前的文件新,指令command才会被执行。
      command
    ...

    targets 是文件名,以空格分开,可以使用通配符。command 是命令行,如果其不与“target:prerequisites”在一行,那么,必须以 [Tab键] 开头,如果和 prerequisites 在一行,那么可以用分号做为分隔。           

    targets 可以是一个 object file(目标文件),也可以是一个执行文件,还可以是一个标签(label)。make 会比较 targets 文件和 prerequisites 文件的修改日期,如果 prerequisites 文件的日期要比 targets 文件的日期要新,或者 targets 不存在的话,那么,make 就会执行后续定义的命令。 

    在makefile 中我们可以使用变量。makefile 的变量也就是一个字符串,理解成 C 语言中的宏可能会更好。 

    例1: 

    edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o 

      cc -o edit main.o kbd.o command.o display.o             //反斜杠()是换行符的意思。指令必须以tab键开头。

                      insert.o search.o files.o utils.o

        ... ...

    clean :
      rm edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o 

    上面的edit (target)就是由冒号后面的.o文件(prerequisites)生成。

    第二行中的cc是编译指令,只有在.o文件中有比edit新的文件存在或在edit这个文件不存在,第二行的指令行才会被执行,这样可以减少重复。

    因为clean后面没有文件,所以make不会主动的执行其后面的指令,但可以显示的调用这条指令:make clean 

    例2:(这段代码的作用和例1是一样的)

    objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o

    edit : $(objects)
      cc -o edit $(objects)

    clean :
      rm edit $(objects)     

    make可以自动推导文件以及文件依赖关系后面的命令,只要 make 看到一个.o 文件,它就会自动的把.c 文件加在依赖关系中。

    objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o
    edit : $(objects)
      cc -o edit $(objects)
    main.o : defs.h    #自动的将main.cpp当作依赖文件。

      ... ...

    .PHONY : clean
      clean :
    -rm edit $(objects)

    PHONY 意思表示 clean 是一个“伪目标”。而在 rm 命令前面加了一个小减号的意思不要管可能出现的某些错误,继续做后面的事。 


     

  • 相关阅读:
    《程序员修炼之道:从小工到专家》读后感2
    Java第五节课总结
    FirstJavaWeb
    Java第四节课总结
    《程序员修炼之道:从小工到专家》读后感1
    Java第三节课总结
    递归回文
    原码、补码和反码
    Java第二节课总结
    C++ STL的容器类型
  • 原文地址:https://www.cnblogs.com/jiahu-Blog/p/4560156.html
Copyright © 2011-2022 走看看