2020-12-24

Meson と RPM パッケージ作成

もはや新しくリリースされた 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 パッケージをビルド

スペックファイルを作成するときには、

  1. rpmbuild -bp specfile: %prep (ソース展開と patch の適用)まで実行
  2. rpmbuild -bc specfile: %build(%prep とコンパイル)まで実行
  3. rpmbuild -bi specfile: %install (%prep, %build, インストール)まで実行
  4. 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 は、ユーザが自由にアイデアを議論できる標準や仕様のための「コラボレーションゾーン」であり、正式な標準化組織ではありません。

Wikipedia より引用・翻訳、編集

デスクトップ環境によって、アプリの起動アイコンを配置する方法が異なれば、プログラムをパッケージ化する負担が増えます。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 によるパッケージ作成速度は、CMakeMeson のような後発のビルドシステムに比べてかなり遅いのです。調べてみると GNOME プロジェクトでは既に Meson への移行がほとんど完了しているということです [11]

Meson を使えるようにしておきたいと考え、GTK4 がリリースされたのを契機に、GTK4 のプログラムを Meson でビルドする RPM パッケージを作ってみました。Meson 用の RPM マクロは今回初めて使いました。😅

参考サイト

  1. bitWalk's: GTK4 を触ってみた [2020-12-21]
  2. bitWalk's: GTK4 を触ってみた (2) ~ Meson でビルド ~ [2020-12-22]
  3. RPM Packaging Guide
  4. specファイル大解剖 - Qiita [2018-12-19]
  5. Meson Packaging Guidelines :: Fedora Docs
  6. Specifications (freedesktop.org)
  7. Desktop Entry Specification
  8. XDG Base Directory Specification
  9. Creating RPM packages :: Fedora Docs
  10. Releases/34/ChangeSet - Fedora Project Wiki
  11. Initiatives/GnomeGoals/MesonPorting - GNOME Wiki!

 

ブログランキング・にほんブログ村へにほんブログ村

0 件のコメント: