16 C源代码编译软件入门
大多数非专有的第三方Unix软件包都有源代码,你可以编译并安装。其中一个原因是,Unix(和 Linux 本身)有太多不同的版本和体系结构,很难为所有可能的平台组合分发二进制软件包。另一个至少同样重要的原因是,Unix 社区广泛传播源代码,鼓励用户为软件贡献错误修复和新功能,这也是开源一词的意义所在。
从内核和C语言库到网络浏览器,你几乎可以在 Linux 系统上获得一切源代码。你甚至可以通过(重新)安装源代码中的部分系统来更新和增强你的整个系统。不过,除非你非常喜欢这个过程或有其他原因,否则你可能不应该通过安装源代码来更新你的机器。
Linux发行版通常提供了更新系统核心部分(如 /bin 中的程序)的简便方法,而且发行版的一个特别重要的特性是,它们通常能很快修复安全问题。但不要指望你的发行版能为你提供一切。以下是你可能需要自己安装某些软件包的原因:
- 控制配置选项。
- 随心所欲地安装软件。甚至可以安装同一软件包的多个不同版本。
- 控制安装的版本。发行版并不总是更新所有软件包的最新版本,尤其是软件包的附加组件(如 Python 库)。
- 更好地了解软件包的工作原理。
16.1 软件构建系统
Linux 上有许多编程环境,从传统的C语言到解释型脚本语言(如 Python)。除了Linux发行版提供的工具外,每种环境通常都至少有一个用于构建和安装软件包的独特系统。
在本章中,我们将只使用其中一种构建系统--由 GNU autotools 套件生成的配置脚本--来编译和安装 C 源代码。这个系统通常被认为是稳定的,许多基本的 Linux 实用程序都使用它。由于它是基于现有的工具(如 make),因此在你了解了它的工作原理后,就能将你的知识应用到其他构建系统中。
从 C 源代码安装软件包通常包括以下步骤:
- 解压源代码压缩包。
- 配置软件包。
- 运行 make 或其他构建命令来构建程序。
- 运行 make install 或发行版特定的 install 命令来安装软件包。
在学习本章之前,您应了解第 15 章中的基础知识。
16.2 解压C源码包
软件包的源代码通常以 .tar.gz、.tar.bz2 或 .tar.xz 文件的形式发布,您应按照第 2.18 节中的说明解压该文件。不过,在解压之前,请使用 tar tvf 或 tar ztvf 验证压缩包的内容,因为有些软件包不会在解压压缩包的目录中创建自己的子目录。
像这样的输出意味着软件包可能可以解压:- package-1.23/Makefile.in
- package-1.23/README
- package-1.23/main.c
- package-1.23/bar.c
- ...
复制代码 不过,你可能会发现并非所有文件都在一个共同的目录中(如上例中的 package-1.23):像这样解压压缩包会在当前目录中留下一大堆乱码。为了避免这种情况,在解压缩之前,先创建一个新的目录,然后 cd 到该目录。
最后,要小心那些包含绝对路径名文件的软件包,例如- /etc/passwd
- /etc/inetd.conf
复制代码 你可能不会遇到这样的文件,但如果遇到了,请从系统中删除该压缩包。它可能包含木马或其他恶意代码。
提取源代码压缩包的内容并获得大量文件后,请尝试了解该压缩包。尤其要查找名为 README 和 INSTALL 的文件。一定要先看 README 文件,因为它们通常包含软件包说明、简短手册、安装提示和其他有用信息。许多软件包还附带 INSTALL 文件,其中包含如何编译和安装软件包的说明。请特别注意特殊的编译器选项和定义。
除了 README 和 INSTALL 文件,你还会发现其他软件包文件,它们大致可分为三类:
与 make 系统相关的文件,如 Makefile、Makefile.in、configure 和 CMakeLists.txt。有些很老的软件包会附带 Makefile,您可能需要修改,但大多数软件包都使用配置实用程序,如 GNU autoconf 或 CMake。它们附带了一个脚本或配置文件(如 configure 或 CMakeLists.txt),以帮助根据系统设置和配置选项从 Makefile.in 生成 Makefile。
以 .c、.h 或 .cc 结尾的源代码文件。C 源代码文件可以出现在软件包目录的任何地方。C++ 源代码文件通常有 .cc、.C 或 .cxx 后缀。
以 .o 或二进制文件结尾的对象文件。通常情况下,源代码发行版中没有任何对象文件,但在极少数情况下,当软件包维护者不允许发布某些源代码,而你需要做一些特殊的事情才能使用对象文件时,你可能会发现一些对象文件。在大多数情况下,源代码发行版中的对象文件(或二进制可执行文件)意味着软件包没有被很好地编译,因此你应该运行 make clean 来确保获得全新的编译。
16.3 GNU Autoconf
尽管 C 源代码通常具有相当高的可移植性,但由于每个平台的差异,大多数软件包都无法用一个 Makefile 来编译。早期解决这一问题的方法是为每种操作系统提供单独的 Makefile,或者提供易于修改的 Makefile。这种方法后来发展为根据对用于编译软件包的系统的分析来生成 Makefile 的脚本。
GNU autoconf 是一种流行的自动生成 Makefile 的系统。使用该系统的软件包带有名为 configure、Makefile.in 和 config.h.in 的文件。.in 文件是模板;其目的是运行 configure 脚本以发现系统的特性,然后在 .in 文件中进行替换,创建真正的编译文件。对于最终用户来说,这很简单;要从 Makefile.in 生成 Makefile,只需运行 configure 即可:当脚本检查系统的先决条件时,你应该会得到很多诊断输出。如果一切顺利,configure 会创建一个或多个 Makefile 和一个 config.h 文件,以及一个缓存文件 (config.cache),这样就不需要再次运行某些测试了。
现在就可以运行 make 来编译软件包了。configure 步骤成功并不意味着 make 步骤也一定会成功,但成功的几率很大。(有关配置和编译失败的故障诊断技巧,请参见第 16.6 节)。
让我们来亲身体验一下这个过程。
注意
此时,你的系统上必须有所有需要的编译工具。对于 Debian 和 Ubuntu,确保这一点的最简单方法是安装build-essential;在 Fedora-like 系统中,使用groupinstall "Development Tools"。
16.3.1 Autoconf 示例
在讨论如何更改 autoconf 的行为之前,让我们先看一个简单的示例,以便了解该如何操作。我们将在自己的主目录下安装 GNU coreutils 软件包(以确保不会弄乱系统)。从 http://ftp.gnu.org/gnu/coreutils/ 获取软件包(最新版本通常是最好的),解压缩,切换到其目录,然后像下面这样配置:- $ ./configure --prefix=$HOME/mycoreutils
- checking for a BSD-compatible install... /usr/bin/install -c
- checking whether build environment is sane... yes
- --snip--
- config.status: executing po-directories commands
- config.status: creating po/POTFILES
- config.status: creating po/Makefile
复制代码 现在运行 make- $ make
- GEN lib/alloca.h
- GEN lib/c++defs.h
- --snip--
- make[2]: Leaving directory '/home/juser/coreutils-8.32/gnulib-tests'
- make[1]: Leaving directory '/home/juser/coreutils-8.32'
复制代码 接下来,尝试运行您刚刚创建的一个可执行文件,如 ./src/ls,并尝试运行 make check 对软件包进行一系列测试。(这可能要花点时间,但很有意思)。
最后,就可以安装软件包了。先用 make -n 试运行一下,看看 make install 在不进行实际安装的情况下能做些什么:浏览一下输出结果,如果没有什么奇怪的地方(比如软件包安装到了 mycoreutils 目录之外的其他地方),就进行真正的安装:现在,你的主目录中应该有一个名为 mycoreutils 的子目录,其中包含 bin、share 和其他子目录。查看 bin 中的一些程序(你刚刚创建了许多在第 2 章中学到的基本工具)。最后,由于你将 mycoreutils 目录配置为独立于系统的其他部分,因此你可以完全删除它,而不必担心造成损害。
16.3.2 使用打包工具进行安装
在大多数发行版中,都可以将新软件安装为一个软件包,然后再使用发行版的打包工具进行维护。以 Debian 为基础的发行版(如 Ubuntu)可能是最简单的;与其运行简单的 make install,不如使用 checkinstall 工具来安装软件包,如下所示:- # checkinstall make install
复制代码 运行该命令会显示与即将构建的软件包相关的设置,并提供修改的机会。继续安装时,checkinstall 会跟踪所有要安装到系统上的文件,并将它们放入 .deb 文件中。然后,你就可以使用 dpkg 安装(和移除)新软件包了。
创建 RPM 软件包要麻烦一些,因为你必须先为软件包创建一个目录树。你可以使用 rpmdev-setuptree 命令来完成这项工作;完成后,你可以使用 rpmbuild 工具来完成其余步骤。在此过程中,最好遵循在线教程。
16.3.3 配置脚本选项
你刚刚看到了 configure 脚本最有用的选项之一:使用 --prefix 指定安装目录。默认情况下,从 autoconf 生成的 Makefile 安装目标使用 /usr/local 作为前缀,也就是说,二进制程序放在 /usr/local/bin,库放在 /usr/local/lib,等等。你通常会希望像这样更改前缀:- $ ./configure --prefix=new_prefix
复制代码 大多数版本的 configure 都有一个 --help 选项,可以列出其他配置选项。不幸的是,该列表通常很长,有时很难找出哪些选项可能很重要,因此这里列出了一些基本选项:
--bindir=目录 在目录中安装可执行文件。
--sbindir=目录 在目录中安装系统可执行文件。
--libdir=目录 在目录中安装库。
--disable-shared 阻止软件包构建共享库。根据库的不同,这可以省去以后的麻烦(参见第 15.1.3 节)。
--with-package=directory告诉 configure 软件包在目录中。当需要的库位于非标准位置时,这很方便。遗憾的是,并非所有 configure 脚本都能识别这类选项,因此很难确定准确的语法。
- 使用单独的编译目录
如果想尝试使用上述某些选项,可以创建单独的编译目录。为此,可在系统的任意位置创建一个新目录,然后从该目录运行原始软件包源代码目录中的 configure 脚本。你会发现 configure 会在你的新构建目录中创建一个符号链接,所有链接都指向原始软件包目录中的源代码树。(有些开发人员喜欢用这种方式构建软件包,因为原始源代码树不会被修改。如果你想使用同一个源码包构建多个平台或配置选项集,这种方法也很有用)。
16.3.4 环境变量
您可以使用 configure 脚本放入 make 变量的环境变量来影响 configure。其中最重要的是 CPPFLAGS、CFLAGS 和 LDFLAGS。但要注意的是,configure 对环境变量非常挑剔。例如,对于头文件目录,通常应该使用 CPPFLAGS 而不是 CFLAGS,因为 configure 通常会独立于编译器运行预处理器。
在 bash 中,向 configure 发送环境变量的最简单方法是将变量赋值放在命令行的 ./configure 前面。例如,要为预处理器定义一个 DEBUG 宏,请使用以下命令:- $ CPPFLAGS=-DDEBUG ./configure
复制代码 您也可以将变量作为选项传递给配置,例如
例如:- $ ./configure CPPFLAGS=-DDEBUG
复制代码 当 configure 不知道去哪里找第三方包含文件和库时,环境变量就特别方便。例如,要让预处理器在 include_dir 中搜索,请运行此命令:- $ CPPFLAGS=-Iinclude_dir ./configure
复制代码 如第 15.2.6 节所示,要让链接器在 lib_dir 中查找,请使用这条命令:- $ LDFLAGS=-Llib_dir ./configure
复制代码 如果 lib_dir 中有共享库(参见第 15.1.3 节),前面的命令可能无法设置运行时动态链接器路径。在这种情况下,除了 -L 之外,还要使用 -rpath 链接器选项:- $ LDFLAGS="-Llib_dir -Wl,-rpath=lib_dir" ./configure
复制代码 设置变量时要小心。稍有不慎就会绊倒编译器,导致 configure 失败。例如,你忘记了 -I 中的 -,如图所示:- $ CPPFLAGS=Iinclude_dir ./configure
复制代码 这样就会产生如下错误- configure: error: C compiler cannot create executables
- See 'config.log' for more details
复制代码 查看这次尝试失败后生成的 config.log 会得到以下结果:- configure:5037: checking whether the C compiler works
- configure:5059: gcc Iinclude_dir conftest.c >&5
- gcc: error: Iinclude_dir: No such file or directory
- configure:5063: $? = 1
- configure:5101: result: no
复制代码 16.3.5 Autoconf Target
一旦配置成功,你会发现它生成的 Makefile 除了标准的 all 和 install 之外,还有许多有用的目标:
如第 15 章所述,它会删除所有对象文件、可执行文件和库。
除了删除所有自动生成的文件(包括 Makefile、config.h、config.log 等)外,它与 make clean 类似。这样做的目的是,在运行 make distclean 之后,源代码树应该看起来像一个新解压的发行版。
有些软件包会附带一系列测试,以验证编译后的程序是否能正常运行;命令 make check 可以运行这些测试。
与 make install 类似,但它会在安装时从可执行文件和库中删除符号表和其他调试信息。剥离后的二进制文件所占空间更小。
16.3.6 Autoconf 日志文件
如果在配置过程中出现问题,而原因又不明显,可以检查 config.log 来查找问题所在。不幸的是,config.log 通常是一个巨大的文件,很难找到问题的确切源头。
在这种情况下,一般的做法是跳转到 config.log 的最末端(例如,在 less 中键入大写字母 G),然后向上翻页,直到发现问题。不过,最后仍有很多内容,因为 configure 会将整个环境转储到这里,包括输出变量、缓存变量和其他定义。因此,与其翻到最后再向上翻页,不如翻到最后再向后搜索一个字符串,比如在失败的 configure 输出结尾附近搜索更多细节或其他文本片段。(很有可能错误就在你搜索到的内容的上方。
16.3.7 pkg-config
系统中的第三方库数量众多,将所有库放在一个共同的位置可能会比较混乱。然而,将每个第三方库安装到一个单独的前缀上,可能会导致在构建需要这些第三方库的软件包时出现问题。例如,如果要编译 OpenSSH,就需要 OpenSSL 库。如何告诉 OpenSSH 配置过程 OpenSSL 库的位置以及哪些库是必需的?
现在,许多库都使用 pkg-config 程序,它不仅可以公布包含文件和库的位置,还可以指定编译和链接程序所需的确切标志。语法如下- $ pkg-config options package1 package2 ...
复制代码 例如,要查找一个流行的压缩库所需的库,可以运行这条命令:输出结果应该是这样的要查看 pkg-config 知道的所有库,包括每个库的简要说明,请运行这条命令:
- pkg-config 如何工作
如果你观察一下后台,就会发现 pkg-config 是通过读取以 .pc 结尾的配置文件来查找软件包信息的。例如,在 Ubuntu 系统(位于 /usr/lib/x86_64-linux-gnu/pkgconfig)上看到的 OpenSSL 套接字库的 openssl.pc 文件:
- prefix=/usr
- exec_prefix=${prefix}
- libdir=${exec_prefix}/lib/x86_64-linux-gnu
- includedir=${prefix}/include
- Name: OpenSSL
- Description: Secure Sockets Layer and cryptography libraries and tools
- Version: 1.1.1f
- Requires:
- Libs: -L${libdir} -lssl -lcrypto
- Libs.private: -ldl -lz
- Cflags: -I${includedir} exec_prefix=${prefix}
复制代码 您可以更改此文件,例如在库标志中添加 -Wl,-rpath=${libdir},以设置运行时库搜索路径。不过,更大的问题是 pkg-config 如何首先找到 .pc 文件。默认情况下,pkg-config 会在安装前缀的 lib/pkgconfig 目录中查找。例如,安装前缀为 /usr/local 的 pkg-config 会在 /usr/local/lib/pkgconfig 目录中查找。
注意:除非安装了开发包,否则很多软件包都不会有 .pc 文件。例如,要在 Ubuntu 系统上获取 openssl.pc,必须安装 libssl-dev 软件包。
- 如何在非标准位置安装 pkg-config 文件
遗憾的是,默认情况下,pkg-config 不会读取其安装前缀之外的任何 .pc 文件。这意味着如果 .pc 文件位于非标准位置,比如 /opt/openssl/lib/pkgconfig/openssl.pc,则任何 pkg-config 安装都无法读取。有两种基本方法可以让 .pc 文件在 pkg-config 安装前缀之外可用:
从实际的 .pc 文件制作符号链接(或副本)到中央 pkgconfig 目录。
设置 PKG_CONFIG_PATH 环境变量,以包含任何额外的 pkgconfig 目录。这种策略在全系统范围内效果不佳。
16.4 安装实践
知道如何构建和安装软件是件好事,但知道何时何地安装自己的软件包则更为有用。Linux 发行版会在安装时尽可能多地塞入软件,因此你应该经常检查自己安装软件包是否会更好。以下是自行安装的优势:
- 可以自定义软件包默认设置。
- 安装软件包时,你往往能更清楚地了解如何使用它。
- 可以控制运行的版本。
- 备份自定义软件包更容易。
- 在网络中分发自行安装的软件包更容易(只要架构一致,安装位置相对独立)。
缺点如下
- 如果你想安装的软件包已经安装在系统上,你可能会覆盖重要文件,从而导致问题。使用 /usr/local 安装前缀可以避免这种情况,稍后会介绍。即使系统上没有安装软件包,也应检查发行版中是否有可用的软件包。如果有的话,你需要记住这一点,以防以后不小心安装了发行版软件包。
- 需要时间。
- 自定义软件包不会自动升级。发行版会保持大多数软件包的更新,而不需要你做很多工作。这一点对于与网络交互的软件包尤为重要,因为你需要确保始终拥有最新的安全更新。
- 如果你不实际使用软件包,那就是在浪费时间。
- 软件包有可能配置错误。
除非你正在构建一个非常定制的系统,否则安装诸如本章前面构建的 coreutils 软件包(ls、cat 等)中的软件包没有太大意义。另一方面,如果你对 Apache 等网络服务器有浓厚的兴趣,最好的办法就是自己安装这些服务器,以获得完全的控制权。
16.4.1 安装位置
GNU autoconf 和许多其他软件包的默认前缀是 /usr/local,这是本地安装软件的传统目录。操作系统升级会忽略 /usr/local,因此在操作系统升级过程中不会丢失安装在该目录下的任何内容。唯一的问题是,如果你安装了大量自定义软件,这可能会变成一团糟。成千上万个稀奇古怪的小文件可能会进入 /usr/local 层次结构,而你可能根本不知道这些文件从何而来。
如果情况真的开始变得混乱,你应该按照第 16.3.2 节所述创建自己的软件包。
16.5 应用补丁
对软件源代码的大多数修改都是以开发者在线版本源代码(如 Git 代码库)分支的形式提供的。不过,偶尔也会有补丁需要应用到源代码中,以修复错误或添加功能。你也可能会看到术语 diff 被用作补丁的同义词,因为 diff 程序会生成补丁。
一个补丁的开头可能是这样的- --- src/file.c.orig 2015-07-17 14:29:12.000000000 +0100
- +++ src/file.c 2015-09-18 10:22:17.000000000 +0100
复制代码 补丁通常包含对多个文件的修改。在补丁中连续搜索三个破折号 (---),就能看到有改动的文件,并始终查看补丁的开头,以确定所需的工作目录。因此,在打补丁之前,您应更改为包含 src 的目录,而不是 src 目录本身。
要打补丁,请运行 patch 命令:如果一切顺利,patch 会顺利退出,给你留下一套更新的文件。不过,patch 可能会问你这个问题:这通常意味着你不在正确的目录中,但也可能表明你的源代码与补丁中的源代码不匹配。在这种情况下,你可能就不走运了。即使你能识别出一些要打补丁的文件,其他文件也不会被正确更新,从而导致你的源代码无法编译。
在某些情况下,你可能会遇到这样的补丁,其中提到了软件包的版本:- --- package-3.42/src/file.c.orig 2015-07-17 14:29:12.000000000 +0100
- +++ package-3.42/src/file.c 2015-09-18 10:22:17.000000000 +0100
复制代码 如果版本号略有不同(或只是重命名了目录),可以让 patch 删除路径前导成分。例如,您的目录中包含 src(和以前一样)。要让 patch 忽略路径中 package-3.42/ 的部分(即去掉一个前导路径成分),请使用 -p1:参考资料
- 软件测试精品书籍文档下载持续更新 https://github.com/china-testing/python-testing-examples 请点赞,谢谢!
- 本文涉及的python测试开发库 谢谢点赞! https://github.com/china-testing/python_cn_resouce
- python精品书籍下载 https://github.com/china-testing/python_cn_resouce/blob/main/python_good_books.md
- Linux精品书籍下载 https://www.cnblogs.com/testing-/p/17438558.html
- python八字排盘 https://github.com/china-testing/bazi
16.6 解决编译和安装问题
如果你了解编译器错误、编译器警告、链接器错误和共享库问题之间的区别(如第 15 章所述),那么在构建软件时解决许多小问题就不会有太大困难。本节将介绍一些常见问题。虽然在使用 autoconf 构建软件时不太可能遇到这些问题,但了解一下它们的样子也无妨。
在介绍具体问题之前,请确保您可以阅读某些类型的 make 输出。了解错误和忽略的错误之间的区别非常重要。下面就是你需要调查的真实错误:- make: *** [target] Error 1
复制代码 然而,有些 Makefile 会怀疑可能会发生错误,但知道这些错误是无害的。您通常可以忽略类似的信息:- make: *** [target] Error 1 (ignored)
复制代码 此外,GNU make 通常会在大型软件包中多次调用自己,错误信息中的每个 make 实例都标有 [N],其中 N 是一个数字。通过查看直接出现在编译器错误信息之后的 make 错误,通常可以很快找到错误。例如
涉及 file.c 的编译器错误信息- compiler error message involving file.c
- make[3]: *** [file.o] Error 1
- make[3]: Leaving directory '/home/src/package-5.0/src'
- make[2]: *** [all] Error 2
- make[2]: Leaving directory '/home/src/package-5.0/src'
- make[1]: *** [all-recursive] Error 1
- make[1]: Leaving directory '/home/src/package-5.0/'
- make: *** [all] Error 2
复制代码 这里的前三行给出了你需要的信息。问题集中在 /home/src/package-5.0/src 中的 file.c。不幸的是,有太多额外的输出,以至于很难发现重要的细节。学会如何过滤后续的 make 错误,对找出真正的原因大有帮助。
16.6.1 特定错误
以下是您可能会遇到的一些常见编译错误。- src.c:22: conflicting types for 'item'
- /usr/include/file.h:47: previous declaration of 'item'
复制代码 src.c 第 22 行对 item 进行了错误的重新声明。通常可以通过删除违规行(注释、#ifdef 或其他可行的方法)来解决这个问题。- src.c:37: 'time_t' undeclared (first use this function)
- --snip--
- src.c:37: parse error before '...'
复制代码 程序员忘记了一个重要的头文件。手册页面是查找丢失的头文件的最佳途径。首先,查看错误行(本例中为 src.c 中的第 37 行)。可能是下面这样的变量声明:在程序中向前搜索 v1,看它是否用于函数调用。例如现在运行 man 2 time 或 man 3 time 查找名为 time() 的系统和库调用。在这种情况下,第 2 部分的手册页面中就有你需要的内容:- SYNOPSIS
- #include <time.h>
- time_t time(time_t *t);
复制代码 这意味着 time() 需要 time.h。将 #include 放在 src.c 的开头,然后再试一次。- src.c:4: pkg.h: No such file or directory
- (long list of errors follows)
复制代码 编译器在 src.c 上运行了 C 预处理器,但找不到 pkg.h 包含文件。源代码可能依赖于你需要安装的库,或者你可能只需要向编译器提供非标准的包含路径。通常情况下,你只需在 C 预处理器标志 (CPPFLAGS) 中添加一个 -I 包括路径选项(请记住,你可能还需要一个 -L 连接器标志来配合包括文件)。
如果看起来不像是缺少一个库,那么就有可能是在尝试编译该源代码不支持的操作系统。请查看 Makefile 和 README 文件,了解有关平台的详细信息。
如果你运行的是基于 Debian 的发行版,请在头文件名下尝试使用 apt-file 命令:这可能会找到你需要的开发包。对于使用 yum 的发行版,你可以试试这个:- make: prog: Command not found
复制代码 要编译软件包,系统上需要安装 prog。如果 prog 是 cc、gcc 或 ld 之类的文件,说明系统中没有安装开发工具。另一方面,如果你认为系统上已经安装了 prog,可以尝试修改 Makefile,指定 prog 的完整路径名。
在极少数情况下,如果源代码配置不佳,make 会先编译 prog,然后假定当前目录 (.) 在命令路径中,立即使用 prog。如果您的 $PATH 不包括当前目录,可以编辑 Makefile,将 prog 改为 ./prog。或者,也可以在路径中临时添加 .
16.7 展望未来
我们仅仅介绍了构建软件的基础知识。当你掌握了自己构建软件的诀窍后,不妨试试下面的方法:
学习如何使用 autoconf 以外的构建系统,如 CMake 和 SCons。
为自己的软件建立构建系统。如果你正在编写自己的软件,你需要选择一个构建系统并学会使用它。关于 GNU autoconf 的打包,John Calcote 著的《Autotools》(第 2 版)(No Starch Press,2019 年)可以帮到你。
编译 Linux 内核。内核的编译系统与其他工具完全不同。它有自己的配置系统,专门用于定制自己的内核和模块。如果你了解引导加载器的工作原理,就不会有任何问题。不过,这样做的时候一定要小心;确保你的旧内核始终放在手边,以防无法使用新内核启动。
探索特定发行版的源代码包。Linux 发行版以特殊源码包的形式维护自己版本的软件源代码。有时,你会发现一些有用的补丁,这些补丁可以扩展功能或修复其他未维护软件包中的问题。源码包管理系统包括自动构建工具,如 Debian 的 debuild 和基于 RPM 的 mock。
构建软件通常是学习编程和软件开发的垫脚石。你在本章和前一章中看到的工具揭开了系统软件来源的神秘面纱。下一步就是查看源代码、修改并创建自己的软件,这并不难。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |