続・玩式草子 ―戯れせんとや生まれけん―

第4回Plamoメンテナのすゝめ(中

朝晩はずいぶん冷え込むようになり、家の回りの山々もすっかり晩秋の景色になりました。少し肌寒さは感じるものの、手指がかじかむほどではない秋の夜長は、プログラミングに最適の時期です。

というわけで(?⁠⁠、今回は、前回作成した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_sources77行目のcheck_root89行目のinstall_tweak95行目の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ウィンドウマネージャの設定画面
図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を使えば誰でも簡単にパッケージを作れますので、皆さんもぜひパッケージ作りに挑戦してみてください。

おすすめ記事

記事・ニュース一覧