最後更新: 2020-08-20
目錄
- Step1: 安裝所需的 tools
- Step2: 建立 Folder 及 設定檔
- Step3: Get Source & Build
- Step4: 將 compile 好的 binary, so file 安放好
- Step5: Create spec file
- Step6: verify & test a spec file
- Step7: build the source and the binary rpm
- Step8: Installation test (這步驟很重要)
- Macro
- Spec file
- Add Program to PATH
- Install Package
- Troubleshoot
- Doc
Step1: 安裝所需的 tools
# rpm-build: Tool will use to build RPMs from specfiles or SRPM packages
yum install -y rpm-build
Checking:
rpmbuild --version
RPM version 4.11.1
查看 rpmbuild 的 Default setting
rpmbuild --showrc
# rpmlint: spec file checking tools
yum install -y rpmdevtools rpmlint
# redhat-rpm-config: rpmbuild build macros and helper scripts
yum install -y redhat-rpm-config
# Other tools you may need
yum -y groupinstall "Development Tools"
yum -y install unzip wget screen vim
Step2: 建立 Folder 及 設定檔
RPM Build Directories Tree
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
OR
mkdir -p ~/rpmbuild; cd ~/rpmbuild
rpmdev-setuptree # rpmdevtools 提供
執行完它後就會建立
- RPMS: The binary package created by rpmbuild will be stored here
- BUILD: The place where rpmbuild will build the package
- SOURCES: The place where to keep the original software sources
- SPECS: This is where the .spec file will be stored
修改 rpmbuild 的設定檔:
~/.rpmmacros
%_topdir %(echo $HOME)/rpmbuild ...
More info.
Directory Tree
- BUILD # uncompresses source packages and compiles the binaries
- SOURCES # Source files and )atches
- BUILDROOT # temporary software installation directory. ($RPM_BUILD_ROOT = %{buildroot})
- SRPMS # directory contains all the source RPM packages that are built.
- RPMS # directory contains subdirectories with various build architectures
Directory macros
The macros are usually used with rpmbuild --define to specify which directories rpmbuild should use
It is unusual to use them within SPEC files
- %{_topdir} %{getenv:HOME}/rpmbuild
- %{_builddir} %{_topdir}/BUILD
- %{_rpmdir} %{_topdir}/RPMS
- %{_sourcedir} %{_topdir}/SOURCES
- %{_specdir} %{_topdir}/SPECS
- %{_srcrpmdir} %{_topdir}/SRPMS
- %{_buildrootdir} %{_topdir}/BUILDROOT
- %{buildroot} %{_buildrootdir}/%{name}-%{version}-%{release}.%{_arch} # same as $BUILDROOT
Step3: Get Source & Build
Example: google-authenticator
yum install pam-devel
cd /usr/src
wget https://github.com/google/google-authenticator-libpam/archive/refs/heads...
unzip master.zip
cd google-authenticator-libpam-master
./bootstrap.sh
./configure
... google-authenticator version 1.09 Prefix.........: /usr/local Debug Build....: C Compiler.....: gcc -std=gnu99 -g -O2 -Wall Linker.........: /usr/bin/ld -m elf_x86_64 -ldl
make -j # 獲得 .libs/pam_google_authenticator.so
Step4: 將 compile 好的 binary, so file 安放好
cd ~/rpmbuild
mkdir myfile
cp -a /usr/src/google-authenticator*/.libs/pam_google_authenticator.so myfile
cp -a /etc/pam.d/sshd myfile
Step5: Create spec file
spec 一共有 7 個 sections, 它們分別是:
- Introduction
- Prep
- Build
- Install
- Clean
- Files
- Changelog (必須)
cd ~/rpmbuild/SPECS
rpmdev-newspec pam_google_authenticator
vi pam_google_authenticator.spec
# This is a comment (just as example) Name: pam_google_authenticator Version: 1 # 原本 software 的主 Version Release: 1%{?dist} # rpm relase 的 version, output rpm file"-1.el7." Summary: The google_authenticator (first must be uppercase) License: Apache License 2.0 URL: https://github.com/google/google-authenticator-libpam Source0: .... # "rpmbuild -bs .." 會用到它 BuildRequires: gettext BuildRequires: libtool Requires: %description Description with almost 79 characters (first char must be uppercase) %prep %build %install install -m 0755 -d $RPM_BUILD_ROOT/usr/lib64/security install -m 0755 -d $RPM_BUILD_ROOT/etc/pam.d install -m 0755 %{_builddir}/pam_google_authenticator.so $RPM_BUILD_ROOT/usr/lib64/security install -m 0755 %{_builddir}/sshd $RPM_BUILD_ROOT/etc/pam.d %clean [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) /usr/lib64/security/pam_google_authenticator.so %config(noreplace) /etc/pam.d/sshd %changelog * Date Name <E-Mail> version-revision - Summary of changes
說明
Version: 2.0.52 # 原本 software 的主 Version
Release: 1%{?dist} # package's version number, output rpm file 有 "-1.el7."
P.S.
%changelog
%changelog 的 Date 是必須填的 ( Format: Fri Aug 28 2015 )
沒填就會有 Error
SPECS/pam_google_authenticator.spec: E: specfile-error error: bad date in %changelog: Date Name <E-Mail> version-revision
用 rpmdev-bumpspec 去建立/更新 spec 內的 %changelog section
rpmdev-bumpspec # bumps release tags in specfiles.
i.e.
SPECS/pam_google_authenticator.spec 不填以下內容
* Date Name <E-Mail> version-revision - Summary of changes
純 Run 以下 command
rpmdev-bumpspec \
--comment="Initial RPM release" \
--userstring="datahunter <[email protected]>" \
SPECS/pam_google_authenticator.spec
$RPM_BUILD_ROOT
相當於 "Buildroot" Folder. Macro: %{buildroot}
Step6: verify & test a spec file
rpmlint - check common problems in rpm packages
# rpmlint
rpmlint SPECS/pam_google_authenticator.spec
SPECS/pam_google_authenticator.spec: W: no-%prep-section
SPECS/pam_google_authenticator.spec: W: no-%build-section
SPECS/pam_google_authenticator.spec: W: no-%install-section
0 packages and 1 specfiles checked; 0 errors, 3 warnings.
# 查看有什麼 warning
# -i, --info # Display explanations for reported messages
rpmlint -i SPECS/pam_google_authenticator.spec
W: no-%prep-section W: no-%build-section W: no-%install-section
Step7: build the source and the binary rpm
# -bb : build only the binary RPM
# -bs : build only the source RPM
rpmbuild -bb SPECS/pam_google_authenticator.spec
Build 好後的 rpm 會放在 ./RPMS/x86_64
P.S.
rpmbuild -b<stage> fileN.spec
- p Execute %prep
- c Execute %prep, %build
- i Execute %prep, %build, %install, %check
- b Execute %prep, %build, %install, %check, package (bin)
- a Execute %prep, %build, %install, %check, package (bin, src)
- l Check %files list
Step8: Installation test (這步驟很重要)
# List File
rpm -qlp RPMS/x86_64/pam_google_authenticator-1.0-5.x86_64.rpm
/etc/pam.d/sshd /usr/lib64/security/pam_google_authenticator.so
# Install
rpm -ivh RPMS/x86_64/pam_google_authenticator-1.0-5.x86_64.rpm
* 當有檔案與其他 rpm package 檔案相同時就會出 conflict
file /etc/pam.d/sshd from install of pam_google_authenticator-1.0-2.x86_64 conflicts with file from package openssh-server-6.4p1-8.el7.x86_64
Macro
%prep
For prepare(download & unzip & patch) the software source code for building process.
ie. unpacking the archive in Source0
如果自己 compile, 那可以略過此 section
%build
This is the section that is responsible for performing the build.
i.e. make
如果自己 compile, 那可以略過此 section
%install
It executed as sh script just like %prep and %build.
This is the step that is used for the installation. 類似 make install
%builddir -copying-> %buildroot
i.e. Script of the .spec file
%install mkdir -p %{buildroot}/{/etc,/usr/bin} install -m755 ???? %{buildroot}/myprogram
%files
The list of files that will be installed(picked) in the end user 's system.
when you list files in %files section these files are expected to reside within %{buildroot} directory.
Here we consider every file in the BUILD directory to be a part of the package. This is done by placing /* under %files.
%files /*
It also specifies the file attributes and the owner and group owner for each file to be installed.
%defattr
%defattr(<file mode>, <user>, <group>, <dir mode>)
For example:
%files myfile %defattr(-,root,root,755) %{prefix}/bin/*
P.S.
"-" Means: keep the file mode of the file as it was installed
%attr
%attr(<mode>, <user>, <group>) file
Similar to the %defattr macro except that it pertains specifically to the file listed
ie.
[1]
%attr(0755,root,mail) /usr/bin/mutt_dotlock
%clean
Bash script performs cleanup after the rpm build process.
%config 與 %config(noreplace)
To specify configuration files for this package
%config # File from update, edited file in .rpmsave
* %config(noreplace) # rpm command will store the new file with a "rpmnew" extension
For example:
%config /etc/rpmproc.conf
%pre, %post, %preun, and %postun
scripts if you need to have different actions upon installation or uninstallation
Spec file
Requires
Syntax
Set Required: somepackage
i.e.
Requires: somepackage >= 0.5.0, somepackage < 0.6.0
Release
%{dist}
- RHEL 6 .el6.centos
- RHEL 7 .el7.centos
- Fedora 26 .fc26
- Fedora 27 .fc27
i.e.
Release: 1%{?dist}
Output
burp-2.0.52-1.el7.centos.x86_64.rpm
Obsoletes
Obsoletes alter the way updates work.
RPM removes all packages matching obsoletes of packages being installed
rpm -i does not do updates and therefore treats Obsoletes: as Conflicts
For most cases rpm -i should be avoided and "rpm -U" should be used
Add Program to PATH
[方法1]
Adding the PATH in the RPM's post-script,
* script file 必須要是 .sh 尾
* Permission 644 也可以
# cat /etc/profile.d/custom.sh
#!/bin/bash PATH=$PATH:/opt/git/bin export PATH
[方法1]
ln -s /opt/myprog/bin/prog /usr/bin/prom
Install Package
# 用 rpm 安裝唔到有依賴的包
yum install mygit-2.25.4-2.el7.x86_64.rpm
Example: mygit.spec
Name: mygit Version: 2.25.4 Release: 2%{?dist} Summary: Fast Version Control System License: GPLv2 URL: http://git-scm.com/ Source0: https://github.com/git/git/archive/v2.25.4.zip Requires: less Requires: openssh-clients Requires: rsync Requires: zlib >= 1.2 %description Create by Datahunter %prep %build %install mkdir %{buildroot}/opt cp -a /opt/git %{buildroot}/opt %files %defattr(-,root,root,755) /opt/git/* %post # add git to PATH cat > /etc/profile.d/mygit.sh <<'EOF' #!/bin/bash PATH=/opt/git/bin:$PATH EOF %changelog * Thu Aug 20 2020 datahunter <[email protected]> - Initial RPM release
Sign package with gpg
Developer
# generate a gpg key pair
# select: (4) RSA (sign only), key expires in: 3y
gpg --gen-key # gpg --list-keys [email protected]
Real name: MyPackage Email address: [email protected] Comment: RPM Signing Key You selected this USER-ID: "MyPackage (RPM Signing Key) <[email protected]>"
# Export the Public key
# public key file available online so others can verify RPMs
# -a Create ASCII armored output.
gpg --export -a a@b > RPM-GPG-KEY
-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v2.0.22 (GNU/Linux) ... -----END PGP PUBLIC KEY BLOCK-----
#Sign rpm package
# You must set "%_gpg_name" in your macro file(~/.rpmmacros)
# echo "%_gpg_name REALNAME" >> ~/.rpmmacros
rpm --addsign test-1-0.x86_64.rpm
Enter pass phrase: Pass phrase is good. test-1-0.x86_64.rpm.rpm:
# Verify the list of gpg public keys in RPM DB
rpm --import RPM-GPG-KEY
rpm --checksig test-1-0.x86_64.rpm
rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n'
... gpg-pubkey-?-? --> gpg(Real name (Comment) <e-mail>)
End-User
yum.repos.d/MyRepo.repo
... gpgkey=https://URL/gpg.key
OR
rpm --import RPM-GPG-KEY
Troubleshoot
WARNING: 'check-rpaths' detected a broken RPATH and will cause 'rpmbuild' to fail. To ignore these errors, you can set the '$QA_RPATHS'
Fix: 清了這一段
cat ~/.rpmmacros
... %__arch_install_post \ [ "%{buildarch}" = "noarch" ] || QA_CHECK_RPATHS=1 ; \ case "${QA_CHECK_RPATHS:-}" in [1yY]*) /usr/lib/rpm/check-rpaths ;; esac \ /usr/lib/rpm/check-buildroot
Doc
http://rpm-guide.readthedocs.io/en/latest/rpm-guide.html