源码编译介绍
源码编译安装就是获取到源代码后,在本地计算机上进行编译,将其转换成二进制的可执行文件的过程。
源码编译的特点
1、在编译时根据自己的需求对软件进行定制,启用或禁用特定的功能
2、需要自行解决编译过程中的以来问题,难度较大
3、编译过程时间较长,特别是一些中大型软件
4、编译过程会根据当前系统的环境进行,编译出的二进制文件兼容性更好
GCC 工具
GCC是 GNU Compiler Collection
的缩写,是一种编程语言编译器,广泛用于编译如 C、C++、Objective-C、Fortran、Ada 和其他语言的代码。
GCC发展历程
- 在1980年Richard Stallman 发起GNU项目,旨在创建一个完全自由的操作系统。所以他开发了GCC(最初只是一个C编译器),目的是为了创建一个完全自由的、高质量的编译器,这样软件开发者就不必依赖专有的编译器。
- 1990年时,GCC开始支持更多编程语言,例如C++、Fortran、Ada等
- 2000年左右对GCC的架构进行了优化,发布了GCC3.0版本。
- 2010年至今,GCC也在持续不断地更新和改进
make 工具
make
是一个自动化构建工具,它主要用于控制软件的编译过程。
make发展历程
在1970年末的时候,软件项目开始变得越来越复杂,需要一种工具来自动化构建过程,特别是在多个文件和模块之间存在依赖关系的情况下。Stuart Feldman 在 1977 年左右在贝尔实验室开发了最初的 make 工具。这个版本主要用于 Unix 系统,并且极大地改善了软件构建过程的自动化。
在其最初的版本中,make 工具的主要功能是通过读取一个名为 "Makefile" 的文件来自动化编译和构建过程。这个文件指定了源代码文件之间的依赖关系以及用于生成目标文件的命令。
随着时间的推移,make 已经被移植和扩展到许多不同的操作系统上,并且出现了多种不同的版本和变种,如 GNU Make。
GNU Make 由 Richard Stallman 和其他人开发, 和原始的 make 工具虽然共享相同的基本理念和目的,即自动化软件构建过程,但 GNU Make 不是对原始 make 的直接重写。它们是基于同样的基本概念独立开发的,而 GNU Make 在此基础上增加了更多的功能和灵活性。
ld 工具
ld是一个链接器,链接器的作用是将编译后的目标文件(Object files)合并成一个单独的可执行文件或库文件。
在 GNU 系统中,ld 通常指的是 GNU Linker,它是 GNU 二进制工具集(Binutils)的一部分。与 GCC 一样,GNU Linker 也是开源的,并且支持多种处理器架构和操作系统。
ld更多的是作为编译工具链的一个内部组件,通常与编译器和其他构建工具(如 make)一起使用,以自动化整个构建过程。即不需要用户直接和ld工具交互,ld通常会在编译过程中被编译器(如 gcc)自动调用,或者通过构建工具(如 make)间接调用。
autoconf 工具
autoconf
是一个用于生成可以自动配置软件包以适应多种 Unix-like 系统的脚本的工具。属于GNU系统的一部分。
autoconf
会生成一个配置脚本(通常命名为configure
),该脚本会根据目标系统的特性自动调整软件包的配置。通过这个配置脚本可以检查系统特性,如操作系统类型、可用的库和工具等,然后根据这些信息生成一个适合当前系统的 Makefile。
cmake 工具
cmake 是一个跨平台的自动化构建系统,它使用独立于平台和编译器的配置文件来生成标准的构建文件,如 Unix 的 Makefile 或 Windows 的项目文件。
autoconf
主要应用于类Linux系统,并不完全跨平台,所以就造成了在其它平台上编译困难。基于这种问题,就诞生了cmake这个工具,cmake只需要一个 CMakeLists.txt
文件,就可以生成多种类型的构建系统文件,例如在Linux上就可一构建出Makefile文件。
configure 和 cmake 使用说明
参数选项区别:
- 使用cmake指定编译参数时,需要使用-D来指定参数。参数格式是
-D参数名=value
- 使用coufigure指定编译参数的时候,直接加参数选项即可。参数格式是:
--参数名=value
例如:
# configure
./configure --perfix=/usr/local/apache
# cmake
cmake ../mysql-5.6.51 -DCMAKE_INSTALL_PREFIX=/apps/mysql
重新编译区别:
使用 autoconf 提供的 configure 脚本编译源码时,首次运行 configure 和 make 会在源码目录中生成中间文件和二进制文件。
所以如果编译失败或者需要重新编译,那么将这个源码文件删除重新解压。要么执行对应命令进行清理。
make clean
可以删除大多数之前编译过程中生成的文件,主要是对象文件(.o)和二进制文件make distclean
会进行更彻底的清理,删除包括由 configure 生成的 Makefile 和配置文件在内的更多文件
cmake支持“源外构建”(out-of-source build),所有构建产生的中间文件和最终产物都不会放在源码目录下,而是放在指定的构建目录中。
所以使用cmake生成makefile文件构建时,需要先创建一个构建目录,生成的makefile文件以及编译时产生的相关文件都会存放在这个构建目录下。所以如果构建失败或者重新构建,直接删除这个构建目录,重新创建即可。
源外构建流程:
1、创建一个新目录用于存放编译过程中产生的所有中间文件和最终产物。这个目录可以位于任何地方,只要不是源码目录本身即可
2、使用cd 目录
进入该目录
3、进入该目录后,在该目录下执行 cmake编译指令,将源码目录的路径作为参数传递给它。这个步骤会生成构建所需的文件
例如:
# 执行cmake的时候就是位于构建目录 ../mysql-5.6.51是存放源码的目录
cmake ../mysql-5.6.51 -DCMAKE_INSTALL_PREFIX=/apps/mysql
编译安装步骤
1、下载源码包
一般通过官网下载指定版本的源码包,源码包文件一般以.zip .tar.gz
等结尾
例如:下载NGINX源码包
2、安装编译工具
一般需要安装 gcc make cmake
等。
例如:
sudo apt install gcc make cmake
3、生成 Makefile
下载源码包后,如果里面提供的是 configure脚本,那么可以使用 configure --help
查看相关编译选项以及结合官方文档进行生成Makefile的操作。
例如:
# autoconf
./configure --user=nginx --group=nginx --with-http_ssl_module --prefix=/apps/nginx
#cmake
cmake ../mysql-5.6.51 -DCMAKE_INSTALL_PREFIX=/apps/mysql
权限说明: 该步骤用于生成 Makefile文件,这个过程一般不需要管理员权限,因为它只是在检查系统环境并创建合适的 Makefile。这个过程只影响当前用户的目录。
4、编译源码文件
运行 make 命令时,make 会读取 autoconf或者cmake生成的Makefile文件,并根据其中定义的规则使用 gcc 和 ld(通常是通过 gcc 间接调用),从而完成自动化编译和构建过程。
说明:Makefile 中会定义如何编译源代码、如何链接目标文件以及其他可能的构建步骤。
# -j 用于指定同时使用多少个线程进行编译
make -j 4
权限说明: 这一步是实际的编译过程,它根据 Makefile 中的指令来编译源代码生成可执行文件或库文件。这个步骤通常也不需要管理员权限,因为它只是在当前用户的目录中创建文件。
5、安装到指定位置
编译完成后,make install 命令用于将编译好的二进制文件和其他必要的文件安装到系统的指定位置。这个过程同样是基于 Makefile 中的指令来实现的。
Makefile 文件除了包含编译源代码的规则外,通常还包含安装指令。这些指令定义了如何将编译好的二进制文件、库文件、配置文件等安装到目标系统上的正确位置。
sudo make install
权限说明: make install
用于将编译后的程序安装到系统中,通常会复制文件到 /usr/local/bin、/usr/local/lib 等系统目录。由于这些目录通常对普通用户是只读的,因此执行 make install 通常需要管理员权限。
6、环境准备
以上步骤都完成后,可以配置PATH变量,创建运行该进程的指定用户,以及相关配置文件的配置等操作。
例如:
echo 'PATH=/path/bin:$PATH' > /etc/profile.d/xxx.sh
解决依赖问题
在生成Makefile文件或者进行编译的时候,如果当前的系统环境缺少相关依赖,会导致生成Makefile文件不成功或者编译失败。这个时候需要我们自行解决依赖问题。
查阅相关文档
查看官方文档或源码包中的 README 或 INSTALL 文件
是解决依赖问题的第一步,因为它们通常会列出必需的依赖项。
自行安装方法
使用包管理工具搜索相关的依赖包,然后根据搜索结果选择正确的开发版本包
进行安装。
操作流程
1、使用包管理工具搜索提示缺少的依赖包位于哪个开发包中。
2、搜索完成后,选择这种带 -dev或者 -devel
后缀的软件包进行安装。
debian系列
debian系列使用 apt-file 工具
来所有具体的依赖位于哪个软件包。
# 如果没有安装需要进行安装
sudo apt install apt-file
sudo apt-file update
# 搜索软件包
apt-file search package_name
redhat系列
redhat系列使用yum或dnf的 whatprovides 选项
进行搜索。
yum whatprovides '*/package_name'
软件包后缀说明
- debian系列以
-dev 结尾
。 redhat系列以-devel结尾
以 -dev 或 -devel 结尾
:通常包含了编译时所需的头文件(.h 文件)和开发库(.a 或 .so 文件)。非 -dev 或 -devel结尾
:通常包含运行时所需的二进制文件,包括命令行工具、库的运行时版本(如共享库 .so 文件),以及其他为正常运行软件所需的资源和文件。
例如:提示缺少 libxml-2.0
configure: error: Package requirements (libxml-2.0 >= 2.7.6) were not met:
No package 'libxml-2.0' found
# debian系列
apt-file search libxml-2.0
# redhat系列
dnf whatprovides '*/libxml-2.0'
例如:提示缺少 sqlite3 包
configure: error: Package requirements (sqlite3 > 3.7.4) were not met:
No package 'sqlite3' found
sudo apt-file search sqlite3
例如:提示缺少 zlib
configure: error: Package requirements (zlib >= 1.2.0.4) were not met:
No package 'zlib' found
sudo apt-file search zlib