RHEL9でRPMを自作するサンプル(C言語プログラム)
所用で自分でRPMを作らなくちゃいけなくなったのでメモを残しておきます。
自分の整理のためのメモなので誤字脱字等はご容赦ください。
はじめに
やりたいこと
自作のRPMを作る。
(プログラムはサンプル。今回は自作RPMにフォーカスして記載)
前提
試した環境はRedhatEnterpriseLinux9です。
RPM早わかり図
今回の内容を図にまとめると以下です。

作業内容
面倒なのでrootでやります。()
事前準備
1. 依存関係をセットアップします。
dnf module install rpmdevtools gcc
2. ひな形ディレクトリを生成します。
rpmdev-setuptree
これで事前準備OKです。
ひな形としては以下のようなディレクトリになっているはずです。
rpmbuild/
├── BUILD
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS
サンプルアプリ作成
続いて、C言語のサンプルアプリを作っていきます。
1. ディレクトリ作成
mkdir SOURCES/hello-1.0
これしとかないとあとでこけます。
2. サンプルプログラムを作成する。
SOURCES/hello-1.0/hello.cというファイルで以下を作成します。
#include <stdio.h>
int main() {
// printf()関数で文字列を表示します
printf("Hello, World!\n");
// プログラムの終了ステータスを返します
return 0;
}
3. Tarで固める
cd SOURCES
tar czvf hello-1.0.tar.gz hello-1.0/
Tarで固める必要があるので注意です。
また、ここでディレクトリがないとあとでこけるのでここも注意です。
RPMビルド
お待たせしました。RPMビルドです。
流れとしては以下です。
- レシピを作る(SPEC)
- レシピをもとにソースPRMを作る
- ソースRPMをもとにバイナリRPMを作る。
1. レシピを作る(SPEC)
SPECS/hello.specとして以下ファイルを作成します。
Name: hello
Version: 1.0
Release: 1%{?dist}
Summary: A simple C program
License: GPLv3
Source0: %{name}-%{version}.tar.gz
BuildRequires: gcc
%description
A simple C program that prints "Hello, World!"
%prep
%autosetup
%build
gcc -g -o hello hello.c
%install
install -Dpm 0755 hello %{buildroot}%{_bindir}/hello
%files
%{_bindir}/hello
これがRPMを作るときのレシピになっています。
2. レシピをもとにソースRPMを作る
レシピができたらソースPRMを作ってみます。
rpmbuild -bs SPECS/hello.spec
これをすると、SRPMS/hello-1.0-1.el9.src.rpmというファイルが生成されると思います。
これをもとにして配布用のRPMを作っていくのですね。
3. ソースRPMをもとにバイナリRPMを作る。
ではいよいよバイナリRPMを作ります。
rpmbuild --rebuild SRPMS/hello-1.0-1.el9.src.rpm
これをすると、RPMS/x86_64/hello-1.0-1.el9.x86_64.rpmが生成されると思います。
RPMインストールしてみる
ではインストールして使ってみましょう。
dnf install RPMS/x86_64/hello-1.0-1.el9.x86_64.rpm}
このコマンドでいつもの通りインストールできます。
あとは、コマンドを実行してみておわりですね。
[root@hogehoge rpmbuild]# hello
Hello, World!
[root@hogehoge rpmbuild]#
やってみると案外あっけないです。
というか結構シンプルでいいですね。
中身見てみる
これで終わってしまうと、ただ作っただけになってしまうので、軽く成果物を見ていきます。
バイナリRPM
fileコマンドで見てみると、当然ですがRPMとして認識されていますね。
[root@hogehoge rpmbuild]# file RPMS/x86_64/hello-1.0-1.el9.x86_64.rpm
RPMS/x86_64/hello-1.0-1.el9.x86_64.rpm: RPM v3.0 bin i386/x86_64 hello-1.0-1.el9
[root@hogehoge rpmbuild]#
以下で詳細情報を見ることもできます。
[root@hogehoge rpmbuild]# rpm -qpi RPMS/x86_64/hello-1.0-1.el9.x86_64.rpm
Name : hello
Version: 1.0
~~~ 省略 ~~~
[root@hogehoge rpmbuild]#
ここの項目はSPECで記載したもののプラスアルファですね。
ソースRPM
ではソースRPMを見てみましょう
[root@hogehoge rpmbuild]# cd SRPMS
[root@hogehoge rpmbuild]#
[root@hogehoge rpmbuild]# rpm2cpio hello-1.0-1.el9.src.rpm | cpio -idmv
[root@hogehoge rpmbuild]#
[root@hogehoge rpmbuild]# ls -l
hello-1.0-1.el9.src.rpm
hello1.0.tar.gz
hello.spec
rpm2cpioコマンドで中身を見てみると、C言語プログラムをTarで固めたものとRPMのレシピ(SPEC)であることがわかります。
SPEC・ソースRPM・バイナリRPMの役割
なぜ一旦レシピをもとにソースRPMを作り、バイナリRPMを作るのか、というと以下になります。
- レシピ(SPEC)
- RPM自体の情報(名前など)が記載されている
- ビルドプロセスの定義(どうやってビルドするか)が書かれている)
- ソースRPM
- ソースコードとSPECファイルがまとめられているもの
- これがあることによって、「ビルドをしやすくしている」
- 例えるなら「具材と調理器具」
- バイナリRPM
- コンパイル済み、つまりそのまま実行できるものがまとめられている
- 例えるなら「完成している料理」
おわり
今時LLMでも手伝ってくれるのであまりまとめる意味ないかもですが、自分用のメモとして。
作ってみると案外簡単であることがわかりますね。
Go言語のサンプルアプリとかもやってみたいです。
Discussion