LoginSignup
16
24

More than 3 years have passed since last update.

CentOSでRPMパッケージを自作する

Last updated at Posted at 2018-08-13

概要

RPMパッケージを自作する手順です。
Go言語で、hello, worldと表示するだけのプログラムをインストールします。

環境

  • CentOS 6 or 7

Installation

rpmパッケージを作成するための環境を作成します。

$ sudo yum install -y rpm-build
$ sudo yum groupinstall -y 'Development tools'

Goでソース作成

以下を参考に、Go言語の環境と、helloを表示するプログラムを作成してください。

rpmdev-setuptreeのインストール

rpmdev-setuptreeを使うと、コマンド1つでrpmの開発環境を作ることができます。

$ sudo yum install -y rpmdevtools yum-utils

rpmdev-setuptree実行

$ rpmdev-setuptree

すると、以下のディレクトリが自動生成されます。

$ ls -1 ~/rpmbuild/
BUILD
RPMS
SOURCES
SPECS
SRPMS

GOのパッケージを移動

GOのソースをtarで固めたら、生成されたディレクトリにtarファイルを移動します。

$ tar czvf hello-1.0.tar.gz hello
$ cp hello-1.0.tar.gz ~/rpmbuild/SOURCES

rpmdev-setuptreeのtopdirを変更する場合

デフォルトでは、~/rpmbuildが開発ディレクトリとなっています。

$ rpmbuild --showrc | grep _topdir
-14: _topdir    %(echo $HOME)/rpmbuild

変更する場合は、~/.rpmmacrosの%_topdir %(echo $HOME)/rpmbuildのパスを変更します。
以下は/usr/src/rpmbuild/になるように変更する例です。

~/.rpmmacros
-%_topdir %(echo $HOME)/rpmbuild
+%_topdir %{_usrsrc}/rpmbuild

%_smp_mflags %( \
    [ -z "$RPM_BUILD_NCPUS" ] \\\
        && RPM_BUILD_NCPUS="`/usr/bin/nproc 2>/dev/null || \\\
                             /usr/bin/getconf _NPROCESSORS_ONLN`"; \\\
    if [ "$RPM_BUILD_NCPUS" -gt 16 ]; then \\\
        echo "-j16"; \\\
    elif [ "$RPM_BUILD_NCPUS" -gt 3 ]; then \\\
        echo "-j$RPM_BUILD_NCPUS"; \\\
    else \\\
        echo "-j3"; \\\
    fi )

%__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

変更されたことを確認

$ rpmbuild --showrc | grep _topdir
-14: _topdir    %{_usrsrc}/rpmbuild

これでrpmdev-setuptreeを実行すると、/usr/src/rpmbuild/が生成されます。

$ rpmdev-setuptree
$ ls -1 /usr/src/rpmbuild/
BUILD
RPMS
SOURCES
SPECS
SRPMS

SPEC

以降、/root/rpmbuild/をtopディレクトリとしている前提とします。

rpmの定義ファイルとなる、.specファイルを作成します。

$ vi /root/rpmbuild/SPECS/hello.spec
hello.spec
%define name hello
%define version 1.0
%define unmangled_version 1.0
%define release 1
%define _binaries_in_noarch_packages_terminate_build 0

Summary: sample hello world program
Name: %{name}
Version: %{version}
Release: %{release}
License: MIT
Source0: %{name}-%{unmangled_version}.tar.gz
Group: Applications/File
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
Prefix: %{_prefix}
BuildArch: noarch

%define INSTALLDIR %{buildroot}/usr/local/bin

%description
This is a sample program to learn how to make a rpm package.

%prep
rm -rf ${RPM_BUILD_ROOT}

%build

%install
rm -rf %{INSTALLDIR}
mkdir -p %{INSTALLDIR}
tar -C %{INSTALLDIR} -xzf  /root/rpmbuild/SOURCES/%{name}-%{unmangled_version}.tar.gz

%clean
rm -rf %{buildroot}

%files
/usr/local/bin
%defattr(-,root,root)

インストール除外したいファイル、ディレクトリの指定方法

/optにパッケージをインストールした場合の例。
%{buildroot}より下から指定する。

ファイルの場合

%files
/opt
%defattr(-,root,root)
%exclude /opt/appname/.gitignore

アスタリスクも可能

%exclude /opt/appname/.git/*

ディレクトリも同じ要領で指定可能

%exclude /opt/appname/.git

その他、設定値は詳しい内容は、以下を参照

Build

作成した.specファイルを使って、buildをします。
エラーが起きた場合は、適宜対処してください。

$ rpmbuild -bb /root/rpmbuild/SPECS/hello.spec

Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.5EA7HS
+ umask 022
+ cd /root/rpmbuild/BUILD
+ rm -rf /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.j7oCjB
+ umask 022
+ cd /root/rpmbuild/BUILD
+ exit 0
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.lARvVj
+ umask 022
+ cd /root/rpmbuild/BUILD
+ '[' /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64 '!=' / ']'
+ rm -rf /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64
++ dirname /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64
+ mkdir -p /root/rpmbuild/BUILDROOT
+ mkdir /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64
+ rm -rf /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64/usr/local/bin
+ mkdir -p /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64/usr/local/bin
+ tar -C /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64/usr/local/bin -xzf /root/rpmbuild/SOURCES/hello-1.0.tar.gz
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-compress
+ /usr/lib/rpm/redhat/brp-strip /usr/bin/strip
+ /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
+ /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1
+ /usr/lib/rpm/redhat/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-java-repack-jars
Processing files: hello-1.0-1.noarch
Provides: hello = 1.0-1
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
warning: Arch dependent binaries in noarch package
Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64
Wrote: /root/rpmbuild/RPMS/noarch/hello-1.0-1.noarch.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.t4IR5L
+ umask 022
+ cd /root/rpmbuild/BUILD
+ rm -rf /root/rpmbuild/BUILDROOT/hello-1.0-1.x86_64
+ exit 0

buildをすると、/rootの下に以下のディレクトリが生成されます。

BUILD
BUILDROOT
RPMS
SRPMS

また、以下のファイルが生成されます。

$ ls -l /root/rpmbuild/RPMS/noarch/hello-1.0-1.noarch.rpm
-rw-r--r-- 1 root root 370740 Aug 13 08:15 RPMS/noarch/hello-1.0-1.noarch.rpm

Install

作成された.noarch.rpmファイルを使ってインストールをします。

$ rpm -ivh /root/rpmbuild/RPMS/noarch/hello-1.0-1.noarch.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:hello-1.0-1                      ################################# [100%]

インストール確認

$ rpm -qa | grep hello
hello-1.0-1.noarch

$ rpm -qp /root/rpmbuild/RPMS/noarch/hello-1.0-1.noarch.rpm
hello-1.0-1.noarch

Run

helloコマンドを実行して、hello, worldと表示されれば成功です。

$ hello
hello, world

Uninstall

アンイストールは以下の手順出来ます。

$ rpm -ev hello-1.0-1.noarch
Preparing packages...
hello-1.0-1.noarch

応用

ソースファイル以外に、設定ファイルや、binファイルを、それぞれソースとは別のディレクトリに設置する例です。

要件

このようなディレクトリ構造のアプリケーションを、

sample_app
├── bin
├── conf
├── src
└── systemd

以下の様なディレクトリ構造で展開したい。

インストール先
bin/* /usr/local/bin
conf/* /etc/sample_app
src/* /opt/sample_app
systemd/* /etc/systemd/system

1行目の説明をすると、bin配下のものは全て/usr/local/bin配下に設置という意味です。

tarファイルを作成

$ tar zcf /root/rpmbuild/SOURCES/sample_app.tar.gz sample_app/*

specファイルを作成

/root/rpmbuild/SPECS/sample_app.spec

sample_app.spec
%define name sample_app
%define version 1.0
# buildコマンドの引数で渡す。後述参照。version 1.0-1となる。
%define release 1%{?dist}
%define _binaries_in_noarch_packages_terminate_build 0

Summary: This is a sample python package.
Name: %{name}
Version: %{version}
Release: %{release}
License: MIT
Source0: %{name}.tar.gz
Group: Applications/File
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
Prefix: %{_prefix}
BuildArch: noarch

# BUILDディレクトリ
%define BUILD_DIR ${HOME}/rpmbuild/BUILD/sample_app
# ソースのインストールディレクトリ
%define INSTALL_DIR %{buildroot}/opt
# Pythonのsite-packagesのディレクトリ
%define PY_PKG_DIR %{INSTALL_DIR}/%{name}/site-packages
# binファイルを設置するディレクトリ
%define BIN_DIR %{buildroot}/usr/local/bin
# 設定ファイルを設置するディレクトリ
%define CONF_DIR %{buildroot}/etc/sample_app
# systemdを設置するディレクトリ
%define SYSD_DIR %{buildroot}/etc/systemd/system

%description
This is a sample python package.

# rpmをbuildする前の準備
%prep
rm -rf ${RPM_BUILD_ROOT}

# makeのための手順
%build

# installのための手順
%install
rm -rf %{INSTALL_DIR}
mkdir -p %{INSTALL_DIR}
mkdir -p %{PY_PKG_DIR}
mkdir -p %{BIN_DIR}
mkdir -p %{CONF_DIR}
mkdir -p %{SYSD_DIR}

# tarファイルを解凍
tar zxfv %{SOURCE0}

# 各ファイルを設置
mv %{BUILD_DIR}/src/*  %{INSTALL_DIR}/sample_app
mv %{BUILD_DIR}/bin/*  %{BIN_DIR}
mv %{BUILD_DIR}/conf/*  %{CONF_DIR}
mv %{BUILD_DIR}/systemd/*  %{SYSD_DIR}

# pipモジュールをインストール
cd %{INSTALL_DIR}/%{name}/pkg && PYTHONPATH='%{PY_PKG_DIR}' python setup.py install --install-lib %{PY_PKG_DIR}
pip install -r %{INSTALL_DIR}/%{name}/requirements.txt -t %{PY_PKG_DIR}

# rpmを作った後の処理
%clean
rm -rf %{buildroot}

# rpm展開後に行うコマンド
%post
systemctl enable service_name
systemctl start service_name

# rpmパッケージアンイストール後に実行するコマンド
# アンイストールのときだけ実行されるようにif文を追加
# 参考: https://qiita.com/ymko/items/80e78bfc8cbf4cee2186
%postun
if [ $1 -eq 0 ]; then
  rm -f /usr/local/bin/sample01
  rm -f /usr/local/bin/sample02
fi

# 設置するファイル。${RPM_BUILD_ROOT}より下から書く
%files
# ソースのインストールディレクトリ
/opt
# binファイルを設置するディレクトリ
/usr/local/bin
# 設定ファイルを設置するディレクトリ
/etc/sample_app
# systemdを設置するディレクトリ
/etc/systemd/system
# ディレクトリの権限
%defattr(-,root,root)
# 設置をしない、除外するディレクトリ
%exclude /opt/%{name}/wrapper/tests
%exclude /opt/%{name}/luigi/tests
# ${RPM_BUILD_ROOT}/usr/doc/sample_app-1.0-1にコピーされる
%doc README.md

Build

--define "dist .el7"のオプションを付けることで、specファイル内の%{?dist}に値が渡ります。

$ sudo rpmbuild -bb /root/rpmbuild/SPECS/sample_app.spec --define "dist .el7"

ファイルが作成されたことを確認

$ sudo ls /root/rpmbuild/RPMS/noarch/
sample_app-1.0-1.el7.noarch.rpm

Install

$ sudo rpm -ivh /root/rpmbuild/RPMS/noarch/sample_app-1.0-1.el7.noarch.rpm

これで、以下のそれぞれのディレクトリの下に、ファイルが展開されます。

  • /usr/local/bin
  • /etc/sample_app
  • /opt/sample_app
  • /etc/systemd/system

追記

python3でビルドする場合は、.specに以下を追記して、インタプリタをpython3にする必要あり。

%global __python %{__python3}

確認

%install
%{__python} -V
%{__python} -m pip -V

参考:https://fedoraproject.org/wiki/Archive:PackagingDrafts/Python3?rd=PackagingDrafts/Python3

参考

16
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
24