Android 共有ライブラリは、随時進化しています。ビルド済みバイナリを最新の状態に保つには、かなりの労力が必要です。Android 9 以前では、削除されたライブラリまたは ABI に依存するビルド済みバイナリは、実行時にリンクに失敗するだけでした。古くなったビルド済みバイナリをデベロッパーが検出するには、ログをトレースする必要がありました。Android 10 では、シンボルベースの ABI 使用状況チェッカーが導入されています。このチェッカーで、古くなったビルド済みバイナリをビルド時に検出できます。したがって、共有ライブラリのデベロッパーは、変更によって無効になった可能性があるビルド済みバイナリと、再ビルドが必要なビルド済みバイナリを判別できます。
シンボルベースの ABI 使用状況チェッカー
シンボルベースの ABI 使用状況チェッカーは、ホスト上で Android ダイナミック リンカーをエミュレートします。チェッカーは、ビルド済みバイナリをその依存関係にリンクし、すべての未定義のシンボルが解決されるかどうかをチェックします。
まず、チェッカーはビルド済みバイナリのターゲット アーキテクチャを確認します。ビルド済みバイナリのターゲットが ARM、AArch64、x86、x86-64 アーキテクチャでない場合、チェッカーはそのビルド済みバイナリをスキップします。
次に、ビルド済みバイナリの依存関係が 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 でなければなりません。未定義のシンボルを解決できない場合は、エラー メッセージを出力します。
ビルド済みバイナリ モジュールのプロパティ
ビルド済みバイナリの依存関係は、次のいずれかで指定されている必要があります。
- 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