zoukankan      html  css  js  c++  java
  • makefile文件编写

    一、编译和链接

      编译:

    一般来说,无论是C还是C++,首先要把源文件编译成中间 代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即Object File,这个动 作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)

      编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文 件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就 可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件( .o 文件或 .obj 文件)。

      链接:

      链接时,主要是链接函数和全局变量。所以,我们可以使用这些中间目标文件( .o 文件或 .obj 文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件 (Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显 地指出中间目标文件名,这对于编译很不方便。所以,我们要给中间目标文件打个包,在Windows下这种包 叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。

      总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程 序语法和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。 而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码 (Linker Error),在VC下,这种错误一般是: Link 2001错误 ,意思说是说,链接器未能找到 函数的实现,你需要指定函数的Object File。


    二、makefile编写

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

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

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

     

     2.1 makefile规则:

    target ... : prerequisites ...
        command
        ...
        ...

      target

       可以是一个object file(目标文件),也可以是一个执行文件,还可以是一个标签(label)。对 于标签这种特性,在后续的“伪目标”章节中会有叙述。

      prerequisites 

       生成该target所依赖的文件和/或target

      command

       该target要执行的命令(任意的shell命令)

    这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件, 其生成规则定义在command中。

     2.1 makefile实例:

        

    直接输入命令make可以生成文件edit,删除执行文件和所有的中间目标文件,那么,只要简单地执行一下 make clean.

      声明一个变量:

      

     

     

     make的隐晦规则,.PHONY表示clean是个目标伪文件。

    稳健做法如下:

       

     .PHONY表示clean是一个“伪目标”。而在rm命令前面加上一个小减号的意思是,也许某些文件出现问题,但不要管,继续做后面的事。

     2.2 makefile包含东西:

      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键开始。

    2.3 make的工作方式:

    1. 读入所有的Makefile。

    2. 读入被include的其它Makefile。

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

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

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

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

    7. 执行生成命令。


    三、makefile书写规则

      文件搜寻:

      

     上面的定义指定两个目录,“src”和“../headers”,make会按照这个顺序进行搜索。目录由“冒号”分隔 。(当然,当前目录永远是最高优先搜索的地方)

    另一个设置文件搜索路径的方法是使用make的“vpath”关键字(注意,它是全小写的),这不是变量,这是 一个make的关键字,这和上面提到的那个VPATH变量很类似,但是它更为灵活。它可以指定不同的文件在不 同的搜索目录中。这是一个很灵活的功能。它的使用方法有三种:

      

     

    参考文献:

    https://seisman.github.io/how-to-write-makefile/introduction.html

    陈小洁的三只猫
  • 相关阅读:
    A. Ivan the Fool and the Probability Theory
    关于消除“输出中最后的一个空格”问题
    半文件式输入中一种常见的输入方式
    持续输入问题
    汉诺塔问题
    给定两个正整数,求它们的最大公约数。
    第三届全国高校绿色计算机大赛(初赛题目)
    第三届全国高校绿色计算机大赛(初赛题目)
    C++中的输入及其原理简析
    流感传染
  • 原文地址:https://www.cnblogs.com/ccpang/p/11457388.html
Copyright © 2011-2022 走看看