zoukankan      html  css  js  c++  java
  • 如何写makefile及makefile文件的执行

    ******************************************************

    makefile有什么作用呢?它可以用来做什么呢?makefile有很大的功能,可以帮助你完成一些大型的工程。要想成为专业的人士,makefile的编写是必须会的。

    makefile关系到了整个系统的编译规则。一个工程中的源文件很多,按类型功能等,放在了不同的文件夹中,makedfile就定义了一系列的规则,指定哪些文件先编译,哪些文件后编译,哪些文件重新编译等等一系列的功能操作。makefile还有一个好处就是能进行自动化编译,一旦makefile写好了之后,只要一个make命令,整个工程就可以完全自动化编译,大大提高了工作的效率。

    **************************************

    一、Makefile的简单编写

    **************************************

    在执行make命令时,当前文件夹中需要有一个makefile文件,makefile中编写了怎么去编译和链接这个程序的语句。

    makefile的规则:

    target ... : prerequisites ...

    command

    ...

    ...

    target是目标文件,可以是后边编译后生成的执行文件,可以只是一个标签。

    prerequisites是生成target所需要的文件或目标,就是依赖。

    command就是在shell中输入make后执行的命令

    这就是一个文件依赖关系,target依赖于prerequisites中的文件,其生成规则定义在command中。target一定要比prerequisites新,不然的话command多定义的命令就会被执行,这就是Makefile的规则,也是Makefile最核心的内容。

    ************举例*************

    编写add.c、sub.c、mul.c、div.c四个函数,用test.c将四个函数实现,然后编写一个Makefile编译函数

     

    math文件夹中的文件包括:


    编写Makefile文件:


    编写完后,make一下,观察过程:


    这时,文件夹中的文件为:


    以长列表的形式观察个文件:

    观察可知:target文件test之所有文件中最新的,如果它不为新,那么在执行make命令时,test将会被更新。比如,用touch命令重新访问add.o文件,那么add.o文件就比test新了,重新make命令一下,那个将会再次执行test后的command:如下图所示:


     

    ******************************clean*******

    一般来说,在Makefile文件中都会包含一个clean命令,它用来清楚make时产生的一些中间文件,比如add.o等,clean的编写如下:


    在shell中执行make clean,看到


    即*.o文件都被删除了;当再次执行make clean时,会出现这样的结果:


    意思是*.o文件已经都被删除了,没有这样的文件了,报错。

    刚染我们提到:当target文件没有它的依赖文件新时,会执行target之后的command命令,clean之后没有依赖,而且它也不会在当前文件夹下产生一个clean,可是,如果当前文件夹下有一个clean文件时会发生什么呢?见下:


    这是在当前文件夹中有个clean,我们touch一下它,然后执行make clean,结果他说clean已经是最新的了,clean没有再次被执行,如何解决这个问题:可以在Makefile的最后加上.PHONY:


     

    *******

    这里有一点说明:clean不是一个文件,他只是一个动作名字,后边也没有什么依赖,那么在make时就不会自动去找文件的依赖,也就不会自动的执行clean后定义的command命令,所以要执行clean命令时,要在make后面明显的指出这个动作名字:make clean。这样的方法我们用到很多地方,比如程序的打包,动态库静态库的建立等等。

    *******

    ************************************************

    二、make是怎么工作的?

    ************************************************

    在默认的方式下,我们只输入make命令,那么

    1、make会在当前目录下找到名字为Makefile或makefile的文件;

    2、找到之后,它会找文件中的第一个目标文件target,如上面的例子中的test,并将下个文件作为最终的目标文件。

    3、如果test文件不存在,或他的依赖比test新,那么要执行后面的command命令来生成test这个文件,如果他的依赖.o文件也不存在,那么就要找到.o的依赖,执行它的command,生成.o文件。

    4、于是。make生成了自己的.o文件,再用.o文件生成最终的可执行文件test。

    上述就是make的执行过程。make会一层一层的去找文件的依赖,如果其中出现错误,make就是停止工作并报错。但是,如果comman有错误,make是不会去管的,它会继续执行下面的操作,make只管文件的依赖。

    当我们又添加了一个.c文件时,只需要在依赖中加上它就可以了。

    ********************************************

    三、makefile中使用的变量

    ********************************************

    在上面的例子中

    看到三四行中的*.o都是重复的,那么我们可不可以用一个变量代替呢?我们随意定义个变量objects来表示*.o:程序如下所示:


    简单了很多吧!

    **************************************

    四、使用make的自动推导

    **************************************

    make可以自动推导文件及文件依赖关系后面的命令,所以有时我们可以不用自己写,而让make自动生成。在例子中,*.o会自动的寻找*.c文件,所以我们的.c文件就可以省略不写。于是,我们刚才写的Makefile可更新为:

     

    这种方法也就是make的“隐晦规则”,更为详细的将在后面介绍。


    是不是更简单了呢

     

    ************************************************************************************************************************************

    好了,这是最基本的makedile编写。简单的makefile就到这里!

  • 相关阅读:
    Typora+PicGo图片上传教程
    创建一个springbootcloud项目
    plugin.xml 解析说明
    Java 元注解 使用示例
    Spring 注解学习 使用示例
    springboot2.2 集成 activity6 请假完整示例
    SpringBoot 过滤器,拦截器初步学习整理(有示例代码)
    mybatis plus mysql 代码生成器 示例demo
    Bootstrap相关方法,事件整理
    网站链接
  • 原文地址:https://www.cnblogs.com/gaidy/p/13031447.html
Copyright © 2011-2022 走看看