エンジニアなプログラマ

プログラミング(特にvala言語関連)の話題を取り上げていきます。

現在、新しいクラス図描画ソフトを開発中! http://gridraw.com/

internal-vapiオプションのバグ?

目的

以前の記事(静的ライブラリ内のprivateクラスへアクセスする - エンジニアなプログラマ)で、 --internal-vapiオプションについて記述した。

このオプションに関してvalacのバグと思われる動作があったので、 その詳細と回避策を記録しておく。

なお、bugzillaへ報告済み。 https://bugzilla.gnome.org/show_bug.cgi?id=731322

問題点

下記ソースファイルを作成しtest.valaとする。

private class Foo1 {
}

private class N1.Foo2 {
}

private class N1.N2.Foo3 {
}

作成したtest.valaを、次のようなオプションでコンパイルする。

valac -H foo.h -h internal-foo.h --internal-vapi=foo.vapi -c test.vala

すると、生成されたfoo.vapiに出力されたヘッダーファイル名がおかしい。

/* foo.vapi generated by valac-0.24 0.24.0, do not modify. */

namespace N1 {
    namespace N2 {
        [CCode (cheader_filename = "internal-internal-internal-foo.h")]
        internal class Foo3 {
            public Foo3 ();
        }
    }
    [CCode (cheader_filename = "internal-internal-foo.h")]
    internal class Foo2 {
        public Foo2 ();
    }
}
[CCode (cheader_filename = "internal-foo.h")]
internal class Foo1 {
    public Foo1 ();
}

ヘッダーファイル名は全て"internal-foo.h"でなければならない。 しかし、上記のように"internal-internal-internal-foo.h"や "internal-internal-foo.h"というおかしなファイル名になってしまう。

原因(?)と対策

valacのソースを少しだけ見てみると、 -hで指定した文字列を、-Hで指定した文字列で置換するコードがあった。

※ 詳しく追っていないので、この置換処理の意図は不明

そこで、-Hで指定する文字列が、-hで指定する文字列に含まれないようにしてみた。

valac -H foo.h -h internal-bar.h --internal-vapi=foo.vapi -c test.vala

すると結果は問題無し。

/* foo.vapi generated by valac-0.24 0.24.0, do not modify. */

namespace N1 {
    namespace N2 {
        [CCode (cheader_filename = "internal-bar.h")]
        internal class Foo3 {
            public Foo3 ();
        }
    }
    [CCode (cheader_filename = "internal-bar.h")]
    internal class Foo2 {
        public Foo2 ();
    }
}
[CCode (cheader_filename = "internal-bar.h")]
internal class Foo1 {
    public Foo1 ();
}

結論

-h(internal-header)で指定する文字列に-H(header)で指定する文字列を含んではいけない。

※ テストしたvalacバージョンは0.22.1と0.24.0