Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

OTA 용량 축소

이 페이지에서는 빌드 간의 불필요한 파일 변경을 줄이기 위해 AOSP에 추가된 빌드 변경사항에 대해 설명합니다. 자체 빌드 시스템을 유지관리하는 기기 구현자는 이 정보를 OTA(over-the-air) 업데이트 용량 축소를 위한 가이드로 활용할 수 있습니다.

간혹 OTA에는 코드 변경보다는 오히려 빌드 시스템의 아티팩트와 일치하는 변경된 파일이 포함될 수 있습니다. 이는 다른 시점에 다른 디렉터리나 다른 시스템에서 빌드된 동일한 코드가 다수의 변경된 파일을 생성하는 경우에 발생할 수 있습니다. 이렇게 과도한 수의 파일은 OTA 용량을 높일 뿐만 아니라 OTA에서 어떤 코드가 변경되었는지를 파악하기가 어렵게 만들 수도 있습니다.

OTA 콘텐츠의 투명성을 높이기 위해 AOSP에는 빌드 간의 불필요한 파일 변경을 제거하여 OTA 용량을 줄이도록 설계된 빌드 시스템 변경사항이 포함됩니다. 목적은 OTA에 포함된 패치와 관련된 파일만 포함하도록 OTA 용량을 줄이는 데 있습니다. AOSP에는 일반적인 빌드 관련 파일 변경사항을 필터링하여 정리된 빌드 파일 diff를 제공하는 빌드 diff 도구, 그리고 블록 할당의 일관성을 유지할 수 있게 도와주는 블록 매핑 도구가 포함됩니다.

빌드 시스템은 여러 방식으로 불필요한 파일 diff를 생성할 수 있습니다. 다음 섹션에서는 이러한 문제와 해결 방법의 일부를 논의하며, 가능한 경우 AOSP의 수정 예시를 제공합니다.

파일 순서

문제: 파일 시스템은 디렉토리의 파일 목록을 요청받았을 때 파일 순서를 보장하지 않지만 동일한 결제의 경우에는 똑같을 때가 많습니다. ls 등의 도구는 기본으로 결과를 정렬하지만 findmake와 같은 명령어가 사용하는 와일드카드 함수는 그렇지 않습니다. 이러한 도구를 사용하려면 먼저 출력부터 정렬해야 합니다.

해결 방법: 와일드카드가 포함된 findmake 등의 도구를 사용하는 경우 이러한 명령어를 사용하기 전에 명령어의 출력부터 정렬해야 합니다. Android.mk 파일의 $(wildcard) 또는 $(shell find)를 사용하는 경우에도 정렬이 필요합니다. 자바를 비롯한 일부 도구는 입력을 정렬하므로 정렬부터 먼저 확인해야 합니다.

예: 다수의 인스턴스는 기본으로 제공되는 all-*-files-under 매크로를 사용하여 핵심 빌드 시스템에 고정되었습니다. 매크로에는 all-cpp-files-under가 포함되며, 이는 여러 정의가 다른 makefile에 분산되었기 때문입니다. 자세한 내용은 다음 CL을 참조하세요.

빌드 디렉터리

문제: 항목이 빌드된 디렉터리를 변경할 경우 바이너리가 달라질 수 있습니다. Android 빌드의 경로는 대부분 상대 경로이므로 C/C++의 __FILE__이 문제가 되지 않습니다. 하지만 디버그 기호는 전체 경로 이름을 기본으로 인코딩하며, 미리 삭제된 바이너리를 해싱하면 .note.gnu.build-id가 생성됩니다. 따라서 디버그 기호가 변경되면 이 또한 변경됩니다.

해결 방법: 이제 AOSP에서 디버그 경로를 상대 경로로 지정합니다. 자세한 내용은 CL(https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02)을 참조하세요.

타임스탬프

문제: 빌드 출력의 타임스탬프가 불필요한 파일 변경을 야기합니다. 이 문제는 다음과 같은 위치에서 발생할 가능성이 높습니다.

  • C 또는 C++ 코드의 __DATE__/__TIME__/__TIMESTAMP__ 매크로
  • zip 기반 아카이브에 삽입된 타임스탬프

해결 방법/예시: 빌드 출력에서 타임스탬프를 제거하려면 아래 섹션의 안내를 활용하세요.

C/C++의 __DATE__/__TIME__/__TIMESTAMP__

이러한 매크로는 항상 다른 빌드의 다른 출력을 생성하기 때문에 사용하면 안 됩니다. 다음은 이러한 매크로를 제거할 수 있는 몇 가지 방법입니다.

아카이브(zip, jar)에 삽입된 타임스탬프

Android 7.0에서는 모든 zip 명령어 사용에 -X를 추가하여 zip 아카이브에 삽입된 타임스탬프 관련 문제를 수정했습니다. 따라서 빌더의 UID/GID 및 확장된 Unix 타임스탬프가 zip 파일에 삽입되지 않습니다.

새로운 도구인 ziptime(/platform/build/+/master/tools/ziptime/에 위치)은 zip 헤더의 정상적인 타임스탬프를 재설정합니다. 자세한 내용은 README 파일을 참조하세요.

signapk 도구는 서버 시간대에 따라 다를 수 있는 APK 파일의 타임스탬프를 설정합니다. 자세한 내용은 CL(https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028)을 참조하세요.

버전 문자열

문제: APK 버전 문자열은 하드코딩된 버전에 BUILD_NUMBER가 붙을 때가 많았습니다. APK의 다른 부분이 변경되지 않은 경우에도 APK가 계속해서 다릅니다.

해결 방법: APK 버전 문자열에서 빌드 번호를 제거합니다.

예:

일관적인 빌드 도구

문제: 설치된 파일을 생성하는 도구가 일관적이어야 합니다(같은 입력이 항상 같은 출력을 생성해야 함).

해결 방법/예시: 다음과 같은 빌드 도구에 변경사항이 필요했습니다.

빌드 diff 도구

빌드 관련 파일 변경사항을 제거할 수 없는 경우를 위해 AOSP에는 빌드 diff 도구인 target_files_diff.py가 포함됩니다. 이 도구는 두 개의 파일 패키지를 비교할 때 사용됩니다. 이 도구는 두 빌드 간의 반복적 diff를 수행하여 다음과 같은 일반적인 빌드 관련 파일 변경사항을 제외합니다.

  • 빌드 출력에서 예상되는 변경사항(예: 빌드 번호 변경)
  • 현재 빌드 시스템의 알려진 문제로 인한 변경사항

빌드 diff 도구를 사용하려면 다음 명령어를 실행합니다.

    target_files_diff.py dir1 dir2
    

dir1dir2는 각 빌드에 대해 추출된 타겟 파일이 포함되는 기본 디렉터리입니다.

블록 할당의 일관성 유지

비 A/B OTA에서 시간에 기여하는 요인 중 하나는 블록 이동입니다. 파일의 경우 콘텐츠가 두 빌드 간에 동일하게 유지되지만 데이터가 보관되는 실질적인 블록은 변경되었습니다. 결과적으로는 OTA 도중 업데이터가 불필요한 I/O를 수행하여 블록을 옮깁니다.

이 문제를 해결하기 위해 Android 7.0에서는 여러 빌드에 걸쳐 블록 할당의 일관성 유지를 시도하는 make_ext4fs 도구를 확장했습니다. make_ext4fsext4 이미지를 생성할 때 파일을 같은 블록에 할당하려고 시도하는 선택적 -d base_fs 플래그를 수락합니다. 이전 빌드의 타겟 파일 zip 파일(IMAGES/system.mapIMAGES/vendor.map)에서 블록 매핑 파일(base_fs 맵 파일)을 추출할 수 있습니다. 그러면 PRODUCT_SYSTEM_BASE_FS_PATHPRODUCT_VENDOR_BASE_FS_PATH를 통해 base_fs 파일을 확인 및 지정할 수 있습니다. 예를 들면 다음과 같습니다.

      PRODUCT_SYSTEM_BASE_FS_PATH := path/to/base_fs_files/base_system.map
      PRODUCT_VENDOR_BASE_FS_PATH := path/to/base_fs_files/base_vendor.map
    

이는 OTA 패키지의 전체 용량을 줄이는 데 도움이 되지 않지만 I/O 용량을 줄여 OTA 성능을 개선합니다.

앱 업데이트 방지

빌드 diff를 최소화하는 것 외에도 앱 스토어를 통해 업데이트되는 앱의 업데이트를 포함하지 않는 방식으로 OTA 용량을 줄일 수 있습니다. APK는 기기의 다양한 파티션의 상당 부분을 차지하는 경우가 많습니다. 앱 스토어에서 업데이트되는 앱의 최신 버전을 OTA 업데이트에 포함할 경우 OTA 패키지 크기에 대한 상당한 영향이 발생할 수 있는 반면 사용자 이점은 적을 수 있습니다. OTA 패키지를 받을 시점이라면 사용자가 이미 업데이트된 앱이나 최신 버전을 앱 스토어에서 직접 다운로드했을 가능성이 있습니다.