Example:
Redis packaging (FPM tool)
Nginx packaging RPM (FPM tool)
Nginx (SPEC file packaging)
Redis (SPEC file packaging)
1. Packaging with FPM tools
1. Update yum software source
yum update
2. Install fpm module dependencies
yum -y install ruby rubygems ruby-devel
3. Change rubygems warehouse
- View current source
gem source list
2. Change Alibaba source
gem sources -a http://mirrors.aliyun.com/rubygems/
3. Remove native sources
gem sources --remove https://rubygems.org/
4. Install fpm tool
gem install fpm
Possible problems:
Reason: ruby supports up to 2.0.0 in yum in centos7, while fpm installation requires ruby to support up to 2.3.0.
Solution:
- Install RAM key (choose one of the two, try again if failed)
Command one:
gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
Command two:
command curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -
command curl -sSL https://rvm.io/pkuczynski.asc | gpg2 --import -
- Install RAM (frequently fails, try again until successful)
curl -L get.rvm.io | bash -s stable
- Update configuration file
source /etc/profile.d/rvm.sh
- View installable scripts
rvm list known | grep ruby
- Install ruby 2.6
rvm install 2.6
- View current ruby version
ruby -v
5. Check whether it is installed correctly
fpm --help
6. fpm parameters
Common parameters
1.-s specifies the source type
2.-t specifies the target type, that is, what package you want to make
3.-n specifies the name of the package
4.-v specifies the version number of the package
5.-C specifies the relative path of the package Change directory to here before searchingforfiles
6.-d Specify which packages it depends on
7.-f If there is an installation package with the same name in the directory when packaging for the second time, overwrite it
8.-p The directory of the output installation package does not want to be placed in the current directory You need to specify
9. –before-install the script to be run before the software package is installed; the same as –pre-install (deprecated)
10. –after-install the script to be run after the software package is installed; the same as –post-install( Deprecated)
11. –before-remove The script to be run after the software package is uninstalled; the same as –pre-uninstall (deprecated)
12. –after-remove The script to be run after the software package is uninstalled; the same as –post- uninstall (deprecated)
For more parameter details, please go to the FPM official website: https://fpm.readthedocs.io/en/latest/cli-reference.html
7. Install software
Compile and install the source code software. Depends on the software. It is recommended to store a compiled software in a designated place.
8. Write shell scripts
Take Nginx as an example:
#!/bin/bash
# 源码编译一般都要添加执行用户
useradd nginx -M -s /sbin/nologin
9. Packing
Packaging format:
fpm -s 源文件类型 -t 目标文件类型 -n 打包后名称 -v 打包后版本号 -d 所需要依赖 --post-install 安装完后执行的脚本 -f 源文件地址
Take Nginx as an example:
fpm -s dir -t rpm -n nginx -v 1.20.1 -d 'pcre-devel,openssl-devel' --post-install /root/rpm_building/ngnix_rpm.sh -f /opt/nginx/
Parameter Description:
1.-s specifies the source type
2.-t specifies the target type, that is, what package you want to make
3.-n specifies the name of the package
4.-v specifies the version number of the package
5.-d specifies which packages it depends on
6.- f If there is an installation package with the same name in the directory during the second packaging, it will be overwritten.
7. –post-install script to be run after the software package is installed; the same as –after-install
Possible errors:
- Need executable ‘rpmbuild’ to convert dir to rpm {:level=>:error}
Solution: install rpm-build
yum install rpm-build -y
10.Install rpm package
Method 1: Install using rpm command (offline trouble)
Install using rpm command
rpm -ivh nginx-1.20.1-1.x86_64.rpm
Direct installation with this method will cause dependency errors. You need to install dependencies using yum or manually before installing the rpm package.
Method two: yum command installation (simple online)
yum -y localinstall nginx-1.20.1-1.x86_64.rpm
This method will install dependencies first and then install the rpm package.
11. Points to note
- Test the software compiled under centos7 environment and it can run under centos8; the software compiled under centos8 cannot run on centos7.
2. Native rpmbuild package rpm package
1. Packaging process
- Place the source code in %_sourcedir
- Unzip the source code into %_builddir and compile it
- Install the compiled software into %_buildrootdir
- Write SPEC files and store them in other directories
- Execute the packaging program and store the packaged binary rpm package in %_rpmdir, and the source rpm package file in %_srcrpmdir.
default location | Macro code | name | use |
---|---|---|---|
~/rpmbuild | is %_top | workspace directory | Save related files when rpmbuild |
~/rpmbuild/SPECS | %_specdir | Spec file directory | Save the RPM package configuration (.spec) file |
~/rpmbuild/SOURCES | %_sourcedir | Source code directory | Save source code packages (such as .tar packages) and all patches |
~/rpmbuild/BUILD | %_builddir | Build directory | The source code package is decompressed here and compiled in a subdirectory of this directory. |
~/rpmbuild/BUILDROOT | %_buildrootdir | Final installation directory | Save files installed during the %install phase |
~/rpmbuild/RPMS | is %_rpm | Standard RPM package directory | Generate/save binary RPM package |
~/rpmbuild/SRPMS | %_srcrpmdir | Source code RPM package directory | Generate/save source code RPM package (SRPM) |
The difference between source rpm package and binary rpm package:
- After the source code rpm package is run, the source code file appears. To run the program, you need to run make to compile it. Packaging principle: compress the source code file directory, the same as the compressed package.
- You can run the file directly after decompressing the binary rpm package. Packaging principle: Compile and install the source code package first, and then package the installed files.
2.SPEC file
SPEC file description:
stage | directory to read | Directory to write to | specific actions |
---|---|---|---|
%prep | %_sourcedir | %_builddir | Read %_sourcedir the source code and patches located in the directory. After that, unzip the source code into %_builddir a subdirectory and apply all patches. |
%build | %_builddir | %_builddir | Compile %_builddir the files located in the build directory. This is achieved by executing a similar ./configure && make command. |
%install | %_builddir | %_buildrootdir | Reads %_builddir files located in the build directory and installs them into %_buildrootdir the directory. These files are the files that users finally get after installing RPM. Note an oddity: the final installation directory is not the build directory. This is achieved by executing a similar make install command. |
%check | %_builddir | %_builddir | Check that the software is functioning properly. This is achieved by executing a similar make test command. Many software packages do not require this step. |
bin | %_buildrootdir | is %_rpm | Read %_buildrootdir the files located in the final installation directory to %_rpmdir create the RPM package in the final directory. In this directory, RPM packages for different architectures will be saved in different subdirectories, and noarch the directory stores RPM packages applicable to all architectures. These RPM files are the RPM packages ultimately installed by users. |
src | %_sourcedir | %_srcrpmdirb | Create a source code RPM package (SRPM for short, as .src.rpm the suffix name) and save it to %_srcrpmdir the directory. SRPM packages are commonly used for auditing and upgrading software packages. |
3. Macro definition file
Macro definition:
Macro format –> %_topdir
Macro represents a variable, such as an environment variable. This variable points to a path or other meaning.
Find the rpmbuild definition file
rpmbuild --showrc | grep Macro
From this picture, you can see that macros can be defined in many places.
Query macro command path
rpmbuild --showrc | grep _mandir
Definition of commonly used macro files
%{_sysconfdir} /etc
%{_prefix} /usr
%{_exec_prefix} %{_prefix}
%{_bindir} %{_exec_prefix}/bin
%{_libdir} %{_exec_prefix}/%{_lib}
%{_libexecdir} %{_exec_prefix}/libexec
%{_sbindir} %{_exec_prefix}/sbin
%{_sharedstatedir} /var/lib
%{_datarootdir} %{_prefix}/share
%{_datadir} %{_datarootdir}
%{_includedir} %{_prefix}/include
%{_infodir} /usr/share/info
%{_mandir} /usr/share/man
%{_localstatedir} /var
%{_initddir} %{_sysconfdir}/rc.d/init.d
%{_var} /var
%{_tmppath} %{_var}/tmp
%{_usr} /usr
%{_usrsrc} %{_usr}/src
%{_lib} lib (lib64 on 64bit multilib systems)
%{_docdir} %{_datadir}/doc
%{buildroot} %{_buildrootdir}/%{name}-%{version}-%{release}.%{_arch}
$RPM_BUILD_ROOT %{buildroot}
4. Install rpmbuild tool
yum install rpm-build -y
5. Establish a working path
Create rpmbuild/BUILD, rpmbuild/RPMS, rpmbuild/SOURCES, rpmbuild/SPECS, rpmbuild/SRPMS directories respectively in the home directory.
mkdir -p ~/rpmbuild/{
BUILD,RPMS,SOURCES,SPECS,SRPMS}
Folder meaning:
default location | Macro code | name | use |
---|---|---|---|
~/rpmbuild | is %_top | workspace directory | Save related files when rpmbuild |
~/rpmbuild/SPECS | %_specdir | Spec file directory | Save the RPM package configuration (.spec) file |
~/rpmbuild/SOURCES | %_sourcedir | Source code directory | Save source code packages (such as .tar packages) and all patches |
~/rpmbuild/BUILD | %_builddir | Build directory | The source code package is decompressed here and compiled in a subdirectory of this directory. |
~/rpmbuild/BUILDROOT | %_buildrootdir | Final installation directory | Save files installed during the %install phase |
~/rpmbuild/RPMS | is %_rpm | Standard RPM package directory | Generate/save binary RPM package |
~/rpmbuild/SRPMS | %_srcrpmdir | Source code RPM package directory | Generate/save source code RPM package (SRPM) |
6. Download source code
cd ~/rpmbuild/SOURCES
wget http://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz
7.Write SPEC file
cd ~/rpmbuild/SPECS
vim hello.spec
After the spec file is entered, the template will be automatically loaded. The initial look of the template is as follows:
The prepared file is as follows:
# 软件名
Name: hello
# 版本号
Version: 2.10
# 发布编号
Release: 1%{
?dist}
# 软件说明
Summary: The "Hello World" program from GNU
Summary(zh_CN): GUN "Hello Word" 程序
# 包所属类别,但目前基本已经被弃用,直接删除即可
Group: Applications/Productivity
# 软件包的版权协议
License: GPLv3+
URL: http://ftp.gnu.org/gnu/hello
Source0: http://ftp.gnu.org/gnu/hello/%{
name}-%{
version}.tar.gz
# 编译需要的依赖
BuildRequires: gettext
# 本软件需要的依赖
#Requires:
# 安装后的依赖
Requires(post): info
# 卸载前的依赖
Requires(preun): info
# 描述
%description
The "Hello World" program, done with all bells and whistles of a proper FOSS
project, including configuration, build, internationalization, help files, etc.
%description -l zh_CN
"Hello World" 程序, 包含 FOSS 项目所需的所有部分, 包括配置, 构建, 国际化, 帮助文件等.
%prep
%setup -q
# 编译阶段执行的命令
%build
%configure
make %{
?_smp_mflags}
# 安装阶段执行的命令
%install
make install DESTDIR=%{
buildroot}
# 查找 install 中的语言文件
%find_lang %{
name}
rm -f %{
buildroot}/%{
_infodir}/dir
# 安装后执行的命令
%post
/sbin/install-info %{
_infodir}/%{
name}.info %{
_infodir}/dir || :
# 卸载前执行的命令
%preun
if [ $1 = 0 ] ; then
/sbin/install-info --delete %{
_infodir}/%{
name}.info %{
_infodir}/dir || :
fi
# 将所需要打包的文件都存放到这边中;-f %{name}.lang 加上后的意思为声明找到的文件
%files -f %{
name}.lang
# doc添加的是说明文档
%doc AUTHORS ChangeLog NEWS README THANKS TODO
%license COPYING
%{
_mandir}/man1/hello.1.*
%{
_infodir}/hello.info.*
%{
_bindir}/hello
# 软件更新说明
%changelog
* Sun Dec 4 2016 Your Name <[email protected]> - 2.10-1
- Update to 2.10
* Sat Dec 3 2016 Your Name <[email protected]> - 2.9-1
- Update to 2.9
8. Check the correctness of the SPEC file
rpmlint hello.spec
9. Build rpm package
cd ~/rpmbuild/SPECS
rpmbuild -ba hello.spec
Check out the output below:
tree ~/rpmbuild/*RPMS