VNDK 정의 도구

VNDK 정의 도구는 공급업체가 소스 트리를 Android 8.0 환경으로 이전할 수 있게 도와줍니다. 이 도구는 시스템과 공급업체 이미지의 바이너리 파일을 스캔하고 종속 항목을 결정합니다. 도구는 모듈 종속 항목 그래프를 토대로 VNDK 개념에 관한 위반을 감지하고, 파티션 간의 모듈 이동을 위한 유용한 정보 및 권장사항도 확인할 수 있습니다. 일반 시스템 이미지(GSI)가 지정되면 VNDK 정의 도구는 시스템 이미지를 GSI와 비교하여 확장 라이브러리를 파악할 수 있습니다.

이 섹션에서는 VNDK 정의 도구와 관련하여 자주 사용되는 세 가지 명령어를 다룹니다.

  • vndk: Android 8.0 이상에서의 빌드 시스템 해결 방법과 관련하여 VNDK_SP_LIBRARIES, VNDK_SP_EXT_LIBRARIES, EXTRA_VENDOR_LIBRARIES를 계산합니다.
  • check-dep: 공급업체 모듈부터 사용할 수 없는 프레임워크 공유 라이브러리까지 위반하는 모듈 종속 항목이 있는지 확인합니다.
  • deps: 공유 라이브러리 및 실행 파일 간의 종속 항목을 출력합니다

고급 명령어 사용에 관한 자세한 내용은 VNDK 정의 도구 저장소의 README.md 파일을 참조하세요.

vndk

vndk 하위 명령어는 시스템 파티션과 공급업체 파티션에서 공유 라이브러리와 실행 파일을 로드한 다음 모듈 종속 항목을 결정하여 /system/lib[64]/vndk-sp-${VER}/vendor/lib[64]에 복사해야 하는 라이브러리를 판단합니다. vndk 하위 명령어의 옵션에는 다음이 포함됩니다.

옵션 설명
--system 시스템 파티션에서 상주하게 될 파일이 포함된 디렉터리를 가리킵니다.
--vendor 공급업체 파티션에서 상주하게 될 파일이 포함된 디렉터리를 가리킵니다.
--aosp-system 일반 시스템 이미지(GSI)에서 상주하게 될 파일이 포함된 디렉터리를 가리킵니다.
--load-extra-deps dlopen() 등의 암시적인 종속 항목을 설명하는 파일을 가리킵니다.

예를 들어 VNDK 라이브러리 집합을 계산하려면 다음 vndk 하위 명령어를 실행합니다.

./vndk_definition_tool.py vndk \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor \
    --aosp-system ${ANDROID_PRODUCT_OUT}/../generic_arm64_ab/system\
    --load-extra-deps dlopen.dep

단순 파일 형식의 추가 종속 항목을 지정합니다. 각 행은 관계를 나타내며, 여기서는 콜론 앞의 파일이 콜론 뒤의 파일에 종속됩니다. 예:

/system/lib/libart.so: /system/lib/libart-compiler.so

이 행으로 VNDK 정의 도구에서 libart.solibart-compiler.so에 종속된다는 것을 알 수 있습니다.

설치 위치

VNDK 정의 도구는 아래 카테고리의 라이브러리와 해당하는 설치 디렉터리를 나열합니다.

카테고리 디렉터리
vndk_sp /system/lib[64]/vndk-sp-${VER}에 설치해야 합니다.
vndk_sp_ext /vendor/lib[64]/vndk-sp에 설치해야 합니다.
extra_vendor_libs /vendor/lib[64]에 설치해야 합니다.

빌드 시스템 템플릿

VNDK 정의 도구에서 출력을 수집한 후 공급업체는 Android.mk를 생성하고 VNDK_SP_LIBRARIES, VNDK_SP_EXT_LIBRARIES, EXTRA_VENDOR_LIBRARIES를 채워 지정된 설치 위치에 라이브러리를 복사하는 프로세스를 자동화할 수 있습니다.

ifneq ($(filter $(YOUR_DEVICE_NAME),$(TARGET_DEVICE)),)
VNDK_SP_LIBRARIES := ##_VNDK_SP_##
VNDK_SP_EXT_LIBRARIES := ##_VNDK_SP_EXT_##
EXTRA_VENDOR_LIBRARIES := ##_EXTRA_VENDOR_LIBS_##

