새 기기 추가

이 페이지의 정보를 활용하여 기기와 제품의 makefile을 생성할 수 있습니다.

새로운 각 Android 모듈에는 모듈 메타데이터, 컴파일 시간 종속 항목 및 패키징 지침으로 빌드 시스템을 안내할 구성 파일이 있어야 합니다. Android는 Soong 빌드 시스템을 사용합니다. Android 빌드 시스템에 관한 자세한 내용은 Android 빌드를 참조하세요.

빌드 레이어 이해하기

빌드 계층 구조에는 기기의 물리적 구성에 해당하는 추상 레이어가 포함됩니다. 이러한 레이어는 아래 표에 설명되어 있습니다. 각 레이어는 일대다 관계에서 바로 위 레이어와 연관성을 지닙니다. 예를 들어 아키텍처에는 두 개 이상의 보드가 포함될 수 있으며 각 보드에는 두 개 이상의 제품이 포함될 수 있습니다. 주어진 레이어의 요소를 같은 레이어에 있는 요소의 한정으로 정의하여 사본을 없애고 유지관리를 단순화할 수 있습니다.

레이어 설명
제품 myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk 제품 레이어는 빌드할 모듈, 지원되는 언어 및 다양한 언어의 구성과 같은 배송 제품의 기능 사양을 정의합니다. 즉, 전체 제품의 이름입니다. 제품별 변수는 제품 정의 makefile에 정의되어 있습니다. 제품은 다른 제품 정의에서 상속될 수 있으며, 이 경우 유지관리가 단순화됩니다. 일반적으로 모든 제품에 적용된 기능이 포함된 기본 제품을 생성한 다음 이러한 기본 제품을 기반으로 제품 변형을 생성합니다. 예를 들면 라디오(CDMA와 GSM)에 따라서만 구분되는 두 제품은 라디오를 정의하지 않는 동일한 기본 제품에서 상속될 수 있습니다.
보드/기기 marlin, blueline, coral 보드/기기 레이어는 기기의 물리적 플라스틱 레이어(기기의 산업 디자인)를 나타냅니다. 또한 이 레이어는 제품의 기본 도식을 나타냅니다. 여기에는 보드의 주변기기와 구성이 포함됩니다. 사용된 이름은 여러 보드/기기 설정의 코드에 불과합니다.
Arch arm, x86, arm64, x86_64 아키텍처 레이어는 보드에서 실행되는 프로세서 구성과 ABI(Application Binary Interface)를 설명합니다.

빌드 변형 사용하기

특정 제품을 빌드하는 경우 최종 출시 빌드에서 마이너 버전의 변형을 보유하면 유용합니다. 모듈 정의에서 모듈은 한 개 이상의 optional(기본값), debugeng 값일 수 있는 LOCAL_MODULE_TAGS를 포함하는 태그를 지정합니다.

모듈에서 LOCAL_MODULE_TAGS로 태그를 지정하지 않은 경우 태그가 optional로 기본 설정됩니다. 선택적 모듈은 PRODUCT_PACKAGES를 포함하는 제품 구성이 필요할 때만 설치됩니다.

다음은 현재 정의된 빌드 변형입니다.

변형 설명
eng 기본 버전입니다.
  • eng 또는 debug로 태그가 지정된 모듈을 설치합니다.
  • 태그가 지정된 모듈 외에도, 제품 정의 파일에 따라 모듈을 설치합니다.
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb는 기본적으로 사용 설정되어 있습니다.
user 최종 출시 비트용 변형입니다.
  • user로 태그가 지정된 모듈을 설치합니다.
  • 태그가 지정된 모듈 외에도, 제품 정의 파일에 따라 모듈을 설치합니다.
  • ro.secure=1
  • ro.debuggable=0
  • adb는 기본적으로 사용 중지되어 있습니다.
userdebug 다음과 같은 경우를 제외하고 user와 동일합니다.
  • 또한 debug로 태그가 지정된 모듈을 설치합니다.
  • ro.debuggable=1
  • adb는 기본적으로 사용 설정되어 있습니다.

userdebug 가이드라인

