GLib2のインストールに失敗した話
Mac OS X 10.11.6, GCC 6.3.0, GLib 2.52.1
ご存知のようにGLibとpkg-configは相互依存している。願わくば、次に生まれる時には基盤となるようなツールやライブラリーに、相互依存関係というものが存在しない世の中に生まれたい。
結論から言えば、どちらも存在しない状態からpkg-configを入れたいのであれば、以下のように --with-internal-glib
オプションを付ければ良い。
# Install pkg-config. # https://www.freedesktop.org/wiki/Software/pkg-config/ $ cd $MY_PROJECT_ROOT/download $ wget https://pkg-config.freedesktop.org/releases/pkg-config-0.29.2.tar.gz $ tar xf pkg-config-0.29.2.tar.gz $ cd pkg-config-0.29.2 $ mkdir work $ cd work $ ../configure --prefix=$MY_PROJECT_ROOT --with-internal-glib $ make -j8 $ make install
では例えば、pkg-configをインストールせずに、GLibだけインストールしたいとしたらどうするか。
結果負けたけど、途中までは以下の手順で行けていた。
# Install libffi. (that is necessary to build GLib2) # https://sourceware.org/libffi/ $ cd $MY_PROJECT_ROOT/download $ wget ftp://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz $ tar xf libffi-3.2.1.tar.gz $ mkdir work $ cd work $ ../configure --prefix=$MY_PROJECT_ROOT $ make -j8 $ make install # Install PCRE - Perl Compatible Regular Expressions. (that is necessary to build GLib2) # http://www.pcre.org $ cd $MY_PROJECT_ROOT/download $ wget https://ftp.pcre.org/pub/pcre/pcre-8.40.tar.gz $ tar xf pcre-8.40.tar.gz $ cd pcre-8.40 $ mkdir work $ cd work $ ../configure --prefix=$MY_PROJECT_ROOT $ make -j8 $ make install # Install gettext. (that is necessary to build GLib2) # http://www.gnu.org/software/gettext/ $ cd $MY_PROJECT_ROOT/download $ wget https://ftp.gnu.org/pub/gnu/gettext/gettext-0.19.8.1.tar.xz $ tar xf gettext-0.19.8.1.tar.xz $ cd gettext-0.19.8.1 $ mkdir work $ cd work $ ../configure --prefix=$MY_PROJECT_ROOT $ make -j8 $ make install $ gettext --version gettext (GNU gettext-runtime) 0.19.8.1 # Install GLib2. (that is necessary to build pkg-config) # https://developer.gnome.org/glib/ $ cd $MY_PROJECT_ROOT/download $ wget http://ftp.gnome.org/pub/gnome/sources/glib/2.52/glib-2.52.1.tar.xz $ tar xf glib-2.52.1.tar.xz $ cd glib-2.52.1 $ mkdir work $ cd work $ LIBFFI_CFLAGS=-I$MY_PROJECT_ROOT/lib/libffi-3.2.1/include LIBFFI_LIBS="-L$MY_PROJECT_ROOT/lib -lffi" PCRE_CFLAGS=-I$MY_PROJECT_ROOT/include PCRE_LIBS="-L$MY_PROJECT_ROOT/lib -lpcre" ../configure --prefix=$MY_PROJECT_ROOT --with-pcre=internal $ make -j8 # Compile error.
オープンソースソフトウェアを使うなら、当然Cのソースくらい読めないとね。
さて、問題。
gdummymyfile.c内の下記unescape_string関数がコンパイルエラーになるわけだが、これがなぜだか分かるだろうか?
static char* unescape_string (const gchar *escaped_string, const gchar *escaped_string_end, const gchar *illegal_characters) { const gchar *in; gchar *out, *result; gint character; if (escaped_string == NULL) return NULL; if (escaped_string_end == NULL) escaped_string_end = escaped_string + strlen (escaped_string); result = g_malloc (escaped_string_end - escaped_string + 1); out = result; for (in = escaped_string; in < escaped_string_end; in++) { character = *in; if (*in == '%') { in++; if (escaped_string_end - in < 2) { g_free (result); return NULL; } character = unescape_character (in); /* Check for an illegal character. We consider '\0' illegal here. */ if (character <= 0 || (illegal_characters != NULL && strchr (illegal_characters, (char)character) != NULL)) { g_free (result); return NULL; } in++; /* The other char will be eaten in the loop header */ } *out++ = (char)character; } *out = '\0'; g_warn_if_fail (out - result <= strlen (escaped_string)); return result; }
まあ、どう見ても間違えてないよね。
こちらの方の記事に問題の原因と解決方法が示されていた。
http://d-alchemy.xyz/tips/qemu_on_snow_leopard.html
要するに、.cファイルなのに無理矢理Objective-Cとしてコンパイルさせようとしているのが問題というわけだ。
実際、上記の問題の関数を抽出し、一部修正してtest.cとしてgccでコンパイルしたらコンパイルできた。全く同じ内容で、test.mとしてgccでコンパイルするとエラーになった。
え? でもObjective-CってCのスーパーセットだよね?
そう、そんなことは本来あってはならない。
ということで、Xcode 7.2で同じことをしてみた。
結果、test.cもtest.mもコンパイルできた。
どゆこと?
どうやら問題は、変数inをforループ内で使った時に、Xcodeはきちんと構文を解釈できる。GCCはfor〜in文として見てしまうのでエラーになってしまう。ということらしい。
【問題を局所化した検証コード】
test.m
#include <stdio.h> #include <string.h> void func() { const char* psz = "Lorem ipsum dolor sit amet"; const char* in; /* for の in = のところでコンパイルエラー */ for (in = psz + strlen(psz); in >= psz; -- in) { printf("%c", *in); } } int main() { func(); return 0; }
なぁんだかねぇ…
この件は誰が悪いの?
- inなんていう汎用的な語句を予約語にしたObjective-Cが悪い
- Cocoaが内部のコアなところでObjective-Cなんて使ってるのが悪い
- .cファイルをObjective-Cでコンパイルさせんのやめえや
- Objective-Cが絡むプロジェクトで変数名 in を使うな? いやいや
- GCCちゃんってそんなのも構文解析できないの? プークスクス
- そもそもGLibとpkg-configの相互依存やめろしいややめてくださいお願いします
私が言いたいのは、「時間を返せ」、ということだけだ。