#-------------------------------------------------------------------------------
# VNDK Modules
#-------------------------------------------------------------------------------
LOCAL_PATH := $(call my-dir)

define define-vndk-lib
include $$(CLEAR_VARS)
LOCAL_MODULE := $1.$2
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_PREBUILT_MODULE_FILE := $$(TARGET_OUT_INTERMEDIATE_LIBRARIES)/$1.so
LOCAL_STRIP_MODULE := false
LOCAL_MULTILIB := first
LOCAL_MODULE_TAGS := optional
LOCAL_INSTALLED_MODULE_STEM := $1.so
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_RELATIVE_PATH := $3
LOCAL_VENDOR_MODULE := $4
include $$(BUILD_PREBUILT)

ifneq ($$(TARGET_2ND_ARCH),)
ifneq ($$(TARGET_TRANSLATE_2ND_ARCH),true)
include $$(CLEAR_VARS)
LOCAL_MODULE := $1.$2
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_PREBUILT_MODULE_FILE := $$($$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/$1.so
LOCAL_STRIP_MODULE := false
LOCAL_MULTILIB := 32
LOCAL_MODULE_TAGS := optional
LOCAL_INSTALLED_MODULE_STEM := $1.so
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_RELATIVE_PATH := $3
LOCAL_VENDOR_MODULE := $4
include $$(BUILD_PREBUILT)
endif  # TARGET_TRANSLATE_2ND_ARCH is not true
endif  # TARGET_2ND_ARCH is not empty
endef

$(foreach lib,$(VNDK_SP_LIBRARIES),\
    $(eval $(call define-vndk-lib,$(lib),vndk-sp-gen,vndk-sp,)))
$(foreach lib,$(VNDK_SP_EXT_LIBRARIES),\
    $(eval $(call define-vndk-lib,$(lib),vndk-sp-ext-gen,vndk-sp,true)))
$(foreach lib,$(EXTRA_VENDOR_LIBRARIES),\
    $(eval $(call define-vndk-lib,$(lib),vndk-ext-gen,,true)))

#-------------------------------------------------------------------------------
# Phony Package
#-------------------------------------------------------------------------------

include $(CLEAR_VARS)
LOCAL_MODULE := $(YOUR_DEVICE_NAME)-vndk
LOCAL_MODULE_TAGS := optional
LOCAL_REQUIRED_MODULES := \
    $(addsuffix .vndk-sp-gen,$(VNDK_SP_LIBRARIES)) \
    $(addsuffix .vndk-sp-ext-gen,$(VNDK_SP_EXT_LIBRARIES)) \
    $(addsuffix .vndk-ext-gen,$(EXTRA_VENDOR_LIBRARIES))
include $(BUILD_PHONY_PACKAGE)

endif  # ifneq ($(filter $(YOUR_DEVICE_NAME),$(TARGET_DEVICE)),)

check-dep

check-dep 하위 명령어는 공급업체 모듈을 스캔하여 종속 항목을 확인하며, 위반이 감지되면 위반한 종속 라이브러리와 기호 사용을 출력합니다.

./vndk_definition_tool.py check-dep \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor \
    --tag-file eligible-list.csv \
    --module-info ${ANDROID_PRODUCT_OUT}/module-info.json \
    1> check_dep.txt \
    2> check_dep_err.txt

예를 들어 다음 샘플 출력에서는 libRS_internal.so에서 libmediandk.so까지, 위반한 종속 항목을 보여줍니다.

/system/lib/libRS_internal.so
        MODULE_PATH: frameworks/rs
        /system/lib/libmediandk.so
                AImageReader_acquireNextImage
                AImageReader_delete
                AImageReader_getWindow
                AImageReader_new
                AImageReader_setImageListener

check-dep 하위 명령어의 옵션에는 다음이 포함됩니다.

옵션 설명
--tag-file 아래에 설명된 사용 가능한 라이브러리 태그 파일을 참조해야 합니다. 이 파일은 Google에서 제공하는 스프레드시트로, 프레임워크 공유 라이브러리의 카테고리를 설명합니다.
--module-info Android 빌드 시스템에서 생성한 module-info.json을 가리킵니다. VNDK 정의 도구가 바이너리 모듈을 소스 코드와 연결할 수 있게 도와줍니다.

사용 가능한 라이브러리 태그 파일

Google에서는 공급업체 모듈에서 사용할 수 있는 프레임워크 공유 라이브러리를 태그하는 사용 가능한 VNDK 스프레드시트(예: eligible-list.csv)를 제공합니다.

태그 설명
LL-NDK 안정적인 ABI/API를 포함하는 공유 라이브러리입니다. 프레임워크 및 공급업체 모듈이 사용할 수 있습니다.
LL-NDK-Private LL-NDK 라이브러리의 비공개 종속 항목입니다. 공급업체 모듈이 이 라이브러리에 직접 액세스하면 안 됩니다.
VNDK-SP SP-HAL 프레임워크 공유 라이브러리 종속 항목입니다.
VNDK-SP-Private 일부 공급업체 모듈에 직접 액세스할 수 없는 VNDK-SP 종속 항목입니다.
VNDK SP-HAL 및 SP-HAL-Dep를 제외한 공급업체 모듈에 제공 가능한 프레임워크 공유 라이브러리입니다.
VNDK-Private 일부 공급업체 모듈에 직접 액세스할 수 없는 VNDK 종속 항목입니다.
FWK-ONLY 공급업체 모듈이 직간접적으로 액세스하면 안 되는 프레임워크 전용 공유 라이브러리입니다.
FWK-ONLY-RS 공급업체 모듈이 액세스하면 안 되는(RS 사용 제외) 프레임워크 전용 공유 라이브러리입니다.

다음 표는 공급업체 공유 라이브러리에 사용되는 태그에 대해 설명합니다.

태그 설명
SP-HAL Same-Process HAL 구현 공유 라이브러리
SP-HAL-Dep SP-HAL 공급업체 공유 라이브러리 종속 항목(LL-NDK 및 VNDK-SP를 제외한 SP-HAL 종속 항목)
VND-ONLY 프레임워크에 표시되지 않는 공유 라이브러리로, 프레임워크 모듈이 액세스해서는 안 됩니다. 복사된 확장 VNDK 라이브러리도 VND-ONLY로 태그됩니다.

태그 간 관계:

태그 간 관계
그림 1. 태그 간 관계

deps

라이브러리 종속 항목을 디버그하기 위해 deps 하위 명령어가 모듈 종속 항목을 출력합니다.

./vndk_definition_tool.py deps \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor

출력은 여러 줄로 구성됩니다. 탭 문자가 없는 행은 새 섹션을 시작합니다. 탭 문자가 있는 행은 이전 섹션에 종속됩니다. 예:

/system/lib/ld-android.so
/system/lib/libc.so
        /system/lib/libdl.so

이 출력에서는 ld-android.so에 종속 항목이 없고 libc.solibdl.so에 종속된다는 것을 보여줍니다.

--revert 옵션을 지정하면 deps 하위 명령어가 라이브러리 사용(역 종속 항목)을 출력합니다.

./vndk_definition_tool.py deps \
    --revert \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor

예:

/system/lib/ld-android.so
        /system/lib/libdl.so
        

이 출력에서는 ld-android.solibdl.so에서 사용된다는 것을 보여줍니다. 즉, libdl.sold-android.so에 종속됩니다. 또한 이 출력은 libdl.sold-android.so의 단독 사용자임을 보여줍니다.

--symbol 옵션을 지정하면 deps 하위 명령어가 사용되고 있는 기호를 출력합니다.

./vndk_definition_tool.py deps \
    --symbol \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor
    

예:

/system/lib/libc.so
        /system/lib/libdl.so
                android_get_application_target_sdk_version
                dl_unwind_find_exidx
                dlclose
                dlerror
                dlopen
                dlsym

이 출력에서는 libc.solibdl.so에서 내보낸 6개의 함수에 종속된다는 것을 보여줍니다. --symbol 옵션과 --revert 옵션을 모두 지정하면 사용자가 사용하는 기호가 출력됩니다.