当前位置:   article > 正文

项目自动化构建工具-make/Makefile_make工具

make工具

目录

make/makefile

make/makefile是什么?

makefile官方解释:

make又是什么?为什么要使用make?     

makefile语法:

依赖关系/依赖方法: 

MakefileDemo:

make机制:

stat指令:

.PHONY伪目标的原理:

 make/makefile小技巧:

注释:makefile中可以使用 # 在行首表示行注释

特殊符号:


make/makefile

make/makefile是什么?

       你们如果是到了那些大型工程中,编写具有上千、上万条代码,一次编译完成之后又修改源代码,接着再想进行编译,此时便需要重新敲入指令,工作就会变得繁琐。在VS中,我们可以无限地修改自己的代码,然后随时编译运行,不需要考虑这些复杂的原理。

    在Linux中也有这样的一站式操作-----【make/Makefile

makefile官方解释:

 一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。可见,makefifile都成为了一种在工程方面的编译方法。
简单的理解就是,Makefile就是一个比较特别的文件,在这个文件里边定义了一些规则,来帮助我们同时编译多个源文件。

make又是什么?为什么要使用make?
     

   make是一个命令工具,是一个解释Makefile文件中指令的命令工具。比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。
总之:make是一条
命令,Makefile是一个文件,两者搭配使用,可完成项目自动化构建,接下来就来仔细讲讲它们是怎么搭配使用的。

makefile语法:

  1. target(目标文件):文件(依赖文件) //依赖关系
  2. <Tab>gcc -o 欲建立的执行文件 目标文件 //依赖方法
  3. ...
  4. ...

依赖关系/依赖方法: 

  • 依赖关系只有 依赖文件存在才能有target(目标文件),两者之间存在关系。
  • 依赖方法是指target(目标文件)通过下面的命令转化成依赖文件。
  • 依赖方法以gcc为例,也可以是其他的,但必须是tab键开头

MakefileDemo:

  1.  先创建一个test.c文件

    touch test.c
    

    再对test.c文件编写

    vim test.c

    【vim相关不会的可以参考一下liunx中yum,rzsz及开发工具(vim)这篇文章。】                         随便编写一些,如:

    1. #include<stdio.h>
    2. int main()
    3. {
    4. printf("hello liunx\n");
    5. printf("hello liunx\n");
    6. printf("hello liunx\n");
    7. printf("hello liunx\n");
    8. printf("hello liunx\n");
    9. printf("hello liunx\n");
    10. return 0;
    11. }
  2. 创建makefile

    1. vim makefile //可以直接vim
    2. //进入后编写
    3. mytest:test.c
    4. gcc -o mytest test.c
    5. clean:
    6. rm -f mytest
  3.  直接【make】就可以实现target(目标文件),如想删除可以【make  clean】,示例:
  4. 上面的
    1. mytest:test.c
    2. gcc -o mytest test.c

    是简洁的,复杂的应该是:

    1. mytest:test.o
    2. 2 gcc -o mytest test.o
    3. 3 test.s:test.i
    4. 4 gcc -c test.i -o test.s
    5. 5 test.o:test.s
    6. 6 gcc -S test.s -o test.o
    7. 7 test.i:test.c
    8. 8 gcc -E test.c -o test.i
    9. 9 clean:
    10. 10 rm -f mytest.i mytest.s mytest.o mytest

  5. 结果:
  6. 1) 对于test.o来说,它依赖于test.s这个经过编译之后文件,可是【test.s】不存在,所以跳转到下一条依赖关系 。2)对于test.s来说,它依赖于test.i这个经过预编译之后的文件,可是【test.i】不存在,所以跳转到下一条依赖关系 。3) 对于test.i来说,它依赖于test.c这个源文件,查找后发现源文件存在,于是开始执行gcc命令
  7. 如果这个依赖的顺序改变后,当我再去make的时候,却发现这个执行的顺序还是按照没打乱之前的位置,这说明了一点:【make】会自动推导Makefile中的依赖关系
  8. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。

make机制:

我们执行完一次make获取【mytest】这个目标文件后,第二次再去执行【make】指令就不会其效果了,这是为何呢?

  • 出现这种情况是为了提高编译效率。
  • 上面也说过未被修改的文件进行编译是没有意义的。

源文件生成的时间一定比可执行文件的要早!!

stat指令

【stat】这个指令来查看源文件和可执行文件的所有属性,不过要观察的还是其中一个叫做ACM时间。

  • 【Access】: 最后一次访问该文件的时间。
  • 【Change】:最后一次改变文件属性状态的时间。
  • 【Modify】:最近一次修改文件内容的时间【比较的是这个时间】。

如:我对源文件的内容修改后,change,modify时间变化了。

 

【touch】指令,它除了创建文件之外还有其他功能。

  • 若是要创建的这个文件不存在,那就将其创建出来。
  • 若是要创建的这个文件存在,那就修改它的ACM时间为最新的时间

 经过对比发现都修改了。

.PHONY伪目标的原理:

       像【clean】这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行, 不过,我们可以显示要【make】执行。即命令——【make clean】,以此来清除所有的目标文件,以便重编译。但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 【.PHONY】 修饰,伪目标的特性是,总是被执行的

下图,先是没有添加.PHONY,一直显示

 加入后:

 make/makefile小技巧:

注释:

makefile中可以使用 # 在行首表示行注释

特殊符号:

我们可以在Makefile中添加一些特殊符号,就可以起到一些特殊的功能即这个【$@和【$^,前者表示:左侧被编译的所有内容,即【目标文件】,后者表示:之后所有内容,即【依赖文件】。

 

 编写了这么多【make】,你是否感觉每次都会出现回显很麻烦呢?能不能像我们在敲普通指令的时候一样,直接给出结果呢?

在【gcc】和【rm】的开头加【@

结果:

 

这样就不用再看到执行的结果。

以上就是对make/makefile的理解,希望能帮助到各位。

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/610923
推荐阅读
相关标签
  

闽ICP备14008679号