从源代码到可执行文件

========================【编译和链接】===============================

首先要把源文件编译成中间代码文件。

UNIX下是 .o 文件,即 Object File,即目标文件。这个动作叫做编译(compile),由编译器完成(gcc)

然后再把大量的Object File合成执行文件,这个动作叫作链接(link),由链接器完成(ld)

 

编译时:

编译器需要的是语法的正确,函数与变量的声明的正确。

对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中)。

只要所有的语法正确,编译器就可以编译出中间目标文件。

一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。

 

链接时:

主要是链接函数和全局变量,

所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来链接我们的应用程序。
链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File)。

在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名。

这对于编译很不方便,所以,我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(Library File)
也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件(静态库)

 

源文件首先会生成中间目标文件,再由中间目标文件生成可执行文件

在编译时,编译器只检测程序语法,和函数、变量是否被声明。

如果函数未被声明,编译器会给出一个警告,但可以生成Object File。

 

而在链接程序时,链接器会在所有的Object File中找寻函数的实现
如果找不到,那到就会报链接错误码(Linker Error)。

 

我的链接:

gcc的介绍:https://www.cnblogs.com/grooovvve/p/14646253.html

Linux系统编程4_编译链接:https://www.cnblogs.com/grooovvve/p/13352515.html

Linux系统编程2_gcc编译器及头文件库文件搜索路径:https://www.cnblogs.com/grooovvve/p/12846777.html

=========================【make和makefile】===========================

 如果手动操作gcc,ld来编译代码最终生成可执行文件,对于代码量较大的工程来说,是很困难,且效率低下。

这时候就需要自动化编译。

makefile和make就是自动化编译的一种方法;

如果是一个大系统,存在很多个模块,那么手工编译的方法就不适用了。

为此,在Linux系统中,专门提供了一个make命令来自动维护目标文件。

 

makefile:

makefile是一个文件,用于描述编译的规则;

一个工程中的源文件不计其数,按类型,功能,模块分别放在若干个目录中。

makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,

哪些文件需要重新编译,甚至于进行更复杂的功能操作。

makefile文件描述了整个工程所有文件的编译顺序编译规则

makefile有自己的书写格式,关键字,函数。还可以使用shell所提供的任何命令来完成想要的工作。

makefile就像一个shell脚本一样,其中也可以执行操作系统的命令。

一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

 

 

make:

make是命令工具,用来解释makefile的指令的命令工具;

make命令执行时,需要一个 makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。

与手工编译和连接相比,make命令的优点在于他只更新修改过的文件(在Linux中,一个文件被创建或更新后有一个最后修改时间,make命令就是通过这个最后修改时间来判断此文件是否被修改)。

而对没修改的文件则置之不理,并且make命令不会漏掉一个需要更新的文件。

make命令当然不会自己知道这些依赖关系,而需要程序员将这些依赖关系写入一个叫makefile的文件中。


我的链接:

makefile基本介绍https://www.cnblogs.com/grooovvve/p/14471033.html

makefile快速查阅https://www.cnblogs.com/grooovvve/p/14453458.html

 

相关链接:

make和makefile使用总结:
https://blog.csdn.net/fanyun_01/article/details/77113422

make命令教程:
http://www.ruanyifeng.com/blog/2015/02/make.html

Makefile由浅入深--教程、干货:
https://zhuanlan.zhihu.com/p/47390641

Makefile经典教程(掌握这些足够)
https://blog.csdn.net/ruglcc/article/details/7814546

Linux 程序编译过程的来龙去脉:https://www.cnblogs.com/jebysun/p/9698363.html
Linux--make基础:https://blog.csdn.net/Rice__/article/details/105897029
linux下make命令详解:https://www.cnblogs.com/tomato0906/articles/6071495.html

如何将linux编译过程中的警告及错误信息输出到文件中:
https://blog.csdn.net/LEON1741/article/details/82052018?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

=======================【configure文件】===============================

对于很大的项目来说,自己手写Makefile非常麻烦,而标准的GNU软件(如Apacle)都是运行一个configure脚本文件来自动产生 Makefile;

这里同时还涉及到代码移植性的问题,即你发布的源代码,要在别人的(类unix)环境中编译成功,这对编写makfile文件提出了不少挑战。

 

这里有两个问题

1、工程很大时,手工编写makefile文件非常麻烦;

2、makefile文件要保证源代码放到其他环境中时能编译通过;

 

这就对makefile文件提出了两个要求

1、自动生成makfile文件;

2、生成适用各个平台具体环境的makefile文件,而且还可以方便用户通过简单指令进行个性化修改;

 

configure 是一个脚本,它能设置源程序来适应各种不同的操作系统平台,并且根据不同的系统来产生合适的Makefile ,

