编译源代码新手指南

作者:Larry Ayers

Linux 新手通常做的第一件事之一是在互联网上搜索有趣且有用的程序来运行,很快就会发现许多程序仅以源代码树的形式提供(如果不是程序员,这种形式可能会让人望而生畏)。因此,新的 Linux 用户需要熟悉编译过程,因为对于任何运行 Linux 的人来说,这确实是一项必要的技能。

我本人不是程序员,但我确实对源代码如何变成可执行文件有基本的了解。可能我非程序员的身份能够提出一些对于经验丰富的程序员来说可能“不言而喻”的信息。《Running Linux》第六章对此主题进行了很好的介绍,作者是 Matt Welsh 和 Lar Kaufman(O'Reilly,1995 年)。

编译软件

GNU 编程实用程序,包括 gcc 编译器、make 程序、链接器和大量相关工具(其中许多工具您不一定需要了解)是大多数 Linux 发行版的组成部分。Slackware 发行版具有菜单驱动的安装过程,在此过程中,您可以选择安装 GNU 编程工具。如果您选择不安装这些软件包,则必须启动 pkgtool 实用程序并将它们复制到您的硬盘驱动器。

还有其他免费编译器,但建议坚持使用 GNU 工具,因为它们维护良好且质量上乘。大多数 Linux 软件似乎也是在考虑 gcc 的情况下编写的,而且您需要对提供的 Makefile 进行的编辑越少越好。

以流行的 Tcl/Tk 编程语言编写的应用程序通常不使用 GNU 工具;如果使用,C 语言组件是 Tcl/Tk 组件的附属品。您需要在系统上安装 Tcl 和 Tk 库和可执行文件,才能安装此类应用程序的源代码。这些应用程序不是通常意义上的编译。安装包括将 Tcl 和 Tk 文件复制到 makefile 中指定的目录。这些程序完全依赖于它们访问现有 Tcl/Tk 已安装文件库的能力,其中最重要的是 Tk “wish” 可执行文件。

就在几个月前,维护最新的 Tcl/Tk 安装仍然很困难;开发速度很快,二进制文件并不总是可用,并且软件包可能难以成功编译。一些较新的应用程序需要 beta 库才能运行。随着非 beta 版 Tcl-7.5 和 Tk-4.1 的发布,情况最近趋于稳定,它们都有二进制和源代码版本。对于这些程序,大多数用户最好安装二进制文件,因为根据我的经验,它们很难从源代码编译。

请注意,即使您拥有相当新的 Linux 发行版,其中包含的 Tcl/Tk 版本也很可能已过时。如果您想运行 TkDesk 和 TkMan 等优秀的最新版本应用程序,升级您的 Tcl/Tk 文件是非常值得的。

获取源代码

FTP 站点真的不能称之为用户友好或对新手有吸引力。文件名通常很神秘,并且导航看似无限级别的目录树可能令人沮丧,特别是如果您不知道文件位于何处。这些站点不是为随意浏览而设计的,但大型存档站点(例如,ftp://sunsite.unc.edu 及其镜像站点)的维护者会保留各种索引文件,有时采用 HTML 格式,其中列出了可用文件及其简要说明。通常存在一个名为 NEW 的文件,其中列出了最近到达的文件。完整的索引文件可能非常大,但值得下载,以便能够使用具有良好搜索功能的文本编辑器来搜索您感兴趣的关键字或文件名。

通常,名为 filename.tar.gz 的文件通常是源代码目录树,经过 tar 压缩和 gzip 压缩。二进制发行版通常具有以 filename.BIN.tar.gz 或 filename.BIN-ELF.tar.gz 模式命名的名称。

各种 Linux 新闻组中的 Usenet 帖子通常包含各种软件包的位置。

我建议使用 NcFtp 作为 FTP 客户端。这个编写良好的命令行 FTP 程序界面具有许多便捷功能,例如记住您在书签文件中访问的每个站点,包括您上次所在的目录。此功能与 NcFtp 的“reget”功能很好地结合在一起,该功能允许在连接断开的点恢复中断的文件传输。

另一个方便的资源是最近发布的 CD-ROM,其中包含主要 Linux FTP 存档站点之一的快照。一些公司销售这些 CD-ROM,价格合理。Linux 软件变化如此之快,以至于即使是最新的 CD-ROM 上的文件也可能比当前版本落后一两个版本,但如果您突然渴望编译 Xemacs 或 Andrew 用户界面系统,CD-ROM 将为您节省漫长的下载时间。

处理 *.tgz 文件

可以轻松配置 NcFtp,将下载的文件存放到 /usr/local/src 或您喜欢的任何位置。获得文件后,必须对其进行解压缩和解 tar。在您的 ~/.bashrc 文件中设置别名(如果您使用 bash)可以简化此过程。例如,行

alias tgz='tar xvzf'

在 .bashrc 中,您可以通过键入 tgz filename.tar.gz 来展开存档。绝大多数存档文件将创建一个子目录,然后在其中展开存档的文件和子目录。偶尔您会遇到一个直接展开到当前目录中的文件。您可以先列出存档的内容 (tar tzvf filename.tar.gz),或者创建一个目录并将文件移动到其中(如果您已经展开了它)。

有一些文件管理器可以加快这些过程。Midnight Commander 文本模式实用程序可以将 *.tgz 文件视为虚拟目录,允许您深入其中并检查内容(阅读 readme 文件),而无需实际展开存档。

Tcl/Tk 文件/桌面管理器 TkDesk 具有特定于存档文件的鼠标右键菜单;它们允许您在编辑器窗口中列出内容并提取到当前目录或根目录。

无论如何,您最终都会得到一个包含源代码的目录树。Unix 有一个有用的约定,即在尝试编译之前应读取的文件名称全部大写,例如,README 或 CHANGES。通常有一个名为 INSTALL 的重要文件,应仔细阅读。由于大写文件名显示在目录列表的顶部,因此这些文件很容易找到。

三种类型的源代码

源代码包可以大致分为三种类型:包含 Configure 脚本的程序、使用 imake 的程序以及包含默认 makefile 的程序。

我们将从最简单的类型开始,即上面提到的第一种。Configure 脚本是非常棒的构造——基本上,它们是 shell 程序,可以在您的 Linux 系统中随意漫游,检查各种库和头文件的存在。脚本使用此信息构建原型 makefile,将其转换为针对您的系统定制的 Makefile。我发现使用这些脚本的程序很容易编译。脚本完成其工作后,通常只需键入 make,然后在过程完成后键入 make install 即可。

许多源代码包使用 imake 程序,通常通过其 shell 脚本界面 xmkmf。这些软件包将包含 Imakefile 和 makefile.in。编译从调用 imake 开始,通常通过键入 xmkmf。Imake 是一个 C 预处理器;它使用 makefile.in 作为模板以及存储在各种模板和宏文件中的信息(通常位于 /usr/X11R6/lib/X11/config 中)生成您的 Makefile。幸运的是,您无需了解其工作原理即可使用它。Imakefile 是您唯一需要修改的文件,通常只是设置首选安装路径和一些重要库的位置。

最简单但问题最多的源代码包类型包含默认 Makefile。必须仔细编辑此 Makefile,以确保包含正确的库。有时,特别是如果源代码是为与您的机器非常相似的机器编写的,这些软件包将以最少的 Makefile 编辑进行编译。但它们也可能崩溃,因此花一点时间尝试一些事情,并知道何时花费的时间不值得可疑的结果。

幸运的是,最有用和最流行的程序往往很容易编译,这是因为更多人参与并提交错误报告。许多免费程序都提供适用于各种操作系统的 makefile,包括 OS/2、Windows NT 甚至 DOS。

编译过程

通过观看编译器在屏幕上向下滚动的状态消息,可以学到很多东西。源代码目录中的每个 *.c 文件首先被编译成目标文件 (*.o)。在此过程中,人类可读的 ASCII 文本源文件被转换为二进制格式。此阶段最耗时。如果您仍在过程快结束时观看,您将看到目标文件链接在一起的剧烈活动,以及完成的可执行文件运行所需的共享库也被链接。然后该过程突然停止。gcc 不会告诉您它已成功编译可执行文件。但是,如果有错误并且无法完成编译,它会告诉您。在编译后快速执行 ls 以验证实际上是否存在一个全新的、从未执行过的程序等待尝试,这始终令人兴奋。

根据我的经验,大多数致命错误都涉及库链接步骤。一点常识在这里有所帮助;确保您拥有该库,并且它位于 ldd(库加载器)已知的位置。有时问题是缺少符号链接,将非标准位置的库链接到正常的库目录之一。如果您拥有的库版本已过时或错误,gcc 将在错误消息中说明。

Xpm 库可能是编译问题的根源。那里有很多版本,有些程序对接受它们很挑剔。如果您为了使某些东西能够编译而升级到较新的 Xpm 库,如果某些较旧的 X 应用程序停止工作,请不要感到惊讶。我还没有找到一种方法可以同时激活多个版本的 Xpm。尽管 Xpm 如此挑剔,但它已成为许多 X 程序的重要组成部分。我开始意识到是什么促使人们创建连贯、可升级的 Linux 发行版。

一些提示

在几个实例中,我使用源代码发行版惨败,然后在几周或几个月后下载了更高版本并使其干净地编译。也许我更新了 Makefile 正在查找的库,或者也许作者对源代码进行了更改,从而幸运地使该程序与我的系统兼容。换句话说,当您最初遇到问题时,值得稍后重试。

我发现自己处于另一种情况:在多次编辑 Makefile 和可能的一些头文件后,我遇到了越来越多的编译器错误。似乎没有任何效果,我似乎无法取得任何进展。这是删除整个目录树并从存档文件重新安装它的理想时机。有时全新的开始会有所帮助。

Makefile 中需要注意的一个编译器标志是 -g(如 gcc -g 中所示)。GNU 程序通常具有此标志,该标志指示编译器将庞大的调试代码添加到可执行文件中。如果您计划在程序上使用调试器,则需要此标志。我甚至没有安装调试器,所以我通常会删除该标志。strip 实用程序将删除此调试代码,通常可以将可执行文件的大小减小一半。

虚拟控制台是为编译量身定制的。一旦您启动了长时间的编译,只需切换到另一个控制台并开始其他操作即可。我喜欢在编译时关闭 X-Windows,因为 gcc 会使用它可以获得的所有处理器周期。可用资源越多,您的程序编译速度就越快。

结论

那么,从学习编译程序中您能获得什么呢?

  • 您可以使用的软件范围大大增加。

  • 我相信使用针对您的系统和配置进行调整的可执行文件是有优势的。

  • 您有机会指定编译器标志,例如 >\#140>O2,以优化代码。有时可以在 Makefile 中设置或取消设置编译时选项。

  • 您可以将程序中您知道永远不需要的函数或子例程排除在可执行文件之外。

  • 源代码通常是连续构建在 beta 测试场景中可用的唯一形式。

  • 通常,源代码附带的文档比二进制发行版更完整。

  • 了解程序的组合方式很有趣。通常,源文件会添加大量注释,因为程序员可能希望向项目中的当前或未来的协作者解释代码段。

Larry Ayers (layers@vax2.rain.gen.mo.us) 居住在密苏里州北部的一个小农场,目前正忙于为家人建造一座木框架房屋。他经营一家便携式带锯厂,从事一般的木工工作,演奏小提琴并寻找稀有的草原植物,以及种植香菇。他还正努力为当地 ISP 配置 Usenet 新闻服务器。

加载 Disqus 评论