上一篇《RPM包制作理论基础篇》我们从RPM包制作的原因、原理以及基本概念进行了理论性的介绍,也重点说到了制作rpm包的核心工作是编写或获取spec文件,也叙述性的阐述了当前获取spec的几种方式;而本篇将从具体如何制作RPM包进行介绍,下面我们就通过几个实操来详细讲解我们是如何获取这个核心spec文件以及又是如何通过它进行rpm包制作的。

实操一: 通过模板获取spec文件

本例我们就自己写一个最简单的程序来介绍制作RPM包的过程,程序会生成一个StudyRpm 二进制文件,如执行StudyRpm -h 给一些提示信息;

第一步:生成rpmbuild 工作空间(如果已经有了就不需要了)

[root@localhost ~]# rpmdev-setuptree  //默认生成目录~/rpmbuild

第二步:编写程序代码StudyRpm.cpp,如下:

#include <iostream>
#include <cstring>
using namespace std;

int main(int argc, char** argv)
{
    if (argc == 1) {
        cout<<"#### please intput a parameter -h or -v"<<endl;
        return -1;
    }

    if (0 == strcmp("-h",argv[1])) {
        cout<<"#### Make learning a habit and make excellence your label"<<endl;
    }
    if (0 == strcmp("-v",argv[1])) {
        cout <<"#### Version 1.0"<<endl;
    }

    return 0;
}

第三步:编写Makefile文件内容如下:

CC=g++
SRCS=StudyRpm.cpp
OBJS=$(SRCS:.cpp=.o)
EXEC=StudyRpm
start:$(OBJS)
        $(CC) -o $(EXEC) $(OBJS)
.cpp.o:
        $(CC) -o $@ -c $<
install:StudyRpm
        cp StudyRpm /usr/bin
clean:
        rm -rf $(OBJS) $(EXEC)

第四步:执行如下命令生成StudyRpm.spec 模板文件,并填写内容如下:

[root@localhost StudyRpm]# rpmdev-newspec StudyRpm.spec
Name:           StudyRpm
Version:        1.0
Release:        1%{?dist}
Summary:        studyRpm is a start

License:        GPL
URL:            
Source0:        StudyRpm-%{version}.tar

#BuildRequires:
#Requires:

%description
study make rpm

%prep
%setup -q


%build
%configure
make %{?_smp_mflags}


%install
#rm -rf $RPM_BUILD_ROOT
mkdir -p -m755 $RPM_BUILD_ROOT%{_bindir}
%make_install DESTDIR=$RPM_BUILD_ROOT

install -m 755 StudyRpm $RPM_BUILD_ROOT%{_bindir}

%files
%defattr(-,root,root)
%attr(0755,root,root) %{_bindir}/StudyRpm
%doc

%changelog
* Sun Aug 25 2019 zhb_2011_nuaa@126.com
- this is the first version

第五步:再创建一个空的configure文件,然后将这四个文件放到StudyRpm-1.0目录下并进行压缩,将压缩文件再拷贝到~/rpmbuild/SOURCE目录下,另外StudyRpm.spec再拷贝一份到rpmbuild/SPEC目录下,其实这个文件放在哪无所谓,只是便于后期我们归档和修改方便,所以都将.spec文件放到该目录下;

rpm包怎么做镜像 rpm包如何制作_DropBear


第六步:然后进入~/rpmbuild/SPEC 目录,执行如下命令即可生成相应的rpm包;

[root@localhost SPECS]# rpmbuild -bb StudyRpm.spec

如果没有错误的话,就可以再~/rpmbuild/RPMS 目录下看到相应的rpm包,如下:

rpm包怎么做镜像 rpm包如何制作_DropBear_02


好了,到这里我们这个rpm打包好了,最后一步安装测试一下;

第七步:安装测试

我们可以安装生成的rpm包,然后执行命令StudyRpm,如下所示:

rpm包怎么做镜像 rpm包如何制作_rpm包怎么做镜像_03


我们可以看到我们生成的rpm包安装成功,测试也没有问题;


实操二: 从源码中获取spec文件

实操一例子是我们自己写的程序,也非常简单,实际工作中肯定要比这个复杂;那么本例就以升级OpenSSH 为例,来说明整个RPM包的制作过程是怎样的,首先我的机器已经安装了OpenSSH ,在升级之前我们先查看当前OpenSSH版本信息如下:

[root@localhost SOURCES]# ssh -V
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017

接下来我们将介绍如何通过openssh 最新源代码来制作RPM包,具体步骤如下:

第一步:生成rpmbuild 工作空间(如果已经有了就不需要了)

[root@localhost ~]# rpmdev-setuptree

第二步:下载最新源码

下载连接: https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.0p1.tar.gz

将软件包下载到本地并拷贝到~/rpmbuild/SOURCES目录下

第三步:获取spec文件

这里我们不再通过模板生成然后自己填写内容,因为这个要填写的内容可能会比较多。由于下载的最新源代码中就包含了spec文件,所以就可以直接用这个spec文件了,别人已经帮我们写好了,我们可以根据自己需要对其内容修改;获取spec文件方式是,解压文件openssh-8.0p1.tar.gz并进入到openssh-8.0p1/contrib/redhat目录(对该目录要敏感,一般可能就会有我们需要的spec文件);在该目录下面我们就能看到我们需要的openssh.spec文件了,将该文件拷贝到~/rpmbuild/SPEC目录下即可,操作步骤如下图;

rpm包怎么做镜像 rpm包如何制作_DropBear_04


第四步:执行命令制作rpm包

[root@localhost SPECS]# rpmbuild -bb openssh.spec
error: File /root/rpmbuild/SOURCES/x11-ssh-askpass-1.2.4.1.tar.gz: No such file or directory

