トップ > ビルド > 開発ツールのビルド >
pkg-config

  

pkg-configのビルド

pkg-configは、ライブラリの利用に必要となる情報を提供するツールです。 環境変数 PKG_CONFIG_PATH に定義されているパスに置かれている *.pc ファイルから情報を取得し、それを返します。

環境変数 PKG_CONFIG_PATH はすでに定義済みです。 すでに実施した事前準備 > MinGWのセットアップ - 4. .profileファイルの作成 -で、.profileファイル内に記述しました。 その内容は以下の通りです。

export PKG_CONFIG_PATH=/working/gimp/lib/pkgconfig:/working/tools/lib/pkgconfig

ソースファイルの展開

まず、ソースファイルを展開します。 MinGW Shell上で以下を実行します。


cd /working/sources
tar xvf /working/sources/pkg-config-0.27.1.tar.gz
cd pkg-config-0.27.1

 

configure

続いて、configureを実行します。 MinGW Shell上で以下を実行します。


CPPFLAGS="-march=pentium -mtune=pentium" \
./configure \
  --prefix=/working/tools \
  --with-internal-glib > ../configurelog.pkgconfig 2>&1

 
  
インストール先の基準ディレクトリを --prefix=/working/tools としています。 すでに説明したように、開発ツールはインストール先を /working/tools とするためです。
  
変数 CPPFLAGS で指定している "-march=pentium -mtune=pentium" は、Pentiumでも動作する命令を生成させるための指定です。

configureが終了したら、ログファイルに出力された内容を参照し、正常に終了したことを確認します。


cat ../configurelog.pkgconfig

 

以下は正常に終了した場合の例です。

...(省略)...
configure: creating ./config.status
config.status: creating Makefile
config.status: creating glib/Makefile
config.status: creating glib/libcharset/Makefile
config.status: creating glib/gnulib/Makefile
config.status: creating m4macros/Makefile
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands
config.status: executing glib/glibconfig.h commands

以下のように、"error" と表示されていれば問題が発生したことを意味しています。

...(省略)...
checking for an ANSI C-conforming const... yes
checking for size_t... yes
checking whether struct tm is in sys/time.h or time.h... time.h
checking for C/C++ restrict keyword... __restrict
checking for working strtod... yes
checking for memset... yes
checking for pow... yes
checking for zlibVersion in -lz... no
checking for z_zlibVersion in -lz... no
configure: error: zlib not installed
  
エラーが発生した場合は、解決してから次へ進んでください。
  
GoogleやYahoo!等で、エラーの内容で検索するのがいいでしょう。 例えば、上記のエラーの例では "error: zlib not installed" で検索します。

ビルド

続いて、ビルドを実行します。 MinGW Shell上で以下を実行します。


make

 

makeが終了したら、画面に出力された内容を参照し、正常に終了したことを確認します。 以下は正常に終了した場合の例です。

...(省略)...
pkg.c:884:21: warning: unknown escape sequence: '\/' [enabled by default]
  CC     parse.o
  CC     main.o
  CCLD   pkg-config.exe
make[2]: Leaving directory `/working/sources/pkg-config-0.27.1'
Making all in check
make[2]: Entering directory `/working/sources/pkg-config-0.27.1/check'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/working/sources/pkg-config-0.27.1/check'
make[1]: Leaving directory `/working/sources/pkg-config-0.27.1'

インストール

続いて、インストールを行います。 MinGW Shell上で以下を実行します。


make install

 

インストールが終了したら、画面に出力された内容を参照し、正常に終了したことを確認します。 以下は正常に終了した場合の例です。

...(省略)...
 /bin/install -c -m 644 pkg-config.1 '/working/tools/share/man/man1'
make[2]: Leaving directory `/working/sources/pkg-config-0.27.1'
make[1]: Leaving directory `/working/sources/pkg-config-0.27.1'
Making install in check
make[1]: Entering directory `/working/sources/pkg-config-0.27.1/check'
make[2]: Entering directory `/working/sources/pkg-config-0.27.1/check'
make[2]: Nothing to be done for `install-exec-am'.
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/working/sources/pkg-config-0.27.1/check'
make[1]: Leaving directory `/working/sources/pkg-config-0.27.1/check'

シェル内の変数について

ここでは、configureの実行時に、

CPPFLAGS="-march=pentium -mtune=pentium" \
./configure \
  --prefix=/working/tools \
  --with-internal-glib > ../configurelog.pkgconfig 2>&1

のように、実行するシェルのパス(./configure)の前に変数 CPPFLAGS を付加しています。 上記のコマンドは複数行に分けているため見づらいですが、1行で記述すると以下になります。

CPPFLAGS="-march=pentium -mtune=pentium" ./configure --prefix=/working/tools --with-internal-glib > ../configurelog.pkgconfig 2>&1

上記のように ./configure の前に変数 CPPFLAGS が定義されています。 一般的に、シェル内の変数といえば、

NAME=value

と記述するシェル変数(子シェルには渡されない)や、

NAME=value
export NAME

または、

export NAME=value

と記述する環境変数(子シェルにも渡される)が知られています。

実は、上記のシェル変数と環境変数以外にも、子シェルにだけ渡される一時的な変数があります。 一時的な変数は、

NAME=value run.sh

と記述します。 この場合には run.sh に変数 NAME が渡されますが、呼び出し元のシェル(コマンドを打ち込んだシェル)には変数 NAME は定義されません。

つまり、run.sh が実行されている間だけ、run.sh 内に存在する変数というわけです。

  

リダイレクトの 2>&1 について

ここでは、configureの実行結果を、

CPPFLAGS="-march=pentium -mtune=pentium" \
./configure \
  --prefix=/working/tools \
  --with-internal-glib > ../configurelog.pkgconfig 2>&1

のように、親ディレクトリの configurelog.pkgconfig ファイルにリダイレクトしていますが、リダイレクトの後ろに、

2>&1

と記述しています。 この記述は、標準エラー出力への出力内容を標準出力へ流し込むためのものです。

例えば、

run.sh > run.log

として実行すると、標準出力への出力内容は run.log ファイルへ出力されますが、標準エラー出力への出力内容は画面に表示されます。

そこで、

run.sh > run.log 2>&1

として実行することで、標準エラー出力への出力内容を標準出力へ流し込み、さらに標準出力への出力内容を run.log ファイルへ出力させることができます。 つまり、画面への出力内容の全てを run.log ファイルへ出力することができます。

順序が大切

リダイレクト関連の記述は順序が大切です。 例えば、

run.sh 2>&1 > run.log

として実行してしまうと、画面への出力内容の全てを run.log ファイルへ出力することはできません

リダイレクトの記述はコマンドラインの後ろから前に向かって解釈されます。 つまり、上記の例だと、標準出力への出力内容が run.log ファイルへ出力された後に、標準エラー出力への出力内容が標準出力へ出力されます。 ということは、

run.sh > run.log

と同じ結果にしかならないということです。

順序について少し詳しく

正確には、シェルはリダイレクトの記述を後ろから解釈するわけではなく、ちゃんと前から解釈してくれます。 ではなぜ、

run.sh 2>&1 > run.log

としてはダメなか、もう少し詳しく説明します。 コマンドを入力するとシェルはどのように解釈しているかを見てみましょう。

コマンドが入力されるとシェルは最初に、

  1. 標準入力をキーボードに対応させる
  2. 標準出力を画面に対応させる
  3. 標準エラー出力を画面に対応させる

という関連付けを行います。 ここで大切なことは、標準入力とキーボード / 標準出力と画面 / 標準エラー出力と画面はまだ接続されていない、ということです。

キーボードが紐で標準入力とつながっている様子や標準出力が紐で画面につながっている様子は想像しないでくださいそういう状態ではありません

想像すべきは、"標準入力" というラベルが貼られた箱があり、そこに "キーボード" と書かれた紙が入っている様子です。 同じく、"標準出力" というラベルの箱には "画面" と書かれた紙が、"標準エラー出力" というラベルの箱にも "画面" と書かれた紙が入っています。

箱のラベル 箱の中身
標準入力 "キーボード" と書かれた紙
標準出力 "画面" と書かれた紙
標準エラー出力 "画面" と書かれた紙

続いてシェルは、

run.sh

の部分を解釈します。 この部分は実行するコマンドであり、リダイレクトには関係ありません。

次にシェルは、

2>&1

の部分を解釈します。 そして『標準エラー出力の出力先を標準出力と同じにせよ』という命令だと理解します。

そのように理解したシェルは、まず "標準エラー出力" のラベルの箱に入っている "画面" という紙を捨てます。 続いて "標準出力" のラベルの箱にある "画面" という紙を複製し、"標準エラー出力" のラベルの箱に入れます。 また、その紙に注意書きで "上書きではなく追加" と書き加えます。

箱のラベル 箱の中身
標準入力 "キーボード" と書かれた紙
標準出力 "画面" と書かれた紙
標準エラー出力 "画面" と書かれた紙
※"上書きではなく追加" と注意書きあり

最後にシェルは、

> run.log

の部分を解釈します。 そして "標準出力" のラベルの箱の紙を "ファイル run.log" と書かれた新しい紙で入れ替えます。

箱のラベル 箱の中身
標準入力 "キーボード" と書かれた紙
標準出力 "ファイル run.log" と書かれた紙
標準エラー出力 "画面" と書かれた紙
※"上書きではなく追加" と注意書きあり

シェルはコマンドの解析を終えました。 "標準エラー出力" というラベルの箱には何と書かれた紙が入っているでしょうか。

そうです、紙には "画面" と書かれています。 結果、標準エラー出力は画面に出力されるのです。


なお、難しいことは考えずにリダイレクトの記述はコマンドラインの後ろから前に向かって解釈されると覚えておけばいいでしょう。 間違っていますが、覚えやすいですから。

上書きされないように注意が必要

なお、

run.sh 2> run.log > run.log

や、

run.sh 2> run.log > 1> run.log

として実行してしまうと、やはり、画面への出力内容の全てを run.log ファイルへ出力することはできません

上記の例だと、標準出力への出力内容が run.log ファイルへ出力された後に、標準エラー出力への出力内容が run.log ファイルへ出力されてしまうためです。 つまり、標準エラー出力への出力内容で上書きされてしまうのです。

そうなる理由は、"標準エラー出力" というラベルの箱には "ファイル run.log" と書かれた紙が入っていますが、"上書きではなく追加" という注意書きが書かれていないからです。

便利な記述もある

もっと簡単に、

run.sh >& run.log

と記述することで、

run.sh > run.log 2>&1

と同じ結果を得られます。

なお、この記述は、sh、bash、ksh、zsh、csh、tcshで使えるようです。

  
筆者には、上記シェル群の全てを試す環境はありません。 そのため、本当に上記シェル群の全てでこの記述が使えるのかは未確認です
  

まとめ

pkg-configは、ライブラリのビルドに必要となる情報を提供するツールです。

メニュー