トホホな疑問(48) Termux、pkg-configでMagick++呼ぶcppをビルド

Joseph Halfmoon

前回Androidスマホの上でXウインドウが稼働、user権限ですが本格的にLinuxです。しかしトホホな件がいくつも。その1つがImageMagickのAPIを呼び出すC++のコードをコンパイルできん、という1件。調べて分かったのは、Termuxのpkg-configちゃんと出来てる、ということ。これでビルド成功。

ImageMagick

ImageMagickといえば、画像のサイズ変更、フォーマット変換などで活躍するコマンド群です。Linuxではもちろん、Windowsでも多用されているんじゃないかと思います。知らないうちにお世話になっていることも多い裏方さん?

ImageMagickのライブラリ(API)をC++などで呼び出せば、簡単に画像の変換プログラムなど書けてしまうので便利です。今回は以下の

640×480ピクセルサイズの真っ白画面の左上あたりに一本赤の線を引く

というだけのC++コード(エラーチェック等皆無、引数与えないとセグメンテーション・フォルトになる)をAndroidスマホ上でビルドして走らせてみます。

#include <iostream>
#include <Magick++.h>

using namespace Magick;

int main(int argc, char *argv[]) {
  std::cout << "image.pixel test" <<std::endl;
  InitializeMagick(*argv);
  Image image("640x480", "white");
  for (int x=10; x<50; x++) {
    image.pixelColor(x,10, "red");
  }
  image.write(argv[1]);
  return 0;
}

先に今回コンパイル成功したコマンドラインを書いておきます。なお、Termuxはデフォルトで clang/LLVM です。gccは入ってないです。こんな感じ。

$ clang++ -o simpleImage simpleImage.cpp `pkg-config Magick++ --cflags --libs`
Magick++-configはどこに?

ImageMagickの場合、コンパイル時のコマンドラインの指定が複雑になるのを「独自」に助けるために、Magick++-config などのスクリプトが用意されているみたいです。こいつがあれば簡単な筈ということでTermuxのディレクトリ内を探してみると以下にありました。パスが通っているじゃん!

$PREFIX/bin

  • Magick++-config
  • MagickCore-config
  • MagickWand-config

お仲間のスクリプト3つ、仲良くそろっておられます。そこでC++のソースのコンパイルに使う Magick++-config を使ってコンパイルを試みました。しかしコンパイル失敗。

Magick++-configの中身を確認して理由がわかりました。たとえば –cppflags を「展開」するところはこんな感じ。

 --cppflags)
   /home/builder/.termux-build/_cache/android-r23b-api-24-v8/bin/pkg-config --cflags Magick++-7.Q16HDRI
   ;;

上記に書かれている builder などというパスは手元のTermuxのディレクトリツリーにはありません。だいたい一時的なパスみたいだし。

でも上記をみると、一般的な pkg-config に「再委託」しているみたい。下請けですな。pkg-config を調べてみると、同じところ $PREFIX/bin にありました。

pkg-configのパスはどこに向いている?

まずは pkg-config のパスがどこを向いているのか調べました。インストールした状態のTermuxでは、特に PKG_CONFIG_PATH 環境変数はセットされていなかったです。ハードコードされている筈のパスは以下の「常識的」なところに向いてました。よかった。

$PREFIX/lib/pkgconfig

上記のディレクトリ内には、.pc 拡張子のファイルが多数。その中をみると以下のモノドモも混じっております。

  • GraphicsMagick++.pc
  • GraphicsMagick.pc
  • GraphicsMagickWand.pc
  • ImageMagick-7.Q16HDRI.pc
  • ImageMagick.pc
  • Magick++-7.Q16HDRI.pc
  • Magick++.pc
  • MagickCore-7.Q16HDRI.pc
  • MagickCore.pc
  • MagickWand-7.Q16HDRI.pc
  • MagickWand.pc

おお、これぞ求めている奴らではないか。今回使うつもりの Magick++ の中を確認したところ、

  • –cppflags, –cxxflags, –ldflagsは不在
  • –cflags –libsは存在

でした。C++でコンパイルなんだけれども –cppflags とか、–cxxflags とか指定せず –cflags で良いみたい。またリンカフラグの –ldflags は不要で、–libs のみ指定すれば良いと。これらを盛り込んで clang++ のコマンドラインに pkg-configを組み込んだところあっけなくビルド成功。オブジェクトファイルができました。

動作確認は以下です。

$ ./simpleImage a.png

実際に生成された a.png ファイルがこちら。隅の方に赤線一本。でも ImageMagickのAPIつかえていることは確認できた、と。

aA

クセが強いのか、強くないのか分からないTermuxですが、冷静に調べていけば

普通にLinuxできるじゃん

という感じ。スマホ1台あればなんでもできるっと。ホントか?

トホホな疑問(47) Androidスマホの中でVNC接続、TermuxのGUI へ戻る

トホホな疑問(49) Termux、「普通に」使うための試行錯誤の結果 へ進む