从而可以使你的源代码能在不同的操作系统平台上被编译出来。

configure很好地解决了上述两大需求;

那么configure脚本是怎么来的?下一节介绍

 

源码编译安装步骤:

从网上下载的许多源码的编译和安装过程非常简单,压缩后需要的操作只有三步:

./configure

make

make install

即我们只要运行./configure,这个脚本就能检测当前系统的一些特性,自动生成适合当前平台的makefile文件;

运行make,则会跟进makefile的规则,对源码进行编译。

 

GNU build system:

这种软件编译和安装的框架其实是有一套标准的,即GNU项目提出的GNU build system

GNU Build System指的是这样一种源码编译系统:

它符合GNU Coding Standards标准,有configure脚本、Makefile脚本等,

并且这些脚本遵循一定的最小接口规范,使得用户可以使用一些简单的命令(如:./configure,make,make install)在不同的系统架构上编译并安装GNU工程。
 

我的链接:

Linux33_编译源代码,configure和prefix的概念:https://www.cnblogs.com/grooovvve/p/13326630.html

 

相关链接:

configure文件学习:https://www.cnblogs.com/simonid/p/6374306.html

在linux中config、make、make install三个命令的区别:https://www.csdn.net/gather_2f/MtTaYg3sNjkyNzUtYmxvZwO0O0OO0O0O.html

=========================【autotools工具套件】===================================

一个符合GNU Build System标准的源代码,

只要使用“./configure”,“make”,“make install”就可以把程序安装到Linux系统中去了。

这将特别适合想做开放源代码软件的程序开发人员。

 

为了使源代码实现GNU Build System标准,这对软件开发人员来说是巨大的挑战。

编写一个简单的makefile还行。但是编写一个符合自由软件惯例的Makefile就不那么容易了。

 

Autotools就是一系列帮助开发人员建立GNU Build System的开发套件。

用于自动编译源码实现类Unix系统间的可移植性

这个工具出现的原因是因为软件的可移植性面临巨大的挑战:系统间的C编译器不同、库函数不兼容等。

 

Autotools是GNU工具链的一员,它的另一个名称是GNU build system。

它是一个程序开发工具套件。这里我们要用到的是automake、autoconf、autoheader、autoscan和alocal。概念上说,它们的从属关系如下图:

 

 

auotscan会遍历指定源码目录下的所有文件,找出其中需要特别指定的宏命令。
它生成的文件configure.scan是一个蓝本文件,即只给出了最基本的宏语句。
开发人发在这个文件中进行功能添加后,应该把它改名为configure.ac(也可以改为configure.in)。//这一步需要手动参与

 

aclocal是一个perl 脚本程序,它根据configure.in文件的内容,自动生成aclocal.m4文件、
aclocal的定义是:"aclocal - create aclocal.m4 by scanning configure.ac"。
aclocal.m4文件可以用来包含该源码包自定义的宏。

 

autoconf是用来产生configure文件的。configure是一个脚本,
它能设置源程序来适应各种不同的操作系统平台,并且根据不同的系统来产生合适的Makefile,
从而可以使你的源代码能在不同的操作系统平台上被编译出来。
autoconf程序更像是一个宏展开工具,它使用M4宏处理工具把configure.ac中的宏定义展开为configure的宏实现。
这些宏的定义在一些Autoconf工程文件中。
autoconf 需要GNU m4 宏处理器来处理aclocal.m4 ,生成configure 脚本。

 

我们使用automake --add-missing来产生Makefile.in。
选项--add-missing的定义是 "add missing standard files to package",
它会让automake加入一个标准的软件包所必须的一些文件。
automake 会根据你写的Makefile.am 来自动生成Makefile.in  //makefile.am也需要手动编写
Makefile.am 中定义的宏和目标, 会指导automake 生成指定的代码。

 

我们用automake产生出来的Makefile.in文件是符合GNU Makefile惯例的,
接下来我们只要执行configure这个shell脚本,会根据Makefile.in产生合适的Makefile文件了。

 

autoheader工具会产生config.h.in文件。

 

相关链接:

automake和autoconf学习小结:  https://blog.csdn.net/mrmiantuo/article/details/9326647

Makefile/Makefile.am/Makefile.in三者关系:https://blog.csdn.net/fzy0201/article/details/17427761

Makefile.am 语法:https://blog.csdn.net/vevenlcf/article/details/48134313

Makefile.am规则和实例讲解:https://www.jianshu.com/p/2f5e586c3402

========================【CMake】===================================

我的链接:

IDE、Cmake、makefile、make:https://www.cnblogs.com/grooovvve/p/11222098.html

 

posted @ 2021-04-13 23:24  Grooovvve  阅读(318)  评论(0编辑  收藏  举报