朝晩はずいぶん冷え込むようになり、家の回りの山々もすっかり晩秋の景色になりました。少し肌寒さは感じるものの、手指がかじかむほどではない秋の夜長は、プログラミングに最適の時期です。
というわけで(?) 、今回は、前回作成したPlamoBuild.fluxbox-1.3.7を用いてPlamoBuildスクリプトの中身を解説します。
PlamoBuildスクリプトの詳細
まず、make_PlamoBuild.pyで作成したPlamoBuild.fluxbox-1.3.7の全体を行番号付きで紹介しましょう。
1 #!/bin/sh
2 ##############################################################
3 pkgbase="fluxbox"
4 vers="1.3.7"
5 url="https://downloads.sourceforge.net/fluxbox/fluxbox-1.3.7.tar.xz"
6 arch=`uname -m`
7 build=B1
8 src="fluxbox-1.3.7"
9 OPT_CONFIG="--disable-static --enable-shared"
10 DOCS="AUTHORS COPYING ChangeLog INSTALL NEWS README TODO"
11 patchfiles=""
12 compress=txz
13 ##############################################################
14
15 source /usr/share/plamobuild_functions.sh
16
17 # このスクリプトで使う1文字変数の意味
18 #
19 # $W : このスクリプトを動かすカレントディレクトリ
20 # $S : ソースコードのあるディレクトリ(デフォルト: $W/${src})
21 # $B : ビルド用ディレクトリ(デフォルト: /tmp/build)
22 # $P : ビルドしたファイルをインストールするディレクトリ(デフォルト: $W/work)
23
24 if [ $# -eq 0 ] ; then
25 opt_download=0 ; opt_config=1 ; opt_build=1 ; opt_package=1
26 else
27 opt_download=0 ; opt_config=0 ; opt_build=0 ; opt_package=0
28 for i in $@ ; do
29 case $i in
30 download) opt_download=1 ;;
31 config) opt_config=1 ;;
32 build) opt_build=1 ;;
33 package) opt_package=1 ;;
34 esac
35 done
36 fi
37 if [ $opt_download -eq 1 ] ; then
38 download_sources
39 fi
40
41 if [ $opt_config -eq 1 ] ; then
42 ######################################################################
43 # out of tree build. patch apply in src dir
44 ######################################################################
45 if [ -d $B ] ; then rm -rf $B ; fi ; mkdir -p $B
46 cd $S
47 for patch in $patchfiles ; do
48 if [ ! -f .${patch} ]; then
49 patch -p1 < $W/$patch
50 touch .${patch}
51 fi
52 done
53 # if [ -f autogen.sh ] ; then
54 # sh ./autogen.sh
55 # fi
56 cd $B
57 export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/share/pkgconfig
58 export LDFLAGS='-Wl,--as-needed'
59 $S/configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --mandir='${prefix}'/share/man ${OPT_CONFIG}
60 if [ $? != 0 ]; then
61 echo "configure error. $0 script stop"
62 exit 255
63 fi
64 fi
65
66 if [ $opt_build -eq 1 ] ; then
67 cd $B
68 export LDFLAGS='-Wl,--as-needed'
69 make -j3
70 if [ $? != 0 ]; then
71 echo "build error. $0 script stop"
72 exit 255
73 fi
74 fi
75
76 if [ $opt_package -eq 1 ] ; then
77 check_root
78 if [ -d $P ] ; then rm -rf $P ; fi ; mkdir -p $P
79 cd $B
80
81 export LDFLAGS='-Wl,--as-needed'
82 make install DESTDIR=$P
83
84 ################################
85 # install tweaks
86 # strip binaries, delete locale except ja, compress man,
87 # install docs and patches, compress them and chown root.root
88 ################################
89 install_tweak
90
91 #############################
92 # convert symlink to null file and
93 # add "ln -sf" command into install/doinst.sh
94 ################################
95 convert_links
96
97 cd $P
98 /sbin/makepkg ../$pkg.$compress <<EOF
99 y
100 1
101 EOF
102
103 fi
ご覧の通り、PlamoBuildスクリプトは100行ほどのシンプルなシェルスクリプトで、頭から順番に、「 パッケージに関する必要な情報の設定(3~12行) 」 、「 ソースコードのダウンロード(37~39行) 」 、「 ビルドのための設定(41~64行) 」 、「 実際のビルド(66~74行) 」 、「 仮ディレクトリにインストールしてパッケージ化(76~103行) 」 、といった作業を行います。
それぞれの作業を行うかどうかは$opt_config や$opt_build といったフラグで管理しており、"download"や"package"といった引数を与えて各作業を指定することもできますし、引数を与えずに実行すれば"config"、"build"、"package"が順に実行されます(24~36行) 。
15行目で読みこんでいる/usr/share/plamobuild_functions.sh が汎用的な処理をまとめたサブルーチン集で、38行目のdownload_sources 、77行目のcheck_root 、89行目のinstall_tweak 、95行目のconvert_links といった処理が定義されています。
また、17行目から22行目で紹介している$W や$B といったスクリプト中の一文字変数もこのplamobuild_functions.sh内で定義しているので、ビルド用ディレクトリを別の場所にするなど、これらの変数を変更する場合は15行目以降で設定する必要があります。
PlamoBuildスクリプトの再実行
さて、それではこのPlamoBuild.fluxbox-1.3.7を使って、実際にパッケージを作る手順を再紹介しましょう。前回はオプション指定無しで一気にパッケージ作成まで進めましたが、今回は設定、ビルド、パッケージ化の各処理を手動で実行してみます。
設定処理
前回、ざっと流した際、"configure: WARNING: unrecognized options: --disable-static, --enable-shared" という警告メッセージが出ていました。このメッセージは、「 fluxbox-1.3.7付属のconfigureスクリプトは、$OPT_CONFIGで設定している--disable-static --enable-shared という指定を認識しない」 、という意味です。そこで、9行目のOPT_CONFIGを空行に修正します。
9 OPT_CONFIG=""
ここで指定していた"--disable-static --enable-shared"という指定は、「 静的ライブララリ(.a)は作らず、動的(共有)ライブラリ(.so)を作る」という意味です。元々GNU Autotoolsは、共有ライブラリが広まる以前に設計されたツールなため、しばらく前までは「静的ライブラリを作り、共有ライブラリは作らない」という動作がデフォルトでした。そのため、Linuxでビルドする際は"--disable-static --enable-shared"を指定して、共有ライブラリ作成を指示する必要があったものの、最近では共有ライブラリがデフォルトで、このオプションが不要なソースコードが増えてきました。
OPT_CONFIG行を空行にすると、PlamoBuild.fluxbox-1.3.7は警告なく設定を完了します。
$ ./PlamoBuild.fluxbox-1.3.7 config
checking for gcc... gcc
checking whether the C compiler works... yes
...
fluxbox version 1.3.7 configured successfully.
Using:
'/usr' for installation.
'/usr/share/fluxbox/menu' for location menu file.
'/usr/share/fluxbox/windowmenu' for location window menu file.
'/usr/share/fluxbox/styles/bloe' by default style.
'/usr/share/fluxbox/keys' for location keys file.
'/usr/share/fluxbox/init' for location init file.
'/usr/share/fluxbox/nls' for nls files.
'g++' for C++ compiler.
Building with:
'-I/usr/include/fribidi -g -O2 ' for C++ compiler flags.
' -lfontconfig -lfreetype -lfreetype -lfribidi -lImlib2 -lXrandr -lXext -lXft -lXinerama -lXpm -lX11 -lXrender -lX11' for linker flags.
Now build fluxbox with 'make'
config を引数に指定してPlamoBuildスクリプトを実行すると、$opt_configフラグが立って41~64行の処理が行われ、$Bで指定した/tmp/build/ 以下にMakefile等の必要なファイルが用意されます。
$ ls /tmp/build/
Makefile config.h config.log config.status* nls/ src/ stamp-h1 util/ version.h
ビルド作業
次にbuild を指定して実行すると、/tmp/buildに移って(67行) 、make -j3を実行(69行)します。
$ ./PlamoBuild.fluxbox-1.3.7 build
cmp: ./src/defaults.cc: そのようなファイルやディレクトリはありません
make all-recursive
make[1]: ディレクトリ '/tmp/build' に入ります
...
g++ -g -O2 -Wl,--as-needed -o fluxbox-update_configs src/fluxbox_update_configs-defaults.o \
src/fluxbox_update_configs-Resources.o util/fluxbox_update_configs-fluxbox-update_configs.o \
libFbTk.a -lfribidi -lX11 -lrt -lm
make[2]: ディレクトリ '/tmp/build' から出ます
make[1]: ディレクトリ '/tmp/build' から出ます
最初にcmpが「ファイルが見つからない」旨のエラーを出しているものの、ビルドそのものは問題なく進み、/tmp/build/以下にコンパイルされたファイルが集積されました。
$ ls /tmp/build/
Makefile config.status* fluxbox* libFbTk.a stamp-h1
config.h fbrun* fluxbox-remote* nls/ util/
config.log fbsetroot* fluxbox-update_configs* src/ version.h
デフォルトで設定している"make -j3"は「make作業を3プロセスまで並列で進める」という指定で、4コアくらいのCPUを想定しています。搭載メモリに余裕があり、コア数が多いCPU環境では、並列度を上げればビルド速度も向上します。
一方、並列ビルドを考慮していない古めのソフトウェアの中には並列処理しようとすると「必要なファイルが見つからない」旨のエラーを出すものがあります。そのような場合、"-j3"オプションを削除するか、"-j1"として並列処理を禁止すれば解決することがあります。
パッケージ化
最後にpackage を指定してパッケージ化の作業を行います。"package"を指定すると、ビルドスクリプトは$P で指定しているインストール先ディレクトリを準備した上で(78行目) 、82行目の"make install DESTDIR=$P"を実行します。
22行目にコメントしてあるように、$Pはカレントディレクトリ(ビルドスクリプトのあるディレクトリ)の"work"ディレクトリを指しているので、./work/ に必要なファイルがインストールされ、そこからパッケージが作られることになります。
$ ./PlamoBuild.fluxbox-1.3.7 package
Do you want to package as root? [y/N]
make install-recursive
make[1]: ディレクトリ '/tmp/build' に入ります
...
pruning symlink in /home/kojima/Srcs/F/Fluxbox/work/usr/share/man/mann
basename:fluxbox
version:1.3.7
arch:x86_64
build:B1
ext:txz
しかしながら前回も指摘したように、一般ユーザで作成したパッケージでは、ファイルの所有者が一般ユーザ(kojima)のままです。
$ tar tvf fluxbox-1.3.7-x86_64-B1.txz
drwxr-xr-x kojima/users 0 2018-11-23 16:09:24 usr/
drwxr-xr-x kojima/users 0 2018-11-23 16:09:26 usr/share/
drwxr-xr-x kojima/users 0 2018-11-23 16:09:25 usr/share/fluxbox/
...
間違えてこの状態のパッケージをインストールしてしまうと、/usr以下のディレクトリの所有者がkojima/usersに変更されてしまい、一般ユーザが/usr以下を書き替え可能になる等の不具合が生じます。そのため、再度ビルドスクリプトを実行し、今度はroot権限でパッケージ化します。
$ ./PlamoBuild.fluxbox-1.3.7 package
Do you want to package as root? [y/N] y
パスワード: *******
make install-recursive
...
"Do you want to package as root?"の質問に "y"と答えると、rootパスワードの入力が求められ、認証されればroot権限でmake installが実行されて、適切なユーザパーミッションが設定されたパッケージが作成できます。
$ tar tvf fluxbox-1.3.7-x86_64-B1.txz
drwxr-xr-x root/root 0 2018-11-23 16:14:22 usr/
drwxr-xr-x root/root 0 2018-11-23 16:14:24 usr/share/
...
紹介したように、一度一般ユーザで作成してから、再度root権限でパッケージを作成し直すのは二度手間のように思われるかも知れません。しかしながら、インストール先を/usr/local/に決め打ちしているなど、DESTDIRが効かない作りのソフトウェアもたまにあり、それに気づかないままroot権限でmake installすると、思ってもいない所にファイルがインストールされてしまうことがあります。そのようなトラブルを防ぐため、一度、一般ユーザでインストールして、全てのファイルが"./work/"以下に収まることを確認した上で、root権限でパッケージ化する方が安全です。
作成したパッケージは、他のPlamo用パッケージ同様、installpkg コマンドでインストールできます。
$ sudo installpkg fluxbox-1.3.7-x86_64-B1.txz
fluxbox-1.3.7-x86_64-B1 のインストール中
テストのために、fluxboxがウィンドウマネージャーになるよう、~/.xinitrc を書き替えます。
$ mv .xinitrc .xinitrc.org
$ echo "startfluxbox" > .xinitrc
こうしておいてからstartx でXを起動すると、シンプルなfluxboxウィンドウマネージャーが起動しました。
図1 fluxboxウィンドウマネージャの設定画面
インストール済パッケージの管理情報
Plamo Linuxではインストールした各パッケージの情報を/var/log/packages ディレクトリにファイルとして記録しています。
今回インストールしたfluxboxでは、/var/log/packages/fluxbox というファイルに、パッケージ名やサイズ、このパッケージからインストールした全ファイルの名前が登録されます。
$ cat -n /var/log/packages/fluxbox
1 PACKAGE NAME: fluxbox-1.3.7-x86_64-B1
2 COMPRESSED PACKAGE SIZE: 776 K
3 UNCOMPRESSED PACKAGE SIZE: 3300 K
4 PACKAGE LOCATION: fluxbox-1.3.7-x86_64-B1.txz
5 PACKAGE DESCRIPTION:
6 FILE LIST:
7 usr/
....
333 usr/bin/fluxbox
334 usr/bin/fbsetroot
335 usr/bin/fluxbox-remote
336 usr/bin/fluxbox-update_configs
337 usr/bin/fbrun
installpkgコマンドでインストールしたパッケージの情報は全てこのディレクトリに保存されているので、たとえば/usr/bin/mutool というコマンドがどのパッケージからインストールされたかも、grepコマンドを使って簡単に調べることができます。
$ grep mutool /var/log/packages
/var/log/packages/mupdf:usr/bin/mutool
/var/log/packages/mupdf:usr/share/man/man1/mutool.1.gz
この例では、/usr/bin/mutoolはmupdf というパッケージに由来することがわかり、/var/log/packages/mupdf を見ればソフトウェアのバージョンやサイズ、一緒にインストールされたファイルなどを確認できます。
$ cat -n /var/log/packages/mupdf
1 PACKAGE NAME: mupdf-1.11-x86_64-B1
2 COMPRESSED PACKAGE SIZE: 20845 K
3 UNCOMPRESSED PACKAGE SIZE: 43950 K
4 PACKAGE LOCATION: /var/adm/mount/plamo/09_printings/mupdf-1.11-x86_64-B1.txz
5 PACKAGE DESCRIPTION:
6 mupdf: 軽量PDF/XPS/E-bookビューワー MuPDF
...
最近では、たいていのソフトウェアが"./configure && make && make install"だけでインストールできます。しかしながら、この方法でインストールしてしまうと、どこにどのファイルがインストールされたかを管理できないため、そのソフトウェアをアンインストールしたい際に面倒なことになります。
そのため、簡単なソフトウェアでも、いったんパッケージ化してinstallpkg/removepkgで管理するのがお勧めで、make_PlamoBuild.pyはそのためのヘルパーとして使えるように設計しているつもりです。
Plamo Linuxは、メンテナの人手不足もあって、パッケージの数はメジャーなディストリビューションと比べるとずいぶん見劣りします。しかしながら、紹介してきたmake_PlamoBuild.pyを使えば誰でも簡単にパッケージを作れますので、皆さんもぜひパッケージ作りに挑戦してみてください。