테스트 도중 userdebug 빌드를 실행하면 기기 개발자가 개발 중인 버전의 성능과 기능을 이해하는 데 도움이 됩니다. 사용자 빌드와 userdebug 빌드 간의 일관성을 유지하고 디버깅에 사용되는 빌드의 측정항목이 안정적으로 기록되도록 기기 개발자는 다음 가이드라인을 따라야 합니다.

  • userdebug는 루트 액세스가 사용 설정된 사용자 빌드로 정의되며, 다음은 예외입니다.
    • 사용자의 요구에 의해서만 실행되는 userdebug 전용 앱
    • 백그라운드 컴파일에 dex2oatd 또는 dex2oat를 사용하는 등의 유휴 유지관리(충전/완충 시) 도중에 실행되는 작업
  • 빌드 유형에 따라 기본적으로 사용 설정/사용 중지되는 기능을 포함하면 안 됩니다. 디버그 로깅 또는 힙 덤프처럼 배터리 수명에 영향을 미치는 어떠한 형태의 로깅도 사용하지 않는 것이 좋습니다.
  • userdebug에서 기본으로 사용 설정되는 모든 디버깅 기능은 명확하게 정의된 후 프로젝트에 참여 중인 모든 개발자에게 공유되어야 합니다. 디버깅하려는 문제가 해결될 때까지 한시적으로만 디버깅 기능을 사용 설정해야 합니다.

리소스 오버레이로 빌드 맞춤설정하기

Android 빌드 시스템에서는 리소스 오버레이를 사용하여 빌드 시에 제품을 맞춤설정합니다. 리소스 오버레이는 기본값 외에 적용되는 리소스 파일을 지정합니다. 리소스 오버레이를 사용하려면 프로젝트 buildfile을 수정하여 PRODUCT_PACKAGE_OVERLAYS를 최상위 수준 디렉터리에 대한 상대적인 경로로 설정합니다. 이 경로는 빌드 시스템에서 리소스를 검색할 때 현재 루트와 함께 검색되는 섀도 루트가 됩니다.

가장 일반적인 맞춤설정은 frameworks/base/core/res/res/values/config.xml 파일에 포함됩니다.

이 파일에 리소스 오버레이를 설정하려면 다음 중 하나를 사용하여 프로젝트 buildfile에 오버레이 디렉터리를 추가합니다.

PRODUCT_PACKAGE_OVERLAYS := device/device-implementer/device-name/overlay

또는

PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay

그런 다음 디렉터리에 오버레이 파일을 추가합니다. 예를 들면 다음과 같습니다.

vendor/foobar/overlay/frameworks/base/core/res/res/values/config.xml

오버레이 config.xml 파일에서 발견된 모든 문자열이나 문자열 배열은 원본 파일에서 발견된 내용을 대체합니다.

제품 빌드하기

다양한 방법으로 기기의 소스 파일을 구성할 수 있습니다. 아래에서는 Pixel 구현을 구성하는 한 가지 방법을 간략히 설명합니다.

Pixel은 marlin이라는 기본 기기 설정으로 구현되었습니다. 이 기기 설정에서는 이름 및 모델과 같은 기기에 관한 제품별 정보를 선언하는 제품 정의 makefile로 제품이 생성됩니다. device/google/marlin 디렉터리를 보고 이러한 모든 내용이 설정되는 방식을 확인할 수 있습니다.

제품 makefile 작성하기

다음 단계에서는 Pixel 제품 계열과 유사한 방식으로 제품 makefile을 설정하는 방법을 설명합니다.

  1. 제품의 device/<company-name>/<device-name> 디렉터리를 생성합니다. 예를 들어 device/google/marlin입니다. 이 디렉터리에는 기기의 소스 코드와 이를 빌드하기 위한 makefile이 포함됩니다.
  2. 기기에 필요한 파일과 모듈을 선언하는 device.mk makefile을 생성합니다. 예시는 device/google/marlin/device-marlin.mk를 참조하세요.
  3. 제품 정의 makefile을 생성하여 기기에 따른 구체적인 제품을 생성합니다. 다음 makefile은 예시를 위해 device/google/marlin/aosp_marlin.mk에서 가져온 것입니다. 제품은 makefile을 통해 device/google/marlin/device-marlin.mkvendor/google/marlin/device-vendor-marlin.mk 파일에서 상속되는 동시에 이름, 브랜드 및 모델과 같은 제품 관련 정보를 선언합니다.
    # Inherit from the common Open Source product configuration
    $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
    $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
    
    PRODUCT_NAME := aosp_marlin
    PRODUCT_DEVICE := marlin
    PRODUCT_BRAND := Android
    PRODUCT_MODEL := AOSP on msm8996
    PRODUCT_MANUFACTURER := Google
    PRODUCT_RESTRICT_VENDOR_FILES := true
    
    PRODUCT_COPY_FILES += device/google/marlin/fstab.common:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.marlin
    
    $(call inherit-product, device/google/marlin/device-marlin.mk)
    $(call inherit-product-if-exists, vendor/google_devices/marlin/device-vendor-marlin.mk)
    
    PRODUCT_PACKAGES += \
        Launcher3QuickStep \
        WallpaperPicker
    

    makefile에 추가 가능한 추가적인 제품 관련 변수는 제품 정의 변수 설정을 참고하세요.

  4. 제품의 makefile을 가리키는 AndroidProducts.mk 파일을 생성합니다. 이 예시에서는 제품 정의 makefile만 필요합니다. 다음 예는 device/google/marlin/AndroidProducts.mk에서 가져온 것으로, 대부분의 구성을 공유하는 Marlin, Pixel, Sailfish, Pixel XL을 모두 포함합니다.
    PRODUCT_MAKEFILES := \
    	$(LOCAL_DIR)/aosp_marlin.mk \
    	$(LOCAL_DIR)/aosp_sailfish.mk
    
    COMMON_LUNCH_CHOICES := \
    	aosp_marlin-userdebug \
    	aosp_sailfish-userdebug
    
  5. 보드 전용 구성을 포함하는 BoardConfig.mk makefile을 생성합니다. 예: device/google/marlin/BoardConfig.mk를 참고하세요.
  6. Android 9 이하에서 vendorsetup.sh 파일을 생성하여 대시로 구분된 빌드 변형과 함께 제품('런치 콤보')을 빌드에 추가합니다. 예:
    add_lunch_combo <product-name>-userdebug
    
  7. 이제 동일한 기기를 기준으로 추가적인 제품 변형을 생성할 수 있습니다.

제품 정의 변수 설정

제품별 변수는 제품의 makefile에 정의되어 있습니다. 표에는 제품 정의 파일에서 유지관리되는 일부 변수가 나와 있습니다.

변수 설명
PRODUCT_AAPT_CONFIG 패키지 생성 시 사용할 aapt 구성.
PRODUCT_BRAND 필요한 경우 소프트웨어의 맞춤설정 기준이 된 브랜드(예: 이동통신사)
PRODUCT_CHARACTERISTICS 변형별 리소스를 패키지에 추가하는 데 필요한 aapt 특성 tablet, nosdcard
PRODUCT_COPY_FILES 단어 목록(예: source_path:destination_path). 소스 경로의 파일은 이 제품 빌드 시 대상 경로에 복사되어야 합니다. 복사 단계에 관한 규칙은 config/makefile에 정의되어 있습니다.
PRODUCT_DEVICE 산업 디자인의 이름입니다. 이는 보드 이름이기도 하며 빌드 시스템에서 이 이름을 사용하여 BoardConfig.mk를 찾습니다. tuna
PRODUCT_LOCALES UI 언어 및 시간, 날짜, 통화 형식과 같이 사용자와 관련된 여러 설정을 설명하는 2자리 언어 코드와 2자리 국가 코드 쌍의 공백으로 구분된 목록. PRODUCT_LOCALES에 나열된 첫 번째 언어는 제품의 기본 언어로 사용됩니다. en_GB, de_DE, es_ES, fr_CA
PRODUCT_MANUFACTURER 제조업체 이름. acme
PRODUCT_MODEL 최종 사용자에게 표시되는 최종 제품의 이름.
PRODUCT_NAME 최종 사용자에게 표시되는 전체 제품의 이름. 설정 > 정보 화면에 표시됩니다.
PRODUCT_OTA_PUBLIC_KEYS 제품의 무선 업데이트(OTA) 공개 키 목록.
PRODUCT_PACKAGES 설치할 APK 및 모듈 목록 캘린더 연락처
PRODUCT_PACKAGE_OVERLAYS 기본 리소스를 사용할지 또는 제품별 오버레이를 추가할지를 나타냅니다. vendor/acme/overlay
PRODUCT_SYSTEM_PROPERTIES 시스템 파티션을 위한 "key=value" 형식의 시스템 속성 할당 목록입니다. 다른 파티션의 시스템 속성은 공급업체 파티션의 PRODUCT_VENDOR_PROPERTIES에서와 같이 PRODUCT_<PARTITION>_PROPERTIES를 통해 설정할 수 있습니다. 지원되는 파티션 이름은 SYSTEM, VENDOR, ODM, SYSTEM_EXT, PRODUCT입니다.

기본 시스템 언어 및 언어 필터 구성하기

이 정보를 사용하여 기본 언어 및 시스템 언어 필터를 구성한 다음 새 기기 유형의 언어 필터를 사용 설정합니다.

속성

다음과 같이 전용 시스템 속성을 사용하여 기본 언어와 시스템 언어 필터를 구성합니다.

  • ro.product.locale: 기본 언어를 설정합니다. 초기에는 PRODUCT_LOCALES 변수의 첫 번째 언어로 설정되어 있습니다. 이 값은 재정의할 수 있습니다. (자세한 내용은 제품 정의 변수 설정 표를 참고하세요.)
  • ro.localization.locale_filter: 언어 이름에 적용된 정규 표현식을 사용하여 언어 필터를 설정합니다. 예
    • 포함 필터: ^(de-AT|de-DE|en|uk).* - 독일어(오스트리아 및 독일 변형), 영어의 모든 영어 변형, 우크라이나어만 허용합니다.
    • 제외 필터: ^(?!de-IT|es).* - 독일어(이탈리아 변형)와 모든 스페인어 변형을 제외합니다.

언어 필터 사용 설정하기

필터를 사용 설정하려면 ro.localization.locale_filter 시스템 속성 문자열 값을 설정합니다.

공장 보정 중에 oem/oem.prop를 통해 필터 속성 값과 기본 언어를 설정하면 필터를 시스템 이미지에 적용하지 않고 제한을 구성할 수 있습니다. 이들 속성이 OEM 파티션에서 선택되도록 하려면 아래와 같이 PRODUCT_OEM_PROPERTIES 변수에 속성을 추가합니다.

# Delegation for OEM customization
PRODUCT_OEM_PROPERTIES += \
    ro.product.locale \
    ro.localization.locale_filter

그러면 프로덕션에서는 실제 값이 oem/oem.prop에 쓰여져서 타겟 요구사항을 반영합니다. 이 방법을 사용하면 초기화 중에 기본값이 유지되므로 초기 설정이 사용자에게 정확히 첫 번째 설정처럼 표시됩니다.

USB를 통해 연결하도록 ADB_VENDOR_KEYS 설정하기

ADB_VENDOR_KEYS 환경 변수를 사용하면 기기 제조업체에서 수동 승인 없이 adb를 통해 디버그 가능한 빌드(-userdebug 및 -eng는 해당하나 -user는 아님)에 액세스할 수 있습니다. 일반적으로 adb는 클라이언트 컴퓨터마다 고유한 RSA 인증 키를 생성하며, 이 키는 연결된 모든 기기로 전송됩니다. 이는 adb 승인 대화상자에 표시되는 RSA 키입니다. 또는 알려진 키를 시스템 이미지에 빌드하여 adb 클라이언트와 공유할 수도 있습니다. 이는 adb 승인 대화상자와 수동으로 상호작용할 필요가 없으므로 OS 개발, 특히 테스트에 유용합니다.

공급업체 키를 만들려면 한 사람(일반적으로 출시 관리자)이 다음을 실행해야 합니다.

  1. adb keygen을 사용하여 키 쌍을 생성합니다. Google 기기의 경우 Google에서 새 OS 버전마다 새 키 쌍을 생성합니다.
  2. 소스 트리의 특정 위치에서 키 쌍을 확인합니다. 예를 들어, Google은 키 쌍을 vendor/google/security/adb/에 저장합니다.
  3. 빌드 변수 PRODUCT_ADB_KEYS가 키 디렉터리를 가리키도록 설정합니다. Google에서는 PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub라는 키 디렉터리에 Android.mk 파일을 추가하여 각 OS 버전에 새 키 쌍을 생성하도록 합니다.

다음은 Google에서 사용하는 makefile로, 각 출시 버전의 체크인 키 쌍이 저장된 디렉터리에 있습니다.

PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub

ifeq ($(wildcard $(PRODUCT_ADB_KEYS)),)
  $(warning ========================)
  $(warning The adb key for this release)
  $(warning )
  $(warning   $(PRODUCT_ADB_KEYS))
  $(warning )
  $(warning does not exist. Most likely PLATFORM_VERSION in build/core/version_defaults.mk)
  $(warning has changed and a new adb key needs to be generated.)
  $(warning )
  $(warning Please run the following commands to create a new key:)
  $(warning )
  $(warning   make -j8 adb)
  $(warning   LOGNAME=android-eng HOSTNAME=google.com adb keygen $(patsubst %.pub,%,$(PRODUCT_ADB_KEYS)))
  $(warning )
  $(warning and upload/review/submit the changes)
  $(warning ========================)
  $(error done)
endif

이러한 공급업체 키를 사용하려면 엔지니어는 ADB_VENDOR_KEYS 환경 변수가 키 쌍이 저장된 디렉터리를 가리키도록 설정하기만 하면 됩니다. 이렇게 하면 수동 승인이 필요한 생성된 호스트 키로 돌아가기 전에 이러한 표준 키를 먼저 시도하도록 adb에 알려 줍니다. adb에서 승인되지 않은 기기에 연결할 수 없는 경우 ADB_VENDOR_KEYS가 아직 설정되지 않았다면 이를 설정하라는 오류 메시지가 표시됩니다.