十年运维系列之基础篇 - Linux
作者:曾林
联系:[email protected]
版权:文章未经同意请勿转载
一、引言
本章将介绍如何通过源代码来生成可执行程序。开放源代码是Linux自由开源的必要因素,整个Linux系统的开发依赖于开发人员之间的自由交流。对于多数桌面系统用户来说,编译已经是一门失传的艺术。编译技术虽然曾经非常普遍,但是如今,版本发行商却维护着很大的预编译二进制库,以便用户下载使用。
那么,为什么要编译软件呢?有如下两个原因:
- 可用性:尽管有些发行版已经包含了版本库中的一些预编译程序,但不会包含用户所有可能需要的应用程序。这种情况下,用户获取所需要软件的唯一方式就是编译源代码。
- 及时性:虽然有些发行版专注于一些前沿的程序版本,但是多数并不会。这就意味着想要获取最新版本的程序,编译是必不可少的。
二、什么是编译
简单来说,编译就是一个将源代码(由程序员编写的人类可读的程序描述)翻译成计算机处理器能识别的语言的过程。
计算机处理器(或CPU)在一个非常基础的层次上工作,只能运行称之为机器语言的程序。而机器语言其实就是一些数值代码,它描述的都是一些非常小的操作,比如“增加某个字节”、“指向内存中某个位置”或“复制某个字节”等,并且每一个这样的指令都是以二进制(0和1)的形式表示的。最早的计算机程序就是用这样的数值代码编写。
汇编语言的出现解决了这一问题,因为它用诸如CPY(复制)和MOV(转移)等更容易的助记符取代了那些数值代码,汇编语言编写的程序会由汇编程序(assembler)处理成机器语言。如今,汇编语言仍然用于某些专门的编程任务,诸如设备驱动和嵌入式系统等。
之后便出现了高级语言编程,被称为高级语言是因为它们可以让程序员少关注些处理器的操作细节而把更多的精力集中在解决手头的问题上。
高级语言编写的程序通过编译器转换为机器语言。有些编译器则将高级语言程序转换为汇编语言,然后再使用一个汇编程序(assembler)将其转换为机器语言。
经常和编译一起使用的步骤就是链接。程序执行着许多共同的任务。例如:打开一个文件,许多程序都会需要进行此操作。如果每个程序都采用自己的方式实现该功能的话便是一种浪费。编写一个用于打开文件的单个程序,并允许其他程序共享它,反而更有意义。提供这种通用任务支持功能的便是库,库中包含了很多的例程,每一个实现的都是许多程序能够共享的通用任务。在/lib和/usr/lib目录中,我们可以发现很多这样的程序。链接器(linker)程序可以实现编译器的输出与编译程序所需要库之间的链接。该操作的最后结果就是生成一个供使用的可执行文件。