Open2

Reposoup: ライブラリグループの抽出と作成

okuokuokuoku

シンボルとヘッダファイル(と、ソースコード)の集合が用意できたので、これらの依存関係を抽出するために依存関係のあるグループに分割する。

重要なのはヘッダファイルを 暗黙的に グループにアサインする必要がある点で、例えば KHR/khrplatform.h はどのAPIのインターフェースでもないが、OpenGLESやVulkanの各ヘッダは共通で依存している。このようなケースでは Khrplatform を単独の隠しライブラリにして、OpenGLESやVulkanはこれらに依存する形にする必要がある。

特殊なライブラリ

というわけで、隠しライブラリのような特殊なライブラリが概念上存在する。Reposoupでの分類は:

  • ベースライブラリ はツールチェインがリンクするライブラリを選択するもので、pthreadとかlibc、libmが該当する。これらはライブラリ名称がプラットフォーム毎に異なる。
  • プライベートライブラリ は、プログラムから直接利用されることは基本的に企図していない、共通ライブラリを括り出すときに使用する。上記の Khrplatform のようなヘッダファイルが該当することになる。

シンボルとヘッダファイルの関係

ヘッダファイルは関数宣言やenum等を提供するが、ここでは エントリポイント にのみ注目する。呼出し可能な(つまり、staticでない)関数宣言がエントリポイントであり、原則的に全てのエントリポイントが何かしらの .so や .a でシンボルとして提供されることが期待される。

特にAndroidの以下に関心がある:

  • .so にあるが .h に無い → 過去との互換用に用意された隠しAPI (AndroidではAPIレベルを更新するとAPIが廃止されるケースがある)
  • .h にあるが .so に無い → ヘッダの間違いか .so の見落し
okuokuokuoku

ヘッダファイルからエントリポイントを抽出する

https://zenn.dev/okuoku/scraps/f231d826d17f1f

Clangを使ってプリプロセスしたヘッダファイルをASTのjsonに変換し、 kind = FunctionDecl を検索する。ただし、後からフィルタリングできるように、定義を実施したファイル名(と、デバッグ用に場所)もダンプする。

エクスポートされない関数

ちゃんとした方法を思いつかなかったので、 mangled name が存在するかどうかで識別している。

https://github.com/okuoku/rs-checker-proto/blob/ad0ed0471ef8438791a4334ecc7e837aa76a09cd/headercheck/pickast.mjs#L11

inline

inline 関数は除去する必要がある。これはnodeの storageClassinline フィルドで判断できる。

https://github.com/okuoku/rs-checker-proto/blob/ad0ed0471ef8438791a4334ecc7e837aa76a09cd/headercheck/pickast.mjs#L19-L28

Clangは必要に応じて __builtin の定義を捏造するため、これらも除去する必要がある(implicit)。

static inline struct sync_fence_info* sync_get_fence_info(const struct sync_file_info* info) {
// This header should compile in C, but some C++ projects enable
// warnings-as-error for C-style casts.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
    return (struct sync_fence_info *)(uintptr_t)(info->sync_fence_info);
#pragma GCC diagnostic pop
}

定義位置の導出

... これは全然わからん。。今は適当に実装しているが、一旦プリプロセスしてからASTに変換する等してAST自体の複雑性を下げないといけないかもしれない。

https://github.com/okuoku/rs-checker-proto/commit/93813be87e71ad8b35cb84569bc754c72a9b1470

結局、 "inner 配列の中で file または presumedFile があったら以降の要素でも使う" のが一番正確なようだ。Schemeの癖でボックス化する function box をわざわざ作ってるけど、単に単一のスコープで for を廻せば充分だな。。