出现上面的错误提示,这里我们可以通过修改openssh.spec 文件去解决该问题:

%define no_x11_askpass 0  改成  %define no_x11_askpass 1
%define no_gnome_askpass 0  改成 %define no_gnome_askpass 1

保存后重新制作:

[root@localhost SPECS]# rpmbuild -bb openssh.spec
error: Failed build dependencies:
        openssl-devel < 1.1 is needed by openssh-8.0p1-1.el7.x86_64

如果出现上面的错误,且你和我一样已经安装了openssl-devel,我们可以再次修改openssh.spec文件,注释掉:

#BuildRequires: openssl-devel < 1.1

保存后再次重新制作,如果没有其它错误的话,正常完成后会在~/rpmbuild/RPMS 下生成如下几个openssh*.rpm文件:

rpm包怎么做镜像 rpm包如何制作_rpm包_05


注:上图中openssh开头的就是本次打包生成的,其它两个以StudyRpm开头的是前面实操一生成的。

到这里实操二从源码中直接获取spec文件,完成rpm包制作就完成了,是不是感觉比实操一还要简单。因为不用我们自己写源程序、Makefile,configue文件以及核心文件spec。最后我们再验证安装一下吧!

第五步:安装验证

先卸载掉原来的openssh 并安装这次生成的rpm包即可,安装后我们再次查看ssh版本,如下:

[root@localhost x86_64]# ssh -V
OpenSSH_8.0p1, OpenSSL 1.0.2k-fips  26 Jan 2017

这时root用户一般是无法远程登陆的,需要修改配置文件/etc/ssh/sshd_config内容

将 #PermitRootLogin prohibit-password 替换为 PermitRootLogin yes ,重启sshd服务即可;



附:ssh 远程连接不上解决办法

0、查看sshd服务是否已经启动,如果没有启动sshd服务,再重新试试;

1、查看selinux 是否关闭,没有的话进行关闭,重新试试;

2、将/etc/ssh/目录下以ssh_host开头的文件全部删除,重新生成试试(会自动生成);

3、如果其它用户可以,root用户不可以,修需要修改配置文件/etc/ssh/sshd_config内容

将 #PermitRootLogin prohibit-password 替换为 PermitRootLogin yes ,重启sshd服务试试;

4、删除~/.ssh/knows_hosts文件,再试试;



实操三: 根据configure 文件生成spec文件

有时我们下载的源代码解压后没有看到contrib/redhat目录,但是我们发现有类似*.spec.in文件,这时靠我们直觉该文件可能是用来生成对应.spec文件的。本例以libSDL 为例子进行介绍:

第一步:下载源码SDL_master.zip,地址:https://github.com/SDL-mirror/SDL

第二步:解压 并进入目录SDL-master:

root@localhost zhb]# unzip SDL-master.zip  //解压
[root@localhost zhb]# cd SDL-master //进入目录

解压进入目录后,我们发现存在SDL2.spec.in文件,如下:

rpm包怎么做镜像 rpm包如何制作_OpenSSH_06


第三步:执行configure 生成spec文件,如下:

[root@localhost SDL-master]# ./configure

执行完成以后,我们可以看到目录下就会生成我们想要的SDL2.spec文件了。至于后面怎么再修改spec文件以及通过spec文件生成rpm包我们就不再继续介绍了,方法和上面都是类似的,这里我们就不再赘述了。

注:这里有时没有现成的configure文件,我们就需要生成configure文件,如执行autogen.sh 或者autoconf。



实操四: 通过源码包获取spec文件

针对在RPM 网站上可以找到软件老版本rpm包时,我们通常可以根据老版本的rpm包找到其对应的源码包,即*.src.rpm包,这里的源码包并不是指源代码的压缩包,它除了包含源代码,还包括一些配置文件、服务启动文件,当然还有我们想要的spec文件。拿到spec文件以后我们就可以根据需要修改此文件了,如版本信息一般肯定是要改的;下面将以dropbear 为例,来介绍如何从源码包获取到spec文件。至于后面怎么再修改spec文件以及通过spec文件生成rpm包我们就不再继续介绍了,方法和上面都是类似的。

第一步:打开网页http://rpm.pbone.net/,搜索dropbear

rpm包怎么做镜像 rpm包如何制作_DropBear_07

这里我只选择centos 7,你可以根据自身情况进行筛选;点击搜索:

rpm包怎么做镜像 rpm包如何制作_rpm包怎么做镜像_08


这里我们选择最后一个,进入如下界面,这里我们就可以下载到源码包;

rpm包怎么做镜像 rpm包如何制作_rpm包怎么做镜像_09


在这个页面的最下面,其实我们还能看到最后生成rpm包里面的内容,如下:

rpm包怎么做镜像 rpm包如何制作_rpm包_10


第二步:我们下载到源码包以后,通过如下命令可以查看并获取rpm包获取到我们想要的spec文件;

[root@localhost zhb]# rpm -qpl dropbear-2017.75-1.8.src.rpm  //查看rpm文件
warning: dropbear-2017.75-1.8.src.rpm: Header V3 DSA/SHA1 Signature, key ID 9dbd524d: NOKEY
dropbear-2017.75.tar.bz2
dropbear-keygen.service
dropbear.service
dropbear.spec
[root@localhost zhb]# rpm2cpio dropbear-2017.75-1.8.src.rpm | cpio -ivd //解压rpm包获取文件

我们可以看到该rpm包种含有源代码压缩包、一个spec文件以及另外另外两个service文件;当我们获取到rpm制作核心文件dropbear.spec文件后,再下载最新源码就可以向实操二一样生成rpm包了。这里就不再赘述了。