说明:写这篇文章的目的最初是因为mysql编译的时间太长,每次太耗费时间,突然想能不能一次编译在其它地方移植呢!
一 回顾下安装软件的三种方式
(1)编译安装软件,优点是可以定制化安装目录、按需开启功能等,缺点是需要查找并实验出适合的编译参数,诸如MySQL之类的软件编译耗时过长。
(2)yum(红帽系列)安装软件,优点是全自动化安装,不需要为依赖问题发愁了,缺点是自主性太差,软件的功能、存放位置都已经固定好了,不易变更。
(3)编译源码,根据自己的需求做成定制RPM包,搭建内网yum仓库,yum安装。缺点就是RPM包的通用性差,只能适用于本公司的环境。另外一般人不会定制RPM包。这是中大型互联网企业运维自动化的必要技能
细节
# 下载证书-->可以通过firefox的形式下载,更换源-->为com而不是org
gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/
缺点:rpmbuild比较晦涩;关于7.5的
包管理基础
操作系统 格式 工具
Debian .deb apt, apt-cache, apt-get, dpkg
Ubuntu .deb apt, apt-cache, apt-get, dpkg
CentOS .rpm yum
Fedora .rpm dnf
FreeBSD Ports, .txz make, pkg
二 rpmbuild制作
概念:rpmbuild 用于创建软件的二进制包和源代码包。一个"包"包括文件的归档以及用来安装和卸载归档中文件的元数据。 元数据包括辅助脚本、文件属性、以及相关的描述性信息。
软件包有两种: 二进制包,用来封装已经编译好的二进制文件; 源代码包,用来封装源代码和要构建二进制包需要的信息。
说明:学习方式,照葫芦画瓢!
预备知识:新旧版本的说明
在旧版本的CentOS中,rpmbuild工具默认的工作路径是/usr/src/redhat,因为权限原因,一般用户身份不能制作rpm软件包,只能切换到root身份才能够制作。
在新版本的CentOS中,可以在一般用户主目录下新建rpmbuild目录作为rpmbuild工具的工作目录。并且在新版本中,发行商建议为了防止系统函数库或其他文件损坏,不要使用root身份去制作rpm软件包
RPM(Redhat Package Manager)是用于Redhat、CentOS、Fedora等Linux 分发版(distribution)的常见的软件包管理器。因为它允许分发已编译的软件,所以用户只用一个命令就可以安装软件。
对比:nginx源码安装
#!/bin/bash
# (0)创建目录
mkdir -p /usr/local/lnmp/nginx
# (1)解压缩
tar zxvf nginx-1.15.8.tar.gz
# (2)一定要进入目录编译
cd nginx-1.15.8/
./configure --prefix=/usr/local/lnmp/nginx --with-http_ssl_module
# 关于安装的模块-->后续介绍常用的!
# (3)安装依赖库
# 例如gzip模块需要zlib库,rewrite模块需要pcre库,ssl功能需要openssl库等
yum install gcc openssl-devel pcre-devel zlib-devel -y
# https的需要(openssl)、正则的需要(pcre)-->需要什么样的功能在编译的时候就编译进去!
./configure --prefix=/usr/local/lnmp/nginx --with-http_ssl_modu
# 编译的时候需不需要指定user和group为nginx!
make && make install
# (4)进入配置目录,修改主配置文件
cd /usr/local/lnmp/nginx/
# nobody改成nginx用户启动
# vim conf/nginx.conf
# (5)创建该用户
useradd -s /sbin/nologin nginx
id nginx
# (6)构建软连接,方便直接运行某些命令-->软连接很重要-->后期的升级和内容的迁移等!
ln -s /usr/local/lnmp/nginx/sbin/nginx /usr/local/bin/
(0)rpmbuild的原理
RPM打包的时候需要编译源码,还需要把编译好的配置文件、二进制命令文件之类的东西按照安装好的样子放到合适的位置,还要根据需要对RPM的包进行测试,这些都需要先有一个“工作空间”。
# spec文件中引用的一些宏变量主要定义在/usr/lib/rpm/macros -->全局-->定义全局的宏代码
# 自定义,在用户当前的家目录中-->工作目录
touch ~/.rpmmacros
核心:制作步骤
最关键的地方,是要清楚虚拟路径的位置,以及宏的定义
(1)必要工具的安装
参照:httpd
说明:编译环境和rpmbuild工具
# 不同版本的可能有所差别-->本文是基于RHEL7.5
yum install make gcc rpm-build
# RPM打包使用的是rpmbuild命令,这个命令来自rpm-build包,这个是必装的
(2)创建制作rpm的工作目录
rpmbuild
命令使用一套标准化的“工作空间”
方式1:手工
核心:为了创建制作rpm的工作目录,你需要在一般用户身份的主目录下新建如下结构的目录
rpmbuild目录,还有该目录下六个目录,包括:BUILD、BUILDROOT、RPMS、SOURCES、SPECS、SRPMS
mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
# 结构如下
[root@random ~]# tree rpmbuild/
rpmbuild/
├── BUILD
├── BUILDROOT
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS
方式2:通过工具自动产生
#(1)安装软件
yum install rpmdevtools -y
# rpmdevtools-8.3-5.el7.noarch 软件包
#(2)制作rpmbuild的工作目录
rpmdev-setuptree
执行此条命令,会在"用户家目录下"生成以6个目录
# 二者还是有差别的-->BUILDROOT
目录结构的说明
理解:几个目录的含义!
“宏代码”这一列就可以在SPEC文件中用来代指所对应的目录,类似于编程语言中的宏或全局变量
~/rpmbuild
这个文件夹也是有宏代码的,叫做%_topdir
SPEC文件:可以理解为编排攻工具、playbook(Ansible的脚本)
# 写 spec 相当于一种脚本编程
(3)打包流程(有点像是流水线,分好几个工序)
1. 首先,需要把源代码放到%_sourcedir中;源代码的放置
2. 然后,进行编译,编译的过程是在%_builddir中完成的,所以需要先把源代码复制到这个目录下边,一般情况下,源代码是压缩包格式,那么就解压过来即可;
3. 第三步,进行“安装”,这里有点类似于预先组装软件包,把软件包应该包含的内容(比如二进制文件、配置文件、man文档等)复制到%_buildrootdir中,并按照实际安装后的目录结构组装,比如二进制命令可能会放在/usr/bin下,那么就在%_buildrootdir下也按照同样的目录结构放置;
4. 然后,需要配置一些必要的工作,比如在实际安装前的准备,安装后的清理,以及在卸载前后要做的工作啦等等,这样也都是通过配置在SPEC文件中来告诉rpmbuild命令;
5. 还有一步可选操作,那就是检查软件是否正常运行;
5. 最后,生成的RPM包放置到%_rpmdir,源码包放置到%_srpmdir下(备选)
以上这些步骤都是配置在SPEC文件中的,具体来说各个阶段
具体操作
rpmbuild所需的
# 1、利用rpmbuild打包,需要两类文件:1、源码,源码以tar归档进行压缩的源码包,以及一些.patch文件,存放于目录./SOURCES下;
# 2、.spec文件,定义了打包的动作,以及依赖,是打包的最主要类容。
第一步:把源码文件放置到 SOURCES 目录下,以nginx为例子(比较简单)
[kiosk@nginx ~]# mv nginx-1.15.8.tar.gz rpmbuild/SOURCES/
# nginx文件也复制到该目录下
第二步:并在SPECS目录下添加配置好的nginx.spec文件
[kiosk@nginx SPECS]$ pwd
/home/kiosk/rpmbuild/SPECS
# 说明:自动有相应的内容生成
[kiosk@nginx SPECS]$ vim nginx.spec
# 不同版本的不一样,但是都是在/usr/share/doc/路径下
less /usr/share/doc/rpm-4.11.3/GROUPS
spec文件的说明
Name: nginx # 软件包名称,后面可使用%{name}引用
Version: 1.15.8 # 软件的版本号,与源码包一致
Release: 1%{?dist} # 发布序列号.后面可使用%{release}引用
Summary: nginx generate rpm # 软件包的内容概要,简要描述信息
# 定义了安装或者编译时的虚拟目录
Group: Development/Tools # 软件分组-->less /usr/share/doc/rpm-4.11.3/GROUPS
License: GPL # 软件授权方式,一定带上(最好是对方源码包的 License ) BSD,GPL,GPLv2
URL: http://nginx.org/download/nginx-1.15.8.tar.gz # #软件的主页
Source0: %{name}-%{version}.tar.gz # source 主要是引用一下自己定义好的脚本,配置文件之类的内容,#源代码包
BuildRequires: # 编译依赖(只有root可以安装,事先安装)
Requires: # 运行依赖
# root事先安装这些软件,才能用普通用户编译--->yum install gcc openssl-devel pcre-devel zlib-devel -y
BuildRoot的理解
# BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
# %{_tmppath}=/var/tmp
# 这是 make install 时使用的“虚拟”根目录也称为“构建根”目录
# 一般会将软件安装在/var/tmp/软件名称-版本号-发布序列号-buildroot/usr/
# 下的bin/ 下(可执行文件)、share/ 下(数据、资源文件)、lib/ 下(共享库文件)
剩余
%description # 用来定义描述软件的详细说明
This is a test for nginx.spec
%prep # 定义脚本预处理的一些操作,如解包打补丁等
%setup -q %{name}-%{version} # 将tar.gz包解压出来;打开软件包,加选项对软件包进行解压处理 去我们的SOURCE目录去找到源码包并解压,这个宏的作用静默模式解压并 cd
%build # 开始编译源码构建包,相当于configure以及make部分
%configure # 编译制作阶段,这一节主要用于编译源码,这个不是关键字,而是rpm定义的标准宏命令。意思是执行源代码的configure配置
make %{?_smp_mflags} # 并行-->优化
%install
make install DESTDIR=%{buildroot}
%files
%doc
%changelog
注意:使用./configure代替了%configure参数,解决了Nginx编译参数--host编译选项找不到的问题
遇到的问题1(必须)
遇到的问题2(非必须)
rpmbuild报error: Installed (but unpackaged) file(s) found的解决办法
vim /usr/lib/rpm/macros
383 %_unpackaged_files_terminate_build 0
# 把1改为0只警告,非必须!
# root执行--->setfacl -m u:kiosk:rwx /usr/local
遇到的问题3(可以忽略)
343 #%_source_payload w9.gzdio
344 #%_binary_payload w9.gzdio
# 在centos6或RHEL6下进行编译的RHEL5或centos5的rpm包
需求1:建立二进制包
-bb build binary package only from <specfile> # 只建立二进制包
rpmbuild -bb nginx.spec
总的文档
[root@nginx SPECS]# cat nginx.spec
Name: nginx
Version: 1.15.8
Release: 1%{?dist}
Summary: nginx generate rpm
Group: Development/Tools
License: GPL
URL: http://nginx.org/download/nginx-1.15.8.tar.gz
Source0: %{name}-%{version}.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) # 创建目录
BuildRequires: gcc make pcre zlib openssl # 最好root先安装
Requires: openssl-devel pcre-devel zlib-devel # 最好root先安装
%description
This is a test for nginx.spec
%prep
%setup -q %{name}-%{version}
%build
mkdir -p /usr/local/lnmp/nginx
./configure --prefix=/usr/local/lnmp/nginx --with-http_ssl_module
make %{?_smp_mflags}
%install
#make install DESTDIR=%{buildroot}
make install
%files
%doc # 该标准定义了文件应该被放置在系统的哪个位置!
%changelog
生成的二进制文件
[root@nginx rpmbuild]# tree RPMS/
RPMS/
└── x86_64
├── nginx-1.15.8-1.el7.x86_64.rpm
└── nginx-debuginfo-1.15.8-1.el7.x86_64.rpm
1 directory, 2 files
测试出现的问题
[root@server1 ~]# rpm -ql nginx # 没有生成对应的配置文件
(contains no files)
# 后续讲解