Android 共有ライブラリは、随時進化しています。ビルド済みのバイナリを最新の状態に保つにはかなりの労力が必要です。Android 9 以前では、削除されたライブラリや ABI に依存するビルド済みのバイナリはランタイムでのリンク失敗となるしかありませんでした。デベロッパーは、古くなったビルド済みバイナリを検出するためにログをトレースする必要がありました。Android 10 では、シンボルベースの ABI 使用状況チェッカーが導入されています。このチェッカーは、ビルド時に古くなったビルド済みのバイナリを検出できるので、共有ライブラリのデベロッパーは、変更により無効となった可能性のあるビルド済みのバイナリと、ビルドし直す必要のあるバイナリを判断できます。
シンボルベースの ABI 使用状況チェッカー
シンボルベースの ABI 使用状況チェッカーは、ホスト上の Android ダイナミック リンカーをエミュレートします。 チェッカーは、ビルド済みのバイナリをその依存関係とリンクし、すべての未定義のシンボルが解決したかどうかを確認します。
はじめに、チェッカーはビルド済みバイナリのターゲット アーキテクチャを確認します。ビルド済みのバイナリが、ARM、AArch64、x86、x86-64 アーキテクチャをターゲットとしていない場合、チェッカーはそのビルド済みのバイナリをスキップします。
2 番目に、ビルド済みのバイナリの依存関係は、LOCAL_SHARED_LIBRARIES
または shared_libs
にリストされている必要があります。ビルドシステムは、モジュール名を共有ライブラリの一致するバリアント(例: core
か vendor
か)に解決します。
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
チェッカーを実行する
チェッカーを実行するには、環境変数 CHECK_ELF_FILES
を true
に設定してから make check-elf-files
を実行します。
CHECK_ELF_FILES=true make check-elf-files
デフォルトでチェッカーを有効にするには、PRODUCT_CHECK_ELF_FILES
を BoardConfig.mk
に追加します。
PRODUCT_CHECK_ELF_FILES := true
事前にビルドされたものは、Android のビルドプロセス中に自動的に確認されます。
make