32비트 및 64비트 아키텍처용으로 빌드

빌드 시스템은 동일한 빌드에서 두 개의 타겟 CPU 아키텍처(32비트 및 64비트)를 위한 바이너리 빌드를 지원합니다. 이처럼 타겟이 2개인 빌드를 multilib 빌드라고 합니다.

내장 정적 라이브러리와 공유 라이브러리의 경우 빌드 시스템에서 두 아키텍처를 위한 바이너리를 빌드합니다. 제품 구성(PRODUCT_PACKAGES)은 종속성 그래프와 함께 어떤 바이너리를 시스템 이미지에 빌드하고 설치할지 결정합니다.

실행 파일 및 앱의 경우 빌드 시스템은 기본적으로 64비트 버전만 빌드하지만, 전역 BoardConfig.mk 변수 또는 모듈 범위 변수로 이 설정을 재정의할 수 있습니다.

두 번째 CPU 아키텍처 및 ABI 식별

BoardConfig.mk에는 두 번째 CPU 아키텍처 및 ABI(Application Binary Interface)를 구성하기 위한 다음 변수가 포함되어 있습니다.

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

이러한 변수를 사용하는 makefile 샘플을 보려면 build/make/target/board/generic_arm64/BoardConfig.mk를 참고하세요.

빌드 시스템에 의해 정의된 이상 multilib 빌드에서는 PRODUCT_PACKAGES의 모듈 이름이 32비트 및 64비트 바이너리 둘 다에 적용됩니다. 종속 항목에 의해 포함되는 라이브러리의 경우, 다른 32비트 또는 64비트 라이브러리나 실행 파일에 필요한 경우에만 32비트 또는 64비트 라이브러리가 설치됩니다.

하지만 make 명령줄의 모듈 이름은 64비트 버전에만 적용됩니다. 예를 들어 lunch aosp_arm64-eng를 실행한 후 make libc는 64비트 libc만 빌드합니다. 32비트 libc를 빌드하려면 make libc_32를 실행해야 합니다.

Android.mk에서 모듈 아키텍처 정의

LOCAL_MULTILIB 변수를 사용하여 32비트 및 64비트를 위해 빌드를 구성하고 전역 TARGET_PREFER_32_BIT 변수를 재정의할 수 있습니다.

TARGET_PREFER_32_BIT를 재정의하려면 LOCAL_MULTILIB를 다음 중 하나로 설정합니다.

  • both는 32비트와 64비트를 모두 빌드합니다.
  • 32는 32비트만 빌드합니다.
  • 64는 64비트만 빌드합니다.
  • first는 첫 번째 아키텍처(32비트 기기의 32비트 및 64비트 기기의 64비트)에 대해서만 빌드됩니다.

기본적으로 LOCAL_MULTILIB는 설정되어 있지 않으며, 빌드 시스템은 모듈 클래스 및 다른 LOCAL_* 변수(예: LOCAL_MODULE_TARGET_ARCH, LOCAL_32_BIT_ONLY 등)를 기반으로 어느 아키텍처를 빌드할지 결정합니다.

특정 아키텍처용 모듈을 빌드하려면 다음 변수를 사용합니다.

  • LOCAL_MODULE_TARGET_ARCH - 이 변수를 arm x86 arm64와 같은 아키텍처 목록으로 설정합니다. 빌드 중인 아키텍처가 목록에 있으면 현재 모듈이 빌드 시스템에 포함됩니다.

  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH - 이 변수는 LOCAL_MODULE_TARGET_ARCH의 반대입니다. 빌드 중인 아키텍처가 목록에 있지 않으면(not) 현재 모듈이 빌드 시스템에 포함됩니다.

이러한 두 변수의 보조 변형이 있습니다.

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

나열된 아키텍처로 인해 현재 모듈을 건너뛰면 빌드 시스템이 경고를 표시합니다.

특정 아키텍처에 관해 빌드 플래그를 설정하려면 아키텍처별 LOCAL_* 변수를 사용하세요. 여기서 *은 아키텍처별 접미사입니다. 예를 들면 다음과 같습니다.

  • LOCAL_SRC_FILES_arm, LOCAL_SRC_FILES_x86,
  • LOCAL_CFLAGS_arm, LOCAL_CFLAGS_arm64,
  • LOCAL_LDFLAGS_arm, LOCAL_LDFLAGS_arm64,

이러한 변수는 해당 아키텍처를 위해 바이너리를 빌드 중인 경우에만 적용됩니다.

빌드 중인 바이너리가 32비트용인지 64비트용인지에 따라 플래그를 설정하는 것이 더 쉬운 경우도 있습니다. LOCAL_* 변수를 _32 또는 _64 접미사와 함께 사용하세요. 예를 들면 다음과 같습니다.

  • LOCAL_SRC_FILES_32, LOCAL_SRC_FILES_64,
  • LOCAL_CFLAGS_32, LOCAL_CFLAGS_64,
  • LOCAL_LDFLAGS_32, LOCAL_LDFLAGS_64,

라이브러리 설치 경로 설정

multilib 외 빌드의 경우 LOCAL_MODULE_PATH를 사용하여 기본 위치가 아닌 다른 위치에 라이브러리를 설치할 수 있습니다. 예: LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw

multilib 빌드에서는 대신 LOCAL_MODULE_RELATIVE_PATH를 사용합니다.

LOCAL_MODULE_RELATIVE_PATH := hw

이 형식에서는 64비트 및 32비트 라이브러리가 모두 올바른 위치에 설치됩니다.

실행 파일을 32비트와 64비트 둘 다로 빌드하는 경우 다음 변수 중 하나를 사용하여 설치 경로를 구별합니다.

  • LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64 - 설치된 파일 이름을 지정합니다.
  • LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64 - 설치 경로를 지정합니다.

소스 파일의 중간 디렉터리 확인

multilib 빌드에서 $(local-intermediates-dir)(또는 명시적 변수를 사용하여 $(intermediates-dir-for))에 소스 파일을 생성하면 안정적으로 작동하지 않습니다. 중간에 생성된 소스가 32비트 및 64비트 빌드 모두에 필요하지만 $(local-intermediates-dir)은 두 중간 디렉터리 중 하나만 가리키기 때문입니다.

빌드 시스템은 소스를 생성하기 위한 multilib 친화적인 전용 중간 디렉터리를 제공합니다. 중간 디렉터리를 가져오려면 $(local-generated-sources-dir) 또는 $(generated-sources-dir-for) 매크로를 사용하세요. 매크로 사용 방식은 $(local-intermediates-dir)$(intermediates-dir-for)와 유사합니다.

소스 파일이 이 전용 디렉터리에 생성되고 LOCAL_GENERATED_SOURCES에 의해 선택되면 multilib 빌드에서 32비트와 64비트 모두에 대해 빌드됩니다.

사전 빌드된 바이너리 타겟의 시스템 아키텍처 나타내기

multilib 빌드에서는 사전 빌드된 바이너리가 타겟팅하는 시스템 아키텍처가 무엇인지를 나타내기 위해 TARGET_ARCH 또는 TARGET_ARCHTARGET_2ND_ARCH를 사용할 수 없습니다. 대신 LOCAL_* 변수인 LOCAL_MODULE_TARGET_ARCH 또는 LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH를 사용하세요.

이러한 변수가 있으면 64비트 multilib 빌드를 진행 중인 경우에도 빌드 시스템에서 해당하는 32비트 사전 빌드된 바이너리를 선택할 수 있습니다.

선택한 아키텍처를 사용하여 사전 빌드된 바이너리의 소스 경로를 계산하려면 $(get-prebuilt-src-arch)를 호출하세요.

32비트 및 64비트 ODEX 파일 생성 보장

64비트 기기의 경우 Google은 기본적으로 부팅 이미지 및 모든 자바 라이브러리를 위한 32비트 및 64비트 ODEX 파일을 생성합니다. APK의 경우 Google은 기본적으로 주 64비트 아키텍처용 ODEX만 생성합니다. 앱이 32비트 및 64비트 프로세스 모두에서 실행되는 경우 LOCAL_MULTILIB := both를 사용하여 32비트 및 64비트 ODEX 파일이 모두 생성되었는지 확인합니다. 앱에 32비트 또는 64비트 JNI 라이브러리가 있는 경우 플래그는 빌드 시스템에 이러한 라이브러리를 포함하도록 지시합니다.