makepkg
makepkg は pacman (Arch Linux のパッケージマネージャ) でのインストールに適したパッケージをコンパイル・ビルドするために使われます。makepkg はパッケージのビルドを自動化するスクリプトです; ソースファイルのダウンロード・検証、依存関係の確認、ビルド時の設定、ソースのコンパイル、一時 root へのインストール、カスタマイズ、メタ情報の生成、そして全てをまとめたパッケージの作成。
makepkg は pacman パッケージの中に入っています。
設定
/etc/makepkg.conf
が makepkg のメインの設定ファイルです。ほとんどのユーザーはパッケージをビルドする前に makepkg の設定オプションを微調整するとよいでしょう。~/.makepkg.conf
ファイルを作成することもできます。
アーキテクチャ、コンパイルフラグ
makepkg でソフトウェアをコンパイルする時 MAKEFLAGS
, CFLAGS
, CXXFLAGS
, CPPFLAGS
オプションが make, gcc, g++
によって使われます。デフォルトでは、様々なマシンでインストールできるような一般的なパッケージを生成するようにオプションが設定されています。ホストマシン用にコンパイルをチューニングすることでパフォーマンスを改善することが可能です。コンパイルするホストのプロセッサに合わせてパッケージをコンパイルするデメリットは、他のマシンでは動作しなくなるかもしれないということです。
/etc/makepkg.conf
[...] ######################################################################### # ARCHITECTURE, COMPILE FLAGS ######################################################################### # CARCH="x86_64" CHOST="x86_64-unknown-linux-gnu" #-- Exclusive: will only run on x86_64 # -march (or -mcpu) builds exclusively for an architecture # -mtune optimizes for an architecture, but builds for whole processor family CPPFLAGS="-D_FORTIFY_SOURCE=2" CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4" CXXFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4" LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro" #-- Make Flags: change this for DistCC/SMP systems #MAKEFLAGS="-j2" [...]
デフォルトの makepkg.conf の CFLAGS
と CXXFLAGS
はそれぞれのアーキテクチャを持つ全てのマシンと互換性があります。
x86_64 のマシンでは、時間を投資して公式のパッケージをリビルドすることでそれに見合うだけのパフォーマンスの向上を得られることは稀です。
GCC バージョン 4.3.0 から、マシンの CPU の自動検知とサポートされている最適化の自動セレクトを有効にする -march=native
スイッチが使えるようになっています。これを使うには、以下のように CFLAGS
と CXXFLAGS
を変更してください:
# -march=native also sets the correct -mtune= CFLAGS="-march=native -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2" CXXFLAGS="${CFLAGS}"
-march=native
は全ての利用可能な命令セットを有効にし特定の CPU にあわせてスケジューリングを改善するので CPU タイプに合わせた最適化によって理論上はパフォーマンスが向上します。アプリケーション (例えば: 音声・動画エンコードツール、科学的なアプリケーション、数学プログラムなど) をリビルドするときにこれは特に顕著で、Arch Linux によって提供されているデフォルトのオプション (またパッケージ) を使うときには有効にならない新しい命令を使えることで大きなアドバンテージを得ることができます。
コンパイラスイッチによって、ループ展開・悪いベクトル化・狂ったインライン化などでコンパイラはコードサイズを膨張させがちなので"標準外の" CFLAGS を使うことでパフォーマンスを下げるのはとても簡単です。何かが速くなると確認・ベンチマークできない限り、高速化できる可能性はほとんどありません!
利用可能なオプションの完全なリストは GCC の man ページを見て下さい。Gentoo の Compilation Optimization Guide や Safe CFLAGS にはより詳しい情報が載っています。
MAKEFLAGS
MAKEFLAGS
オプションを使って make に追加するオプションを指定することができます。マルチコア・マルチプロセッサのシステムを使っているユーザーは同時に実行するジョブの数を指定できます、例: -j4
。nproc
を使うことで利用可能なプロセッサの数がわかります。PKGBUILD によっては、特定のバージョンで競合状態になったり、もしくはサポートされていないために、この値を -j1
で上書きします。これによってビルドが失敗するパッケージがある場合は、エラーがあなたの MAKEFLAGS によって引き起こされていることを確認してから、バグトラッカーに報告してください。
利用可能なオプションの全ては man make
を見て下さい。
パッケージの出力
次に、ソースファイルやパッケージが置かれる場所、パッケージ作成者としての名前を設定することができます。このステップは任意です; デフォルトでは、パッケージは makepkg が実行された作業ディレクトリに作成されます。
/etc/makepkg.conf
[...] ######################################################################### # PACKAGE OUTPUT ######################################################################### # # Default: put built package and cached source in build directory # #-- Destination: specify a fixed directory where all packages will be placed #PKGDEST=/home/packages #-- Source cache: specify a fixed directory where source files will be cached #SRCDEST=/home/sources #-- Source packages: specify a fixed directory where all src packages will be placed #SRCPKGDEST=/home/srcpackages #-- Packager: name/email of the person or organization building packages #PACKAGER="John Doe <john@doe.com>" [...]
例えば、ディレクトリを作成して:
$ mkdir /home/$USER/packages
/etc/makepkg.conf
の PKGDEST
変数を修正してください。
PACKAGER
変数はコンパイルしたパッケージの .PKGINFO
メタデータファイルの中に packager
値を設定します。デフォルトでは、ユーザーがコンパイルしたパッケージは以下のように表示されます:
pacman -Qi package
[...] Packager : Unknown Packager [...]
設定した後:
pacman -Qi package
[...] Packager : John Doe <john@doe.com> [...]
システム上で複数のユーザーがパッケージをコンパイルしていたり、あなたのパッケージを他のユーザーに渡す場合にこれを使うと有用です。
署名チェック
.sig
や .asc
形式の署名ファイルが PKGBUILD の source 行に含まれている場合、makepkg は自動的に署名を検証します。ユーザーのキーリングに署名検証に必要な公開鍵が存在しない場合、makepkg はインストールを停止して PGP 鍵が検証できないというメッセージを表示します。
PKGBUILD に validpgpkeys エントリで鍵 ID が指定されているときパッケージをビルドするには公開鍵が必要になります。公開鍵が存在しない場合、あるいは他の開発者による公開鍵を追加したい場合、手動で鍵をインポートするか、もしくは鍵サーバーを使ってインポートすることができます。
使用方法
次に進む前に、base-devel グループがインストールされているか確認してください。このグループに属しているパッケージは PKGBUILD の中に依存パッケージとして載せる必要はないことになっています。以下を (root で) 実行して base-devel グループをインストールしてください:
# pacman -S base-devel
パッケージを作成するには、まずパッケージの作成に記述されているようにして PKGBUILD を作成するか ABS ツリーや Arch User Repository などから取得してくる必要があります。
PKGBUILD
を入手したら、PKGBUILD が保存されているディレクトリに移動してから次のコマンドを実行して PKGBUILD
に記述されたパッケージを作成します:
$ makepkg
パッケージ作成後、要らなくなったファイル ($srcdir に展開されたファイルなど) を makepkg によって削除するには、以下のオプションを加えて下さい。同じパッケージをビルドしたりパッケージのバージョンを更新するときに、同じビルドフォルダを使う場合、このオプションは有益です。残ったファイルを新しいビルドに持ち越す危険がなくなります。
$ makepkg -c
必要な依存パッケージが欠けている場合、makepkg は警告を表示します。必要な依存パッケージを自動的にインストールするには、次のコマンドを使って下さい:
$ makepkg -s
依存パッケージが取ってこれるのは設定されたリポジトリからだけということに注意してください; 詳しくは pacman#リポジトリ を見て下さい。また、ビルドの前に手動で依存パッケージをインストールすることもできます (pacman -S --asdeps dep1 dep2
)。
全ての依存関係が解決されパッケージのビルドが成功すれば、パッケージファイル (pkgname-pkgver.pkg.tar.xz
) が作業ディレクトリの中に作成されます。インストールするには、(root で) 次を実行してください:
# pacman -U pkgname-pkgver.pkg.tar.xz
もしくは、pacman -U pkgname-pkgver.pkg.tar.xz
を実行する代わりに -i
フラグを使ってインストールすることもできます:
$ makepkg -i
Tips and tricks
パッケージの堅牢化
hardening-wrapper パッケージをインストールしてください。このパッケージは gcc や g++ などをラッピングして /etc/hardening-wrapper.conf
でセキュリティを強化するフラグを制御できます。
ハードニングフラグを全て有効にするには:
/etc/hardening-wrapper.conf
HARDENING_BINDNOW=1 HARDENING_PIE=1 HARDENING_FORTIFY=2 HARDENING_RELRO=1 HARDENING_STACK_CHECK=1 HARDENING_STACK_PROTECTOR=2
インストール後、/etc/profile
を source するか、一度ログアウトしてログインしなおす必要があります。ラッパーが使われているか確認するには:
$ which gcc /usr/lib/hardening-wrapper/bin/gcc
後は普通にパッケージを作成すれば自動的に使用されます。
セキュリティを高めるフラグが使われているかどうか確認したい場合、checksec パッケージをインストールしてください。個別の実行ファイルをチェックしたり、ディレクトリを再帰的にチェックできます。例:
$ checksec --dir /tmp/makepkg/dwm/pkg/dwm/usr/bin RELRO STACK CANARY NX PIE RPATH RUNPATH FORTIFY Checked Total Filename Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH Yes 4 6 /tmp/makepkg/dwm/pkg/dwm/usr/bin/dwm
セキュリティ#パッケージの再ビルドも参照してください。
特定のパッケージ作成者によるパッケージを表示
以下のコマンドはシステムにインストールされているパッケージの中から packagername という名前のパッケージ作成者によって作られたパッケージを全て表示します:
$ expac "%n %p" | grep "packagername" | column -t
以下のコマンドは /etc/makepkg
の PACKAGER
変数に設定されている値とパッケージ作成者が一致するパッケージを表示します (/etc/pacman.conf
に定義されているリポジトリに含まれているパッケージだけが対象):
$ . /etc/makepkg.conf; grep -xvFf <(pacman -Qqm) <(expac "%n\t%p" | grep "$PACKAGER$" | cut -f1)
コンパイル時間を短縮する
tmpfs
パッケージをコンパイルするのは I/O に負担がかかる作業のため、tmpfs を利用することでビルド時間を大幅に短縮することができます。該当する /etc/makepkg.conf
のオプションは BUILD ENVIRONMENT
セクションの一番下にあります:
/etc/makepkg.conf
[...] ######################################################################### # BUILD ENVIRONMENT ######################################################################### # # Defaults: BUILDENV=(!distcc color !ccache check !sign) # A negated environment option will do the opposite of the comments below. # #-- distcc: Use the Distributed C/C++/ObjC compiler #-- color: Colorize output messages #-- ccache: Use ccache to cache compilation #-- check: Run the check() function if present in the PKGBUILD #-- sign: Generate PGP signature file # BUILDENV=(!distcc color !ccache check !sign) # #-- If using DistCC, your MAKEFLAGS will also need modification. In addition, #-- specify a space-delimited list of hosts running in the DistCC cluster. #DISTCC_HOSTS="" # #-- Specify a directory for package building. #BUILDDIR=/tmp/makepkg [...]
BUILDDIR=/tmp/makepkg
行をアンコメントして BUILDDIR=/tmp/builds
などに設定すれば (もしくはデフォルトの値のままにすれば) Arch のデフォルトの /tmp
tmpfs が使用されます。
tmpfs でコンパイルしたパッケージは再起動するとなくなってしまうので注意してください。そのため、何度もインストールするようなパッケージは他の(永続的な)ディレクトリに移動したほうが良いでしょう。
ccache
ccache を使うことでコンパイル結果をキャッシュしてビルド時間を短縮できます。
md5sum を新規作成する
pacman 4.1 から makepkg -g >> PKGBUILD
は必要なくなり、pacman-contrib は updpkgsums
スクリプトに併合されました。このスクリプトを使って PKGBUILD の中に新しいチェックサムを生成することができます:
$ updpkgsums
Makepkg が PKGBUILD を二度利用する
Makepkg は PKGBUILD を二度実行します (最初に実行した時と、fakeroot 下で2回目)。PKGBUILD に置かれた標準から外れた関数は全て同じく二度実行されます。
圧縮しないパッケージを作成する
パッケージをローカルでインストールしたいだけの場合、LZMA2 の圧縮と解凍を避けることでプロセスを高速化できます:
/etc/makepkg.conf
[...] #PKGEXT='.pkg.tar.xz' PKGEXT='.pkg.tar' [...]
以下のように圧縮アルゴリズムを指定してビルドすることもできます (lzop アルゴリズムを使用する例、lzo パッケージが必要です):
$ PKGEXT='.pkg.tar.lzo' makepkg
マルチコアを利用して圧縮する
xz は対称型マルチプロセッシング (SMP) による圧縮をサポートしています。--threads
オプションを使うことでマルチコアを活用できます:
/etc/makepkg.conf
[...] COMPRESSXZ=(xz -c -z - --threads=0) [...]
64ビット環境で32ビットのパッケージをビルド
まず multilib リポジトリを有効にして multilib-devel をインストールしてください。gcc
や gcc-libs
パッケージを削除するかどうかきかれたら yes と答えてください。gcc-multilib は64ビットと32ビット両方のソフトウェアをビルドすることができます。
それから32ビットの設定ファイルを作成:
~/.makepkg.i686.conf
CARCH="i686" CHOST="i686-unknown-linux-gnu" CFLAGS="-m32 -march=i686 -mtune=generic -O2 -pipe -fstack-protector-strong" CXXFLAGS="${CFLAGS}" LDFLAGS="-m32 -Wl,-O1,--sort-common,--as-needed,-z,relro"
そして makepkg を以下のように実行してください:
$ linux32 makepkg --config ~/.makepkg.i686.conf
トラブルシューティング
Makepkg によるパッケージの署名に失敗する
gnupg 2.1 から gpg-agent は手動で起動する必要がなくなり、gpg を実行したときに自動的に起動します。gpg-agent を手動で起動しなかったとき makepkg によって起動されます。問題は makepkg が fakeroot で gpg を起動するため、gpg-agent も同じ環境で起動されてしまいます。これによって問題が起こります。makepkg を実行する前に手動で gpg-agent を起動することで解決できますが (詳しくは GnuPG#gpg-agent を参照)、信頼性のある方法ではありません: FS#49946。
gpg-agent の設定に頭を使いたくない場合、署名は後回しにして makepkg を実行し、それから gpg --detach-sign name.pkg.tar.xz
でパッケージに署名する方法もあります。
QMAKE を使用するパッケージで makepkg.conf の CFLAGS/CXXFLAGS/CPPFLAGS が適用されない
Qmake は CFLAGS
と CXXFLAGS
変数を自動的に設定します。makepkg の設定ファイルで定義した変数を qmake に使わせるには、PKGBUILD を編集して QMAKE_CFLAGS_RELEASE と QMAKE_CXXFLAGS_RELEASE 変数を qmake に指定する必要があります。例:
PKGBUILD
... build() { cd "$srcdir/$_pkgname-$pkgver-src" qmake-qt4 "$srcdir/$_pkgname-$pkgver-src/$_pkgname.pro" \ PREFIX=/usr \ QMAKE_CFLAGS_RELEASE="${CFLAGS}"\ QMAKE_CXXFLAGS_RELEASE="${CXXFLAGS}" make } ...
もしくは、システム全体で設定したい場合、qmake.conf
を作成して QMAKESPEC 環境変数を設定してください。
QMAKE を使用するパッケージのインストールディレクトリを指定する
qmake によって生成される makefile は INSTALL_ROOT
環境変数を使ってプログラムをインストールするディレクトリを指定します。したがって package 関数を以下のようにしてください:
PKGBUILD
... package() { cd "$srcdir/${pkgname%-git}" make INSTALL_ROOT="$pkgdir" install } ...
また、qmake を正しく設定する必要があります。例えば .pro ファイルに以下を記述してください:
YourProject.pro
... target.path = /usr/local/bin INSTALLS += target ...
WARNING: Package contains reference to $srcdir
リテラル文字列 $srcdir
か $pkgdir
があなたのパッケージ内のインストールされたファイルのどれかに含まれています。
ファイルを確認するには、makepkg のビルドディレクトリから次のコマンドを実行してください:
$ grep -R "$(pwd)/src" pkg/
詳しくは こちら を参照。
参照
- gcccpuopt: 現在の CPU にあわせた gcc の cpu オプションを表示するスクリプト
- makepkg のソースコード