インストール: pkg-config | パッケージのコンパイル用の情報を出力するビルドツール

GNOME Terminal

ビルドツールであるpkg-configをソースコードからインストールする。

pkg-configはソフトウェアのビルド時の依存関係を解決するためのツールであり,他のビルドツールであるCMakeやGNなどからも使われている。

本来ならば,ビルド時に必要なライブラリーのインストール場所はユーザーの環境ごとに異なっている。

/usr/share/pkgconfig/usr/lib/pkgconfigなどに格納されるpkg-configの形式の.pcファイルが存在すれば,pkg-configコマンドにより,ビルドに必要なヘッダーやライブラリーの指定を.pcファイルに従って出力してくれる。

例えば,以下のようにヘッダー (--cflags) とライブラリー (--libs) を指定すれば,該当するパス付きでビルドオプションを表示してくれる。

pkg-config --cflag --libs zlib
-I/home/senooken/.local/stow/zlib-1.2.11/include -L/home/senooken/.local/stow/zlib-1.2.11/lib -lz

この出力結果を使い,以下のようにコンパイル時のコマンドラインに活用できる。

gcc -o out.exe source.cpp $(pkg-config --cflag --libs zlib)

pkg-configにより,ビルドオプションの指定を抽象化でき,ビルドが簡単になる。

インストール手順
インストール情報
項目説明
配布元pkg-config
リポジトリー
手順
依存情報README · master · pkg-config / pkg-config · GitLab
依存先 (必須)GLib
依存先 (任意)pkg-config
依存元CMake, GN
インストールコマンド
sh -eux <<-"EOT"
PKG=pkg-config VER=0.29.2 TAG=$PKG-$VER
LOCAL=~/.local J=$(grep -cs '^processor' /proc/cpuinfo || echo 2)
mkdir -p "$LOCAL/src"
cd "$LOCAL/src"

if command -v git >/dev/null; then
  [ -e $PKG ] || git clone --depth 1 https://gitlab.freedesktop.org/pkg-config/pkg-config $PKG
  cd $PKG
  git fetch --depth 1 origin tag $TAG
  git checkout -f $TAG
  git clean -dfX
  ACLOCAL="aclocal --system-acdir=." autoreconf -is
else
  [ -e $PKG-$VER ] || wget https://pkg-config.freedesktop.org/releases/pkg-config-0.29.2.tar.gz
  tar -xf $PKG-$VER.*
  cd $PKG-$VER
  make -kj $J distclean clean || :
fi

[ $(echo "$VER" | sed 's/[^0-9]//g') -le 0292 ] && patch -Np 1 <<-"EOP" || :
diff --git a/check/check-system-flags b/check/check-system-flags --- a/check/check-system-flags +++ b/check/check-system-flags @@ -34,10 +34,10 @@ PKG_CONFIG_SYSTEM_INCLUDE_PATH=/foo/include PKG_CONFIG_SYSTEM_LIBRARY_PATH=/foo/lib RESULT="-I/usr/include" -run_test --cflags system +PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 run_test --cflags system RESULT="-L/usr/lib -lsystem" -run_test --libs system +PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 run_test --libs system # Now check that the various GCC environment variables also update the # system include path @@ -56,7 +56,7 @@ done # system include path when --msvc-syntax is in use for var in INCLUDE; do RESULT="-I/usr/include" - eval $var=/usr/include run_test --cflags system + eval PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 r$var=/usr/include run_test --cflags system # Make sure these are skipped in --msvc-syntax mode if [ "$native_win32" = yes ]; then EOP
./configure --prefix="$LOCAL/stow/$PKG-$VER" --with-internal-glib make -j $J make -j $J check make -j $J install cd "$LOCAL/stow" echo $PKG-[0-9]* | xargs -n 1 stow --ignore=dir -D stow --ignore=dir $PKG-$VER EOT
インストール例
日付バージョンOS依存関係
2019-06-080.29.2Ubuntu 18.04GNU Make 4.2.1, GCC 7.4.0

pkg-configの依存関係には,Glibと古いバージョンのpkg-configが存在している。ただし,Glibの依存関係にもpkg-configが存在している。そのため,依存関係のループができており,インストールするのが煩雑だった。

これを回避するために,configureに--with-internal-glibを指定した。READMEにも記載がある通り,これによりpkg-configに同梱されているGlibを使ってpkg-configをビルドできる。そのため,Glibの依存関係であるGNU MakeとGCCさえ用意できればpkg-configもビルドできる

リポジトリーからのビルド用に,autogen.shが存在している。このautogen.shは中でconfigureの実行まで行っている。配布用ソースコードとビルド手順を統一するために,autogen.shを直接使わず,中で実行しているautoreconfだけ実行し,その後configureを実行している。

autoreconfのエラー対応

autogen.sh (autoreconf -is) の実行時に以下のエラーが出てしまった。

autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal ${ACLOCAL_FLAGS}
autoreconf: configure.ac: tracing
autoreconf: configure.ac: adding subdirectory glib to autoreconf
autoreconf: Entering directory `glib'
autoreconf: running: aclocal -I m4macros ${ACLOCAL_FLAGS}
m4macros/glib-gettext.m4:39: error: m4_copy: won't overwrite defined macro: glib_DEFUN
m4macros/glib-gettext.m4:39: the top level
autom4te: /usr/bin/m4 failed with exit status: 1
aclocal: error: echo failed with exit status: 1
autoreconf: aclocal failed with exit status: 1

autoreconfが内部で,glib/配下でaclocal -I m4macros ${ACLOCAL_FLAGS}を実行して,m4_copyの実行でエラーが出ているようだ。

m4_copy([AC_DEFUN],[glib_DEFUN])

aclocalコマンドのm4_copyマクロは,第2引数が未定義であることを保証するらしい。つまり,定義済みの場合,エラーになるようだ。

ここでは,glib_DEFUNマクロが定義済みであるためにエラーが出ている。

実際に,aclocalのサーチパスのマクロを確認したところ,システムが持っている/usr/share/aclocal/glib-gettext.m4内で既にglib_DEFUNが定義されていた。

このファイルをどかせば,エラーなく実行できるが,システムのファイルは操作したくない。対応方法を調べていたところ,autoreconfのmanなどで,autoreconf内部で実行しているコマンドを環境変数で上書きできるようだ。

The environment variables AUTOM4TE, AUTOCONF, AUTOHEADER, AUTOMAKE, ACLOCAL, AUTOPOINT, LIBTOOLIZE, M4, and MAKE may be used to override the invocation of the respective tools.
autoreconf Invocation – Autoconf

今回マクロが定義されていた/usr/share/aclocal/のディレクトリーはシステムのサーチパスとなっている。これを上書きするには,aclocalコマンドのオプションに--system-acdirを指定する必要がある。-I-Bオプションはシステムのサーチパスの前後にパスを追加するだけであるため,--sytsem-acdirで上書きする必要があった。

そこで,以下のコマンドを実行することでエラーを回避した。

ACLOCAL="aclocal --system-acdir=." autoreconf -is
make check失敗対応

make check実行時に以下のcheck-system-flagsテストが失敗してしまった。

PASS: check-dependencies
../pkg-config --cflags system :
'' != '-I/usr/include'
FAIL: check-system-flags
==============================================================================
1 of 30 tests failed
Please report to https://bugs.freedesktop.org/enter_bug.cgi?product=pkg-config
==============================================================================

失敗したテストの実行ファイルはcheck/check-system-flagsに存在していた。

ファイルの冒頭にset -vxを指定してログ出力することで,テストに失敗した箇所を36行目付近だと特定できた。

PKG_CONFIG_SYSTEM_INCLUDE_PATH=/foo/include
PKG_CONFIG_SYSTEM_LIBRARY_PATH=/foo/lib

RESULT="-I/usr/include"
run_test --cflags system

どうやら,pkg-configはデフォルトではシステムのインクルード (/usr/include) とライブラリー (/usr/lib) パスは,削除する挙動となっている。pkg-configに–debugオプションを指定すると,一度追加されたパスを削除しているメッセージが出ていた。

そのため,RESULTに/usr/includeか/usr/libがあっても,pkg-configが勝手に削除するため,結果が合わなかった。直前のテストコマンドと同様に環境変数のPKG_CONFIG_ALLOW_SYSTEM_CFLAGSPKG_CONFIG_ALLOW_SYSTEM_LIBSの設定が必要だった。

そこで,以下のパッチを当てることで対応した。

--- a/check/check-system-flags
+++ b/check/check-system-flags
@@ -34,10 +34,10 @@ PKG_CONFIG_SYSTEM_INCLUDE_PATH=/foo/include
 PKG_CONFIG_SYSTEM_LIBRARY_PATH=/foo/lib
 
 RESULT="-I/usr/include"
-run_test --cflags system
+PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 run_test --cflags system
 
 RESULT="-L/usr/lib -lsystem"
-run_test --libs system
+PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 run_test --libs system
 
 # Now check that the various GCC environment variables also update the
 # system include path
@@ -56,7 +56,7 @@ done
 # system include path when --msvc-syntax is in use
 for var in INCLUDE; do
     RESULT="-I/usr/include"
-    eval $var=/usr/include run_test --cflags system
+    eval PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 r$var=/usr/include run_test --cflags system
 
     # Make sure these are skipped in --msvc-syntax mode
     if [ "$native_win32" = yes ]; then

問題の原因と対策がわかったので,配布元にも以下のissueで報告し,パッチを提出した。

Is the test of “check-system-flags” right? (#51) · Issues · pkg-config / pkg-config · GitLab

うまく本体に取り込まれれば,次回のバージョンの0.29.3からこのパッチが不要になるだろう。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です