zoukankan      html  css  js  c++  java
  • makefile入门

     

    日期:2019/3/23 19:28

    转载自https://blog.csdn.net/haoel/article/details/2887

    一、make规则

    target ... : prerequisites

        command1

        command2

        ...

     

    ·target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)。

    ·prerequisites就是,要生成那个target所需要的文件或是目标。

    ·command也就是make需要执行的命令。(任意的Shell命令,必须以tab开头)。

    ·prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。

    我们编写makefile的终极目标:

    ·如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。

    ·如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。

    ·如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。

    二、make符号

    符号

    含义

    换行

    $

    引用变量,如$(objs)

    #

    注释

     

    三、make实例

        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

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

        main.o : main.c defs.h

                cc -c main.c

        kbd.o : kbd.c defs.h command.h

                cc -c kbd.c

        command.o : command.c defs.h command.h

                cc -c command.c

        display.o : display.c defs.h buffer.h

                cc -c display.c

        insert.o : insert.c defs.h buffer.h

                cc -c insert.c

        search.o : search.c defs.h buffer.h

                cc -c search.c

        files.o : files.c defs.h buffer.h command.h

                cc -c files.c

        utils.o : utils.c defs.h

                cc -c utils.c

        clean :

                rm edit main.o kbd.o command.o display.o

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

     

    四、make工作原理

    以下为引用。

    • 输入make
    • make会在当前目录下找名字叫"Makefile"或"makefile"的文件
    • 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到"edit"这个文件,并把这个文件作为最终的目标文件。
    • 如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
    • 如果edit所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
    • 当然,C文件和H文件是存在的,于是make会生成 .o 文件,然后再用 .o 文件生命make的终极任务,也就是执行文件edit了。

    注意事项:

    • make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。

    举例说明:

    • 如果这个工程已被编译过了,当我们修改了其中一个源文件,比如file.c,那么根据我们的依赖性,我们的目标file.o会被重编译(也就是在这个依性关系后面所定义的命令),于是file.o的文件也是最新的啦,于是file.o的文件修改时间要比edit要新,所以edit也会被重新链接了
    • 如果我们改变了"command.h",那么,kdb.o、command.o和files.o都会被重编译,并且,edit会被重链接。

    五、使用变量

    实质:类似C中的define替换。

    • 使用变量表示所有.o文件

    在makefile一开始就这样定义:

    objects = main.o kbd.o command.o display.o

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

     

    以"$(objects)"的方式来使用这个变量

    edit : $(objects)

        cc -o edit $(objects)

     

    六、自动推导

    GNU make可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]文件后都写上类似的命令,因为,我们的make会自动识别,并自己推导命令。

    只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件。

    下面是经过上述简化的makefile。".PHONY"表示,clean是个伪目标文件。在rm命令前面加了一个小减号:当rm不存在的文件时会输出"cannot remove '123': No such file or directory",-rm会忽略这样的输出,继续rm后面的文件。

    当然,clean的规则不要放在文件的开头,不然,这就会变成make的默认目标,相信谁也不愿意这样。不成文的规矩是——"clean从来都是放在文件的最后"。

    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

        kbd.o : defs.h command.h

        command.o : defs.h command.h

        display.o : defs.h buffer.h

        insert.o : defs.h buffer.h

        search.o : defs.h buffer.h

        files.o : defs.h buffer.h command.h

        utils.o : defs.h

     

        .PHONY : clean

        clean :

                -rm edit $(objects)

     

    七、文件搜查

    在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中。所以,当make需要去找寻文件的依赖关系时,你可以在文件前加上路径,但最好的方法是把一个路径告诉make,让make在自动去找。

    Makefile文件中的特殊变量"VPATH"就是完成这个功能的,如果没有指明这个变量,make只会在当前的目录中去找寻依赖文件和目标文件。如果定义了这个变量,那么,make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。(看到这里已经够用了)

    VPATH = src:../headers

     

    参考文献

    将2886数字++,即可访问《跟我一起写 Makefile》系列的博客

  • 相关阅读:
    hibernate_0100_HelloWorld
    MYSQL子查询的五种形式
    JSF是什么?它与Struts是什么关系?
    nop指令的作用
    htmlparser实现从网页上抓取数据(收集)
    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. Struts tags are only usable when the
    FCKeditor 在JSP上的完全安装
    Java遍历文件夹的2种方法
    充电电池和充电时间说明
    吃知了有什么好处
  • 原文地址:https://www.cnblogs.com/sinkinben/p/10585220.html
Copyright © 2011-2022 走看看