もはや新しくリリースされた GTK4 の話題から逸れてしまったのでブログのタイトルを改めました。しかし、前回まで取り上げてきた Hello World のプログラム [1] [2] を今回も使用して RPM パッケージ化した例を紹介します。今回のポイントは、make を使わずに meson でビルドすることと、デスクトップ環境用のアプリ起動アイコンを追加することです。
本ブログ記事では下記の OS 環境で動作確認をしています。
Fedora 33 (Workstation Edition)
x86_64
OUTLINE
RPM パッケージとは
RPM, RPM Package Manager は、Red Hat Enterprise Linux (RHEL) などの Linux ディストリビューションで採用されているパッケージ管理システムです。RPM Packaging Guide [3] によると、RPM の特徴は以下の通りです。
RPM の特徴
パッケージのインストール、再インストール、削除、アップグレード、検証
ユーザーは標準的なパッケージ管理ツール (DNF など) を使用して RPM パッケージのインストール、再インストール、削除、アップグレード、検証を行うことができます。
インストールされたパッケージのデータベースを使用して、パッケージの問い合わせと検証を行います。
RPM はインストールされたパッケージとそのファイルのデータベースを管理しているので、ユーザはシステム上のパッケージを簡単に照会して検証することができます。
メタデータを使ってパッケージやインストール手順などを記述
各 RPM パッケージには、パッケージのコンポーネント、バージョン、リリース、サイズ、プロジェクト URL、インストール手順などを記述したメタデータが含まれています。
オリジナルのソフトウェアソースをソースパッケージとバイナリパッケージにパッケージ化
RPM を使用すると、オリジナルのままのソフトウェアソースを、ソースパッケージ (.src.rpm ファイル) とバイナリパッケージ (.x86_64.rpm ファイル等) にパッケージ化してユーザに提供することができます。ソースパッケージでは、使用されたパッチと完全なビルド手順が含まれたオリジナルのままのソースが得られます。
このデザインは、ソフトウェアの新しいバージョンがリリースされたときにパッケージのメンテナンスを容易にします。
パッケージを Yum リポジトリに追加
あなたのパッケージを Yum リポジトリに追加することで、クライアントがあなたのソフトウェアを簡単に見つけてデプロイできるようになります。
パッケージにデジタル署名
GPG 署名鍵を使用すると、パッケージにデジタル署名をすることができるので、ユーザはパッケージの真正性 (authenticity) を確認することができます。
rpm-build パッケージのインストール
RPM パッケージを作成するには、rpm-build パッケージをインストールする必要があります。あと、Red Hat 系のディストロであれば、マクロを定義した redhat-rpm-config もインストールします。
$ sudo dnf install rpm-build redhat-rpm-config
インストールしたパッケージ名は rpm- build ですが、下記のようにパッケージに収録されているファイルのリストを確認して判るように、実際に使用するコマンドはハイフンが無い rpmbuild です。
[bitwalk@fedora-pc /]$ rpm -ql rpm-build
/usr/bin/gendiff
/usr/bin/rpmbuild
/usr/bin/rpmspec
/usr/lib/.build-id
...
(以下省略)
RPM パッケージは、ユーザー権限でホームディレクトリ下に作成します。
ホームディレクトリの下に RPM をビルドするために、下記のようにして rpmbuild ディレクトリとサブディレクトリと、ユーザー用の RPM マクロ設定ファイル .rpmmacros を生成します。
$ mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
$ echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros
作成した rpmbuild 内のサブディレクトリの役割は以下のようになっています。
$HOME/rpmbuild
├── BUILD : コンパイルなどの作業領域
├── RPMS : RPM パッケージ (.x86_64.rpm ファイル等) の出力先(更にアーキテクチャのサブディレクトリが作成されます)
├── SOURCES : ビルドするソースファイルを保存
├── SPECS : ビルドする方法を記載したスペックファイルを保存
└── SRPMS : RPM ソースファイル (.src.rpm) の出力先
この他に、$HOME/rpmbuild/BUILDROOT という、パッケージを仮想インストールする際に使用するルートのディレクトリが、パッケージをビルドする際に作成されます。
ビルドするソースファイルのダウンロード
RPM パッケージにビルドするソースファイルをダウンロードします。これは、以前のブログ記事 [2] で取り上げた Meson でビルドする Hello World のプログラムに、デスクトップ環境に必要な起動用アイコンと、RPM をビルドするのに必要なスペックファイルを加えたものです。下記 Github からブラウザでダウンロードするか、wget コマンドでダウンロードします。
インターネットブラウザの場合
インターネットブラウザで Github の URL にアクセスしてダウンロードするには、下記のようにクリックして、hello-world-gtk-1.0.zip を $HOME/rpmbuild/SOURCES 内へ保存 します。
Github のサイトから zip ファイルをダウンロードする場合
wget コマンドの場合
wget コマンドでダウンロードする場合、~/rpmbuild/SOURCES へカレントディレクトリを移して、ダウンロードするファイル名を hello-world-gtk-1.0.zip に指定して wget コマンドでダウンロードします。
[bitwalk@fedora-pc ~]$ cd ~/rpmbuild/SOURCES
[bitwalk@fedora-pc SOURCES]$ wget -O hello-world-gtk-1.0.zip https://github.com/bitwalk123/hello-world-gtk/archive/1.0.zip
--2020-12-23 18:49:39-- https://github.com/bitwalk123/hello-world-gtk/archive/1.0.zip
github.com (github.com) をDNSに問いあわせています... 52.192.72.89
github.com (github.com)|52.192.72.89|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 302 Found
場所: https://codeload.github.com/bitwalk123/hello-world-gtk/zip/1.0 [続く]
--2020-12-23 18:49:39-- https://codeload.github.com/bitwalk123/hello-world-gtk/zip/1.0
codeload.github.com (codeload.github.com) をDNSに問いあわせています... 13.112.159.149
codeload.github.com (codeload.github.com)|13.112.159.149|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 特定できません [application/zip]
`hello-world-gtk-1.0.zip' に保存中
hello-world-gtk-1.0 [ <=> ] 4.35K --.-KB/s 時間 0.001s
2020-12-23 18:49:40 (7.84 MB/s) - `hello-world-gtk-1.0.zip' へ保存終了 [4455]
[bitwalk@fedora-pc SOURCES]$ ls
hello-world-gtk-1.0.zip
[bitwalk@fedora-pc SOURCES]$
スペックファイル
RPM パッケージを作成するには、まずパッケージを作成する方法をまとめた拡張子が .spec のスペックファイルを用意する必要があります。
ダウンロードした hello-world-gtk-1.0.zip 内に、このソースファイルをビルドするスペックファイルが含まれていますので、該当するファイルだけ抽出して利用します。
端末エミュレータを起動して ~/rpmbuild/SOURCES へカレントディレクトリを移し、ダウンロードした hello-world-gtk-1.0.zip 内のファイルリストを表示します。
[bitwalk@fedora-pc SOURCES]$ unzip -vl hello-world-gtk-1.0.zip
Archive: hello-world-gtk-1.0.zip
0c232888beaa78f0d30eb1679c5530fc1ee11e7d
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
0 Stored 0 0% 12-24-2020 08:42 00000000 hello-world-gtk-1.0/
1211 Defl:N 692 43% 12-24-2020 08:42 85ee1060 hello-world-gtk-1.0/LICENSE
600 Defl:N 345 43% 12-24-2020 08:42 3e6e6443 hello-world-gtk-1.0/README.md
1014 Defl:N 450 56% 12-24-2020 08:42 983da16d hello-world-gtk-1.0/hello-world-gtk.c
732 Defl:N 411 44% 12-24-2020 08:42 0f9fa688 hello-world-gtk-1.0/hello-world-gtk.spec
176 Defl:N 133 24% 12-24-2020 08:42 032e1b2b hello-world-gtk-1.0/hello.desktop
5012 Defl:N 917 82% 12-24-2020 08:42 5c3bae6b hello-world-gtk-1.0/hello.svg
357 Defl:N 201 44% 12-24-2020 08:42 a782a4de hello-world-gtk-1.0/meson.build
-------- ------- --- -------
9102 3149 65% 8 files
hello-world-gtk-1.0.zip 内の hello-world-gtk-1.0/hello-world-gtk.spec だけを抽出して、$HOME/rpmbuild/SPECS (../SPECS) へ、hello-world-gtk.spec として出力します。
[bitwalk@fedora-pc SOURCES]$ unzip -p hello-world-gtk-1.0.zip hello-world-gtk-1.0/hello-world-gtk.spec > ../SPECS/hello-world-gtk.spec
[bitwalk@fedora-pc SOURCES]$ cd ../SPECS
[bitwalk@fedora-pc SPECS]$ ls
hello-world-gtk.spec
[bitwalk@fedora-pc SPECS]$
スペックファイル hello-world-gtk.spec の内容は以下のようになっています。
hello-world-gtk.spec
このスペックファイルは最小限の構成ですが、以下のようになっています。
スペックファイル hello-world-gtk.spec の構成
基本情報、データ定義部
インストール後に、パッケージに関する問い合わせの際に返す情報、パッケージ作成時に必要となるタグ、パッケージの依存関係を示すタグを記述します。
%description にパッケージの詳しい説明を記述します。
スクリプト部
パッケージのビルドやインストール等の手順を記述します
%prep セクション
ソースをビルドする前に実施する準備する処理をシェルスクリプトで記述します。
%autosetup マクロで、SOURCES にある圧縮ファイルを BUILD 内に展開します。
%build セクション
ソースをビルドする手順をスクリプトで記述します。
%meson マクロでセットアップします。
%meson_build マクロでコンパイルします。
%install セクション
${RPM_BUILD_ROOT} の下にインストールするスクリプトを記述します。
%meson_install マクロでインストールします。
%check セクション
ビルドしたバイナリが正常に動作することを check するスクリプトの記述します。
%meson_test マクロでテストでテストします。
%files : ファイルリスト部
RPM パッケージに収録するファイル名を列挙します。
%doc マクロで README など、インストールするソフトウェアに関する文書などを指定します。
%license マクロで、ライセンス関係の文書を指定します。
%{_bindir} , %{_libdir} , %{_includedir} , %{_datadir} などを使って、インストールファイルをくまなく指定します。
%changelog : パッケージの更新履歴
パッケージの更新履歴を最新の更新情報が上にくるように記述します。
※ スペックファイルにはたくさんのマクロが使われていますが、一般的なマクロは /usr/lib/rpm/macros で定義されています。また、ツールなどに依存するマクロは /usr/lib/rpm/macros.d/ 内にある macros. で始まるファイルで定義されています。
参考サイト [4] が判りやすくまとめられていると思いますので、ご興味がある方はぜひご覧になってください。
RPM パッケージをビルド
スペックファイルを作成するときには、
rpmbuild -bp specfile : %prep (ソース展開と patch の適用)まで実行
rpmbuild -bc specfile : %build(%prep とコンパイル)まで実行
rpmbuild -bi specfile : %install (%prep, %build, インストール)まで実行
rpmbuild -ba specfile : RPM バイナリ / ソースパッケージ作成
という順番で、作りながら動作確認をしていきますが、今回は出来上がっているスペックファイルを使いますので、最後の rpmbuild -ba specfile を実行します。
少し長くなりますが、コマンド実行時の出力を全て掲載します。
[bitwalk@fedora-pc SPECS]$ rpmbuild -ba hello-world-gtk.spec
setting SOURCE_DATE_EPOCH=1608681600
実行中(%prep): /bin/sh -e /var/tmp/rpm-tmp.LAXzRE
+ umask 022
+ cd /home/bitwalk/rpmbuild/BUILD
+ cd /home/bitwalk/rpmbuild/BUILD
+ rm -rf hello-world-gtk-1.0
+ /usr/bin/unzip -qq /home/bitwalk/rpmbuild/SOURCES/hello-world-gtk-1.0.zip
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd hello-world-gtk-1.0
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ RPM_EC=0
++ jobs -p
+ exit 0
実行中(%build): /bin/sh -e /var/tmp/rpm-tmp.ebmREC
+ umask 022
+ cd /home/bitwalk/rpmbuild/BUILD
+ cd hello-world-gtk-1.0
+ CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
+ export CFLAGS
+ CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
+ export CXXFLAGS
+ FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules'
+ export FFLAGS
+ FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules'
+ export FCFLAGS
+ LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld '
+ export LDFLAGS
+ LT_SYS_LIBRARY_PATH=/usr/lib64:
+ export LT_SYS_LIBRARY_PATH
+ CC=gcc
+ export CC
+ CXX=g++
+ export CXX
+ /usr/bin/meson --buildtype=plain --prefix=/usr --libdir=/usr/lib64 --libexecdir=/usr/libexec --bindir=/usr/bin --sbindir=/usr/sbin --includedir=/usr/include --datadir=/usr/share --mandir=/usr/share/man --infodir=/usr/share/info --localedir=/usr/share/locale --sysconfdir=/etc --localstatedir=/var --sharedstatedir=/var/lib --wrap-mode=nodownload --auto-features=enabled . x86_64-redhat-linux-gnu
The Meson build system
Version: 0.55.3
Source dir: /home/bitwalk/rpmbuild/BUILD/hello-world-gtk-1.0
Build dir: /home/bitwalk/rpmbuild/BUILD/hello-world-gtk-1.0/x86_64-redhat-linux-gnu
Build type: native build
Using 'PKG_CONFIG_PATH' from environment with value: ':/usr/lib64/pkgconfig:/usr/share/pkgconfig'
Using 'PKG_CONFIG_PATH' from environment with value: ':/usr/lib64/pkgconfig:/usr/share/pkgconfig'
Project name: Hello World
Project version: undefined
Using 'CC' from environment with value: 'gcc'
Using 'CFLAGS' from environment with value: '-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
Using 'LDFLAGS' from environment with value: '-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld '
Using 'CC' from environment with value: 'gcc'
Using 'CFLAGS' from environment with value: '-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
Using 'LDFLAGS' from environment with value: '-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld '
C compiler for the host machine: gcc (gcc 10.2.1 "gcc (GCC) 10.2.1 20201125 (Red Hat 10.2.1-9)")
C linker for the host machine: gcc ld.bfd 2.35-15
Host machine cpu family: x86_64
Host machine cpu: x86_64
Found pkg-config: /bin/pkg-config (1.7.3)
Using 'PKG_CONFIG_PATH' from environment with value: ':/usr/lib64/pkgconfig:/usr/share/pkgconfig'
Run-time dependency gtk4 found: YES 3.99.4
Build targets in project: 1
Found ninja-1.10.1 at /bin/ninja
+ /usr/bin/meson compile -C x86_64-redhat-linux-gnu -j 8 --verbose
Found runner: ['/bin/ninja']
ninja: Entering directory `x86_64-redhat-linux-gnu'
[1/2] gcc -Ihello.p -I. -I.. -I/usr/include/gtk-4.0 -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/fribidi -I/usr/include/libxml2 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/graphene-1.0 -I/usr/lib64/graphene-1.0/include -I/usr/include/gio-unix-2.0 -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mfpmath=sse -msse -msse2 -pthread -MD -MQ hello.p/hello-world-gtk.c.o -MF hello.p/hello-world-gtk.c.o.d -o hello.p/hello-world-gtk.c.o -c ../hello-world-gtk.c
[2/2] gcc -o hello hello.p/hello-world-gtk.c.o -Wl,--as-needed -Wl,--no-undefined -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,--start-group /usr/lib64/libgtk-4.so /usr/lib64/libpangocairo-1.0.so /usr/lib64/libpango-1.0.so /usr/lib64/libharfbuzz.so /usr/lib64/libgdk_pixbuf-2.0.so /usr/lib64/libcairo-gobject.so /usr/lib64/libcairo.so /usr/lib64/libgraphene-1.0.so /usr/lib64/libgio-2.0.so /usr/lib64/libgobject-2.0.so /usr/lib64/libglib-2.0.so -Wl,--end-group
+ RPM_EC=0
++ jobs -p
+ exit 0
実行中(%install): /bin/sh -e /var/tmp/rpm-tmp.ZjKx6D
+ umask 022
+ cd /home/bitwalk/rpmbuild/BUILD
+ '[' /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64 '!=' / ']'
+ rm -rf /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64
++ dirname /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64
+ mkdir -p /home/bitwalk/rpmbuild/BUILDROOT
+ mkdir /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64
+ cd hello-world-gtk-1.0
+ DESTDIR=/home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64
+ /usr/bin/meson install -C x86_64-redhat-linux-gnu --no-rebuild
Installing hello to /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64/usr/bin
Installing /home/bitwalk/rpmbuild/BUILD/hello-world-gtk-1.0/hello.desktop to /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64/usr/share/applications
Installing /home/bitwalk/rpmbuild/BUILD/hello-world-gtk-1.0/hello.svg to /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64/usr/share/icons/hicolor/scalable/apps
+ /usr/lib/rpm/find-debuginfo.sh -j8 --strict-build-id -m -i --build-id-seed 1.0-1.fc33 --unique-debug-suffix -1.0-1.fc33.x86_64 --unique-debug-src-base hello-world-gtk-1.0-1.fc33.x86_64 --run-dwz --dwz-low-mem-die-limit 10000000 --dwz-max-die-limit 110000000 -S debugsourcefiles.list /home/bitwalk/rpmbuild/BUILD/hello-world-gtk-1.0
explicitly decompress any DWARF compressed ELF sections in /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64/usr/bin/hello
extracting debug info from /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64/usr/bin/hello
original debug info size: 40kB, size after compression: 44kB
/usr/lib/rpm/sepdebugcrcfix: Updated 1 CRC32s, 0 CRC32s did match.
2 blocks
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-ldconfig
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/redhat/brp-strip-lto /usr/bin/strip
+ /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/redhat/brp-python-bytecompile '' 1 0
+ /usr/lib/rpm/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-mangle-shebangs
実行中(%check): /bin/sh -e /var/tmp/rpm-tmp.MH9nsB
+ umask 022
+ cd /home/bitwalk/rpmbuild/BUILD
+ cd hello-world-gtk-1.0
+ /usr/bin/meson test -C x86_64-redhat-linux-gnu --num-processes 8 --print-errorlogs
ninja: Entering directory `/home/bitwalk/rpmbuild/BUILD/hello-world-gtk-1.0/x86_64-redhat-linux-gnu'
ninja: no work to do.
No tests defined.
+ RPM_EC=0
++ jobs -p
+ exit 0
ファイルの処理中: hello-world-gtk-1.0-1.fc33.x86_64
実行中(%doc): /bin/sh -e /var/tmp/rpm-tmp.2BgGMB
+ umask 022
+ cd /home/bitwalk/rpmbuild/BUILD
+ cd hello-world-gtk-1.0
+ DOCDIR=/home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64/usr/share/doc/hello-world-gtk
+ export LC_ALL=C
+ LC_ALL=C
+ export DOCDIR
+ /usr/bin/mkdir -p /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64/usr/share/doc/hello-world-gtk
+ cp -pr README.md /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64/usr/share/doc/hello-world-gtk
+ RPM_EC=0
++ jobs -p
+ exit 0
実行中(%license): /bin/sh -e /var/tmp/rpm-tmp.oWbazB
+ umask 022
+ cd /home/bitwalk/rpmbuild/BUILD
+ cd hello-world-gtk-1.0
+ LICENSEDIR=/home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64/usr/share/licenses/hello-world-gtk
+ export LC_ALL=C
+ LC_ALL=C
+ export LICENSEDIR
+ /usr/bin/mkdir -p /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64/usr/share/licenses/hello-world-gtk
+ cp -pr LICENSE /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64/usr/share/licenses/hello-world-gtk
+ RPM_EC=0
++ jobs -p
+ exit 0
Provides: application() application(hello.desktop) hello-world-gtk = 1.0-1.fc33 hello-world-gtk(x86-64) = 1.0-1.fc33
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires: libc.so.6()(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libgio-2.0.so.0()(64bit) libglib-2.0.so.0()(64bit) libgobject-2.0.so.0()(64bit) libgtk-4.so.0()(64bit) rtld(GNU_HASH)
ファイルの処理中: hello-world-gtk-debugsource-1.0-1.fc33.x86_64
Provides: hello-world-gtk-debugsource = 1.0-1.fc33 hello-world-gtk-debugsource(x86-64) = 1.0-1.fc33
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
ファイルの処理中: hello-world-gtk-debuginfo-1.0-1.fc33.x86_64
Provides: debuginfo(build-id) = 8f4475d30ab4fa4c56496ce5d98608ef5f944827 hello-world-gtk-debuginfo = 1.0-1.fc33 hello-world-gtk-debuginfo(x86-64) = 1.0-1.fc33
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Recommends: hello-world-gtk-debugsource(x86-64) = 1.0-1.fc33
パッケージに含まれないファイルの検査中: /usr/lib/rpm/check-files /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64
書き込み完了: /home/bitwalk/rpmbuild/SRPMS/hello-world-gtk-1.0-1.fc33.src.rpm
書き込み完了: /home/bitwalk/rpmbuild/RPMS/x86_64/hello-world-gtk-1.0-1.fc33.x86_64.rpm
書き込み完了: /home/bitwalk/rpmbuild/RPMS/x86_64/hello-world-gtk-debugsource-1.0-1.fc33.x86_64.rpm
書き込み完了: /home/bitwalk/rpmbuild/RPMS/x86_64/hello-world-gtk-debuginfo-1.0-1.fc33.x86_64.rpm
実行中(%clean): /bin/sh -e /var/tmp/rpm-tmp.4qWWIA
+ umask 022
+ cd /home/bitwalk/rpmbuild/BUILD
+ cd hello-world-gtk-1.0
+ /usr/bin/rm -rf /home/bitwalk/rpmbuild/BUILDROOT/hello-world-gtk-1.0-1.fc33.x86_64
+ RPM_EC=0
++ jobs -p
+ exit 0
[bitwalk@fedora-pc SPECS]$
このように、rpmbuild でビルドするパッケージは $HOME/rpmbuild 内で、コンパイルからパッケージングまですべてが完結するようになっています。コンパイルしたバイナリ (hello) を含むパッケージは、上の「書き込み完了」二番目の /home/bitwalk/rpmbuild/RPMS/x86_64/hello-world-gtk-1.0-1.fc33.x86_64.rpm です。このパッケージの構成は次のようになっています。
[bitwalk@fedora-pc SPECS]$ rpm -qlp /home/bitwalk/rpmbuild/RPMS/x86_64/hello-world-gtk-1.0-1.fc33.x86_64.rpm
/usr/bin/hello
/usr/lib/.build-id
/usr/lib/.build-id/14
/usr/lib/.build-id/14/e59fde06c519e226b72d296bbdbe9a8acd4789
/usr/share/applications/hello.desktop
/usr/share/doc/hello-world-gtk
/usr/share/doc/hello-world-gtk/README.md
/usr/share/icons/hicolor/scalable/apps/hello.svg
/usr/share/licenses/hello-world-gtk
/usr/share/licenses/hello-world-gtk/LICENSE
[bitwalk@fedora-pc SPECS]$
ちなみに、上記下線部分 は、デスクトップ環境のための起動用設定とアイコンです。
上の「書き込み完了」一番目の /home/bitwalk/rpmbuild/SRPMS/hello-world-gtk-1.0-1.fc33.src.rpm は、ソース RPM パッケージで、パッケージの構成は次のようになっています。
[bitwalk@fedora-pc SPECS]$ rpm -qlp /home/bitwalk/rpmbuild/SRPMS/hello-world-gtk-1.0-1.fc33.src.rpm
hello-world-gtk-1.0.zip
hello-world-gtk.spec
[bitwalk@fedora-pc SPECS]$
今回は単純なサンプルだったのでパッチファイルがありませんでしたが、パッケージ化するためにオリジナルのソースに変更を加える必要があるときは、ソースプログラムを修正し、修正した部分の差分をパッチファイルとして管理して、RPM パッケージをビルドするときにパッチを適用します。つまり、オリジナルのファイル(この例の場合は hello-world-gtk-1.0.zip )は変更を加えない状態で保持されます。
なお、rpmbuild --rebuild /home/bitwalk/rpmbuild/SRPMS/hello-world-gtk-1.0-1.fc33.src.rpm のようにすると、構成するソースファイルとスペックファイルを $HOME/rpmbuild 以下に展開して、パッケージをリビルドします。
残りの「書き込み完了」の RPM パッケージはデバッグ用途です。
[bitwalk@fedora-pc SPECS]$ rpm -qlp /home/bitwalk/rpmbuild/RPMS/x86_64/hello-world-gtk-debugsource-1.0-1.fc33.x86_64.rpm
/usr/src/debug/hello-world-gtk-1.0-1.fc33.x86_64
/usr/src/debug/hello-world-gtk-1.0-1.fc33.x86_64/hello-world-gtk.c
/usr/src/debug/hello-world-gtk-1.0-1.fc33.x86_64/x86_64-redhat-linux-gnu
[bitwalk@fedora-pc SPECS]$ rpm -qlp /home/bitwalk/rpmbuild/RPMS/x86_64/hello-world-gtk-debuginfo-1.0-1.fc33.x86_64.rpm
/usr/lib/debug
/usr/lib/debug/.build-id
/usr/lib/debug/.build-id/d8
/usr/lib/debug/.build-id/d8/45357e6478396b035b6c5f175f15cdc7f133a9
/usr/lib/debug/.build-id/d8/45357e6478396b035b6c5f175f15cdc7f133a9.debug
/usr/lib/debug/usr
/usr/lib/debug/usr/bin
/usr/lib/debug/usr/bin/hello-1.0-1.fc33.x86_64.debug
[bitwalk@fedora-pc SPECS]$
これらデバッグパッケージを生成したくない場合は、スペックファイルの先頭に %global debug_package %{nil} を記入しておくことで抑制できます。
ビルドした RPM パッケージをインストール
管理者権限で dnf コマンドを使って、作成した rpm パッケージをインストールします。、
[bitwalk@fedora-pc SPECS]$ sudo dnf install /home/bitwalk/rpmbuild/RPMS/x86_64/hello-world-gtk-1.0-1.fc33.x86_64.rpm
[sudo] bitwalk のパスワード:
メタデータの期限切れの最終確認: 2:13:26 時間前の 2020年12月23日 18時36分56秒 に実施しました。
依存関係が解決しました。
========================================================================================================================================
パッケージ アーキテクチャー バージョン リポジトリー サイズ
========================================================================================================================================
インストール:
hello-world-gtk x86_64 1.0-1.fc33 @commandline 14 k
トランザクションの概要
========================================================================================================================================
インストール 1 パッケージ
合計サイズ: 14 k
インストール後のサイズ: 23 k
これでよろしいですか? [y/N]: y
パッケージのダウンロード:
トランザクションの確認を実行中
トランザクションの確認に成功しました。
トランザクションのテストを実行中
トランザクションのテストに成功しました。
トランザクションを実行中
準備 : 1/1
インストール中 : hello-world-gtk-1.0-1.fc33.x86_64 1/1
scriptletの実行中: hello-world-gtk-1.0-1.fc33.x86_64 1/1
検証 : hello-world-gtk-1.0-1.fc33.x86_64 1/1
インストール済み:
hello-world-gtk-1.0-1.fc33.x86_64
完了しました!
[bitwalk@fedora-pc SPECS]$
RPM パッケージをインストール後、GNOME の「アクティビティ」をクリックしてダッシュを表示します。下のグリッドボタンをクリックしてアプリケーション一覧を表示すると Hello World アイコンが追加されていることを確認できます。
GNOME アプリ一覧に追加された Hello World アイコン
Hello World アイコンをクリックするとプログラムが起動します。
hello-world-gtk の実行例
freedesktop.org について
freedesktop.org (fd.o) は、Linux や Unix 系 OS 上の X Window System (X11) や Wayland で動作するフリーソフトウェアのデスクトップ環境において、相互運用性と共有ベース技術の向上に取り組むプロジェクトです。2000 年 3 月に Red Hat 社の Havoc Pennington 氏によって設立されました。プロジェクトのサーバはポートランド州立大学がホストしており、HP、Intel、Google 各社がスポンサーとなっています。
GNOME、KDE Plasma Desktop、Xfce など、広く使われているデスクトッププロジェクトが freedesktop.org プロジェクトと協力しています。2006 年には、デスクトップ環境のための共通のインターフェイスのセットである Portland 1.0 (xdg-utils) がリリースされました。 しかし、freedesktop.org は、ユーザが自由にアイデアを議論できる標準や仕様のための「コラボレーションゾーン」であり、正式な標準化組織ではありません。
デスクトップ環境によって、アプリの起動アイコンを配置する方法が異なれば、プログラムをパッケージ化する負担が増えます。freedesktop.org のように標準や仕様を議論する緩い組織の存在は、開発者にとってありがたい存在です。参考サイト [6] は freedesktop.org が作成した仕様の一覧を集めたサイトです。freedesktop.org によると freedesktop.org は公式の標準化団体ではなく、プロジェクトがfreedesktop.org の仕様すべてを実装することを求めていません。しかし、ポピュラーなデスクトップ環境が、この仕様に準拠しようとしていることはとてもありがたいことです。
今回の Hello World のサンプルを RPM パッケージする際に追加した hello.desktop の書き方は、参考サイト [7] を参考にしています。
デスクトップファイル hello.desktop や、hello.svg といったアイコンファイルは、それぞれ
/usr/share/applications/hello.desktop
/usr/share/icons/hicolor/scalable/apps/hello.svg
に配置しています。これは長年の経験から知りえた情報ではありますが、実は参考サイト [8] 等の仕様がベースとなっています。
デスクトップ環境に関連する情報が保存される領域のトップディレクトリは、環境変数 $XDG_DATA_DIRS に定義されています。Fedora 33 では変数の値は下記のように複数指定されています。
[bitwalk@fedora-pc ~]$ echo $XDG_DATA_DIRS
/home/bitwalk/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
[bitwalk@fedora-pc ~]$
Flatpak アプリの場合は別の場所になっています
freedesktop.org の情報に絡めて、GNOME のデスクトップ環境の関連データの情報を別の機会にまとめたいと考えています。
まとめ
プログラムをソースコードからビルドするには Makefile を記述して make を実行する、というのが長い間、自分にとっては常識でした。
ところが、次期 Fedora 34 から、RPM パッケージのビルドルートから make に依存するパッケージを無くそうとする活動が始まることを知り慌ててしまいました [10] 。要するに make によるパッケージ作成速度は、CMake や Meson のような後発のビルドシステムに比べてかなり遅いのです。調べてみると GNOME プロジェクトでは既に Meson への移行がほとんど完了しているということです [11] 。
Meson を使えるようにしておきたいと考え、GTK4 がリリースされたのを契機に、GTK4 のプログラムを Meson でビルドする RPM パッケージを作ってみました。Meson 用の RPM マクロは今回初めて使いました。😅
参考サイト
bitWalk's: GTK4 を触ってみた [2020-12-21]
bitWalk's: GTK4 を触ってみた (2) ~ Meson でビルド ~ [2020-12-22]
RPM Packaging Guide
specファイル大解剖 - Qiita [2018-12-19]
Meson Packaging Guidelines :: Fedora Docs
Specifications (freedesktop.org)
Desktop Entry Specification
XDG Base Directory Specification
Creating RPM packages :: Fedora Docs
Releases/34/ChangeSet - Fedora Project Wiki
Initiatives/GnomeGoals/MesonPorting - GNOME Wiki!
VIDEO
にほんブログ村