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

陈小洁的三只猫
原文地址:https://www.cnblogs.com/ccpang/p/11457388.html