ビルド済み ABI 使用状況チェッカー

Android 共有ライブラリは、随時進化しています。ビルド済みのバイナリを最新の状態に保つにはかなりの労力が必要です。Android 9 以前では、削除されたライブラリや ABI に依存するビルド済みのバイナリはランタイムでのリンク失敗となるしかありませんでした。デベロッパーは、古くなったビルド済みバイナリを検出するためにログをトレースする必要がありました。Android 10 では、シンボルベースの ABI 使用状況チェッカーが導入されています。このチェッカーは、ビルド時に古くなったビルド済みのバイナリを検出できるので、共有ライブラリのデベロッパーは、変更により無効となった可能性のあるビルド済みのバイナリと、ビルドし直す必要のあるバイナリを判断できます。

シンボルベースの ABI 使用状況チェッカー

シンボルベースの ABI 使用状況チェッカーは、ホスト上の Android ダイナミック リンカーをエミュレートします。 チェッカーは、ビルド済みのバイナリをその依存関係とリンクし、すべての未定義のシンボルが解決したかどうかを確認します。

はじめに、チェッカーはビルド済みバイナリのターゲット アーキテクチャを確認します。ビルド済みバイナリのターゲットが ARM、AArch64、x86、x86-64 アーキテクチャでない場合、チェッカーはそのビルド済みバイナリをスキップします。

次に、ビルド済みバイナリの依存関係が LOCAL_SHARED_LIBRARIES または shared_libs で指定されていることを確認します。ビルドシステムは、モジュール名を共有ライブラリの一致するバリアント(例: corevendor か)に解決します。

3 番目に、チェッカーは、DT_NEEDED エントリを LOCAL_SHARED_LIBRARIES または shared_libs と比較します。具体的には、チェッカーは DT_SONAME エントリを各共有ライブラリから抽出し、これらの DT_SONAME をビルド済みのバイナリに記録された DT_NEEDED エントリと比較します。不一致がある場合は、エラー メッセージが出ます。

4 番目に、チェッカーは、ビルド済みのバイナリの未定義シンボルを解決します。これらの未定義のシンボルは、依存関係のいずれか 1 つに定義される必要があり、シンボル バインディングは GLOBAL または WEAK である必要があります。未定義のシンボルを解決できない場合は、エラー メッセージが出力されます。

モジュールのプロパティを事前にビルドする

ビルド済みのバイナリの依存関係は、次のいずれか 1 つに指定する必要があります。

  • Android.bp: shared_libs: ["libc", "libdl", "libm"],
  • Android.mk: LOCAL_SHARED_LIBRARIES := libc libdl libm

ビルド済みのバイナリが未解決の未定義シンボルを持つように設計されている場合は、次のいずれかを指定します。

  • Android.bp: allow_undefined_symbols: true,
  • Android.mk: LOCAL_ALLOW_UNDEFINED_SYMBOLS := true

ビルド済みバイナリへの ELF ファイル チェックをスキップするには、次のいずれかを指定します。

  • Android.bp: check_elf_files: false,
  • Android.mk: LOCAL_CHECK_ELF_FILES := false

チェッカーを実行する

チェッカーは、Android ビルドプロセスにおけるすべての ELF ビルド済みモジュールに対応しています。

チェッカーを単独で実行して処理時間を短縮するには:

m check-elf-files

ABI エラー修正ツール

自動修正ツールは ABI チェックエラーの解決に役立ちます。Android.bp / Android.mk を入力として修正ツールを実行すると、修正候補が stdout に出力されます。必要に応じて、--in-place オプションを指定して修正ツールを実行すると、修正候補を使用して Android.bp / Android.mk が直接更新されます。

Android.bp の場合:

m fix_android_bp_prebuilt
# Print the fixed Android.bp to stdout.
fix_android_bp_prebuilt <path-to-Android.bp>
# Update the Android.bp in place.
fix_android_bp_prebuilt --in-place <path-to-Android.bp>

Android.mk の場合:

m fix_android_mk_prebuilt
# Print the fixed Android.mk to stdout.
fix_android_mk_prebuilt <path-to-Android.mk>
# Update the Android.mk in place.
fix_android_mk_prebuilt --in-place <path-to-Android.mk>