聊聊linux源码编译

Linux,全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,其内核由林纳斯·本纳第克特·托瓦兹于1991年10月5日首次发布,它主要受到Minix和Unix思想的启发,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的Unix工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。Linux有上百种不同的发行版,如基于社区开发的debian、archlinux,和基于商业开发的Red Hat Enterprise Linux、SUSE、Oracle Linux等。

linux通过编译构建一个软件对大部分程序猿可能比较陌生,最近构建了一个比较老版本的Docker镜像。出于某些需求,只能使用比较老的软件和系统版本。随之而来的就是各种奇怪的报错,甚至源码语法错误。当然,有时候也很难说清楚错误的具体原因。对于用过一段时间linux的用户来说,编译安装软件和windows双击运行,然后一路下一步没有太大区别。事实确实也是如此,linux编译安装一款软件一般只需要三个命令

  • configure 配置构建参数
  • make 编译
  • make install 安装

比较容易出现问题的是configure和make。configure阶段按照参数配置编译选项,比如安装装到哪个目录,启用什么功能和依赖是否缺失等,一般都通过这个命令配置。make命令则是实实在在的编译和连接过程。make install可以理解成就是文件复制到安装目录。幸运的是,所有软件configure时配置安装目录的参数都是--prefix,比如下面nginx的安装命令表示将nginx安装到/usr/local/nginx目录

1
./configure --prefix=/usr/local/nginx

这是编译最常用的选项了。其他选项可以使用-h或–help参数查看,比如下面nginx的部分帮助信息

1
./configure --help
2022-04-15_00-07

有些源码并没有configure可执行文件,比如下面是boost的源码目录

2022-04-15_00-10

能看到源码中没有configure文件。这种就需要看源码目录的INSTALL或者README文件了。当然,对于编译安装很熟练的linux老手看到bootstrap.sh基本也不用看INSTALL。直接查看bootstrap.sh提供的帮助信息即可。(一般来说,编译前先用ls命令看文件夹里有没有绿色的可执行文件,如果类似bootstrap,config,configure等,基本就是编译配置命令,如果有Makefile文件,则可以直接make安装)

1
./bootstrap.sh --help
2022-04-15_00-172022-04-15_00-22

基于此便可以构建boost,构建命令如下

1
2
./bootstrap.sh --with-libraries=program_options ## 仅编译program_options库
./bjam install ## 安装

其实,configure操作并不是必须的,应为configure命令仅仅是配置编译选项,检查依赖是否完整等预处理操作,最终生成Makefile。Makefile后面再说,只需要知道是make命令需要的一个文件,有Makefile就可以使用make进行编译。比如hiredis的源码包就不需要configure。

2022-04-15_00-33

这种安装包使用下面命令编译即可.如果想要改变编译参数则需要修改Makefile

1
make -j 4 && make install

除了make外,还有一个很常用的编译工具是cmake。cmake是一款跨平台项目管理工具,cmake属于make的下层工具,用来生成make所需的Makefile。对于小型项目,直接上手编写Makefile是没有什么问题的。但是对于大型项目,上手直接编写Makefile不是一件简单的事情,应该考虑自动生成Makefile。大多数linux系统可以直接通过包管理工具安装cmake,使用方式也很简单。

1
2
3
4
5
6
// 新建build文件夹,文件夹名称无所谓,习惯上用build。特殊编译方式参考README
mkdir build && pushd build
// 编译
cmake ../
// 安装
make install

相关源码和文献

[nginx]: http://nginx.org/download/nginx-1.21.6.tar.gz
[百度百科]: https://baike.baidu.com/item/Linux/27050?fr=aladdin