記事の目的
ターゲット環境が違っても、ビルドスクリプトを修正せずに、いい感じでビルドしてくれるAutotoolsとpkg-config。
いつも、なんとなくで使ってしまっているので、自分の使う範囲で、何をしてくれているのか、を整理する。
ツールの概要
Autotools
Wikipedia Autotools
Autotoolsとは、主にUnix系オペレーティングシステム (OS) においてソフトウェアパッケージ開発を行うための、ツール及びフレームワークの一種である。このツールを使用することにより、多種多様なUNIX互換環境にパッケージを対応させることが容易になる。 Autotoolsは主に autoconf/automake/libtools の3つから成り立っている。
autoconf
configure.acからconfigureを生成する。クロスコンパイラの対応は、configureがやってくれている。
Yoctoでクロス開発環境を作成した場合、ツールチェーンをsourceした後、下記のようにconfigureをかける。
./configure ${CONFIGURE_FLAGS}
${CONFIGURE_FLAGS}の中身を見ると、クロスコンパイラの環境変数を設定していそうなことがわかる。
echo ${CONFIGURE_FLAGS} --target=arm-poky-linux-gnueabi --host=arm-poky-linux-gnueabi --build=x86_64-linux --with-libtool-sysroot=/opt/poky/2.2+snapshot/sysroots/cortexa7hf-neon-vfpv4-poky-linux-gnueabi
automake
Makefile.amからMakefile.inを生成する。
Makefile.inの時点では、環境固有の設定は、反映されていない。
configureが、Makefile.inに環境固有の設定を追加することで、最終的なMakefileが生成される。
libtool
使っていないので割愛。
pkg-config
Wikipedia pkg-config
pkg-configとは、ライブラリを利用する際に必要となる各種フラグやパス等を、共通したインターフェースで提供でするための手段である。
つまり、ライブラリが簡単に使えますよ、って話。
サンプル
環境
- Ubuntu 16.04
- glibを使ったhello world
- ソースコード
※クリーンな環境で試していないが、↓でだいたい必要なものがそろう、はず!
sudo apt-get install -y build-essential libglib2.0-0 libglib2.0-dev autoconf automake libtool
ビルド&実行手順
ビルド
git clone https://github.com/tomoyuki-nakabayashi/autotools-hello.git
cd autotools-hello
autoreconf -fi
./configure
make
実行
./src/hello
hello world
Dive into サンプル
glib使うところ以外は、GNU Autotools で「Hello, World」を参考にさせて頂きました。
configure.ac
glibがビルド環境にあるかどうか、をconfigure.acでチェックする行を追加。
PKG_CHECK_MODULES(GLIB, [glib-2.0])
PKG_CHECK_MODULESは、autoconfとpkg-configのインタフェースとなるマクロ。
第一引数に、コンパイル時のフラグやライブラリ参照で利用するprefixを指定する。
第二引数に、pkg-configのサーチパスで見つかるモジュール名を指定する。(自分の環境では、インクルードパスが『/usr/include/glib-2.0/』なので、"glib"ではダメで、"glib-2.0"とする必要がある)
src/Makefile.am
configure.acのPKG_CHECK_MODULESで指定したprefixを使って、コンパイルフラグとライブラリ参照を追加する。
hello_CFLAGS = \
@CFLAGS@ \
@GLIB_CFLAGS@
hello_LDADD = \
@GLIB_LIBS@
この意味はなんなのか?
make実行時のログを見てみると、どうやらgccは↓の通り実行されている。
gcc -g -O2 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -g -O2 -o hello hello-main.o -lglib-2.0
Makefile.amを編集しながらmakeすると、CFLAGSは"-g -O2"、GLIB_CFLAGSは"-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include"、GLIB_LIBSは"-lglib-2.0"と連動することがわかる。
src/Makefileを見ると次のようになっている。なるほど。
GLIB_CFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
GLIB_LIBS = -lglib-2.0
Yoctoで作成したクロスビルド環境を使った場合は、次のようになっている。なるほど。
GLIB_CFLAGS = -I/opt/poky/2.2+snapshot/sysroots/cortexa7hf-neon-vfpv4-poky-linux-gnueabi/usr/include/glib-2.0 -I/opt/poky/2.2+snapshot/sysroots/cortexa7hf-neon-vfpv4-poky-linux-gnueabi/usr/lib/glib-2.0/include
GLIB_LIBS = -lglib-2.0
ちなみに、src/Makefile.inの時点では、環境固有のパスになっていない。configureで環境固有の設定を反映するってそういうことね。なるほど。
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
まとめ
ちょっとだけ何をしているかがわかった。