[笔记]快乐的Linux命令行《二十四》编译程序

72 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第25天,点击查看活动详情

前言

在这一章中,我们将看一下如何通过编译源代码来创建程序。源代码的可用性是至关重要的自由,从而使得 Linux 成为可能。整个 Linux 开发生态圈就是依赖于开发者之间的自由交流。对于许多桌面用户来说,编译是一种失传的艺术。

以前很常见,但现在,由系统发行版提供商维护巨大的预编译的二进制仓库,准备供用户下载和使用。在写这篇文章的时候,Debian仓库(最大的发行版之一)包含了几乎 23,000 个预编译的包。

那么为什么要编译软件呢

有两个原因:

  1. 可用性。尽管系统发行版仓库中已经包含了大量的预编译程序,但是一些发行版本不可

能包含所有期望的应用。在这种情况下,得到所期望程序的唯一方式是编译程序源码。

  1. 及时性。虽然一些系统发行版专门打包前沿版本的应用程序,但是很多不是。

这意味着,为了拥有一个最新版本的程序,编译是必需的。从源码编译软件可以变得非常复杂且具有技术性;许多用户难以企及。然而,许多编译任务是相当简单的,只涉及到几个步骤。这都取决于程序包。我们将看一个非常简单的案例,为的是给大家提供一个对编译过程的整体认识,并为那些愿意进一步学习的人们构筑一个起点。

我们将介绍一个新命令:

  • make - 维护程序的工具

一、编译程序

1.1 什么是编译?

简而言之,编译就是把源码(一个由程序员编写的人类可读的程序描述)翻译成计算机处理器的母语的过程。

计算机处理器(或 CPU)工作在一个非常基本的水平,执行用机器语言编写的程序。这 是一种数值编码,描述非常小的操作,比如“加这个字节”,“指向内存中的这个位置”,或者 “复制这个字节”。

这些指令中的每一条都是用二进制表示的(1 和 0)。

最早的计算机程序就是用这种数值编码写成的,这可能就解释了为什么编写它们的程序员据说吸很多烟,喝大量咖啡,并带着厚厚的眼镜。这个问题克服了,随着汇编语言的出现,汇编语言代替了数值编码(略微)简便地使用助记符,比如 CPY(复制)和 MOV(移动)。用汇编语言编写的程序通过汇编器处理为机器语言。

所有的程序都是可编译的吗?

不是。正如我们所看到的,有些程序比如 shell 脚本就不需要编译。它们直接执行。

这些程序是用所谓的脚本或解释型语言编写的。近年来,这些语言变得越来越流行,包括 Perl,Python,PHP,Ruby,和许多其它语言。

1.2 编译一个 C 语言

让我们编译一些东西。在我们行动之前,然而我们需要一些工具,像编译器,链接器,还有 make。在 Linux 环境中,普遍使用的 C 编译器叫做 gcc(GNU C 编译器),最初由 RichardStallman 写出来的。大多数 Linux 系统发行版默认不安装 gcc。

我们可以这样查看该编译器是否存在:

[me@linuxbox ~]$ which gcc
/usr/bin/gcc

在这个例子中的输出结果表明安装了 gcc 编译器。

小提示:你的系统发行版可能有一个用于软件开发的 meta-package(软件包的集合)。

如果是这样的话,考虑安装它,若你打算在你的系统中编译程序。若你的系统没有提供一个meta-package,试着安装 gcc 和 make 工具包。在许多发行版中,这就足够完成下面的练习了。

得到源码

为了我们的编译练习,我们将编译一个叫做 diction 的程序,来自 GNU 项目。这是一个小巧方便的程序,检查文本文件的书写质量和样式。就程序而言,它相当小,且容易创建。

1.3 检查源码树

打开该 tar 文件,会创建一个新的目录,名为 diction-1.11。这个目录包含了源码树。

让我们看一下里面的内容:

[me@linuxbox src]$ cd diction-1.11
[me@linuxbox diction-1.11]$ ls

image.png

image.png

构建程序

大多数程序通过一个简单的,两个命令的序列建立:

./configure
make

这个 confifigure 程序是一个 shell 脚本,由源码树提供。它的工作是分析程序建立环境。大多数源码会设计为可移植的。也就是说,它被设计成,能建立在多于一个的类 Unix 系统中。但是为了做到这一点,在建立程序期间,为了适应系统之间的差异,源码可能需要经过轻微的调整。confifigure 也会检查是否安装了必要的外部工具和组件。让我们运行 confifigure 命令。因为 confifigure 命令所在的位置不是位于 shell 通常期望程序所呆的地方,我们必须明确地告诉shell 它的位置,通过在命令之前加上./ 字符,来表明程序位于当前工作目录:

[me@linuxbox diction-1.11]$ ./configure

confifigure 将会输出许多信息,随着它测试和配置整个构建过程。当结束后,输出结果看起来像这样:

image.png

安装程序

打包良好的源码经常包括一个特别的 make 目标文件,叫做 install。这个目标文件将在系统目录中安装最终的产品,以供使用。通常,这个目录是/usr/local/bin,为在本地所构建软件的传统安装位置。然而,通常普通用户不能写入该目录,所以我们必须变成超级用户,来执行安装操作:

[me@linuxbox diction-1.11]$ sudo make install

After we perform the installation, we can check that the program is ready to go:

[me@linuxbox diction-1.11]$ which diction

/usr/local/bin/diction

[me@linuxbox diction-1.11]$ man diction

And there we have it!

总结

在这一章中,我们已经知道了三个简单命令:

  • ./configure
  • make
  • make install

可以用来构建许多源码包。我们也知道了在程序维护过程中,make 程序起到了举足轻重的作用。

make 程序可以用到任何需要维护一个目标/依赖关系的任务中,不仅仅为了编译源代码。