[AOSP] Gapps를 포함시키기

2018. 7. 6. 16:33Research/Android

소개

Android Open Source Project에서 소스코드를 가져와서 컴파일할 경우 안드로이드 시스템 자체는 컴파일해서 올릴 수는 있지만 Google PlayStore나 이와 관련된 것들이 하나도 없는 것을 확인할 수 있다.


이것들을 Gapps라고 부르며, OpenGapps나 microG 등 이러한 Gapps를 AOSP로 컴파일된 안드로이드에 올릴 수 있게 만들 수 있다.


필자는 OpenGapps를 사용할 것이다.


OpenGapps 

OpenGapps에 패키지 타입이 있는데 이는 포함되는 패키지의 내용에 차이가 있으며, 이를 대략 7가지로 볼 수 있다. (7가지로 분류한 근거는 opengapps-packages.mk이다.)

  • super: stock + Wallet + DMAgent + GoogleEarth + GCS + GoogleHindiIME + GoogleJapaneseInput + KoreanIME + GooglePinyinIME + Tycho + Street + TranslatePrebuilt + GoogleZhuyinIME
  • stock: full + GoogleCamera + GoogleContacts + LatinImeGoogle + TagGoogle + GoogleVrCore
  • full: mini + Books + CloudPrint2 + EditorsDocs + Drive + FitnessPrebuilt + PrebuiltKeep + Videos + Music2 + Newsstand + PrebuiltNewsWeather + PlayGames + EditorsSheets + EditorsSlides + talkback
  • mini: micro + CalculatorGoogle + PrebuiltDeskClockGoogle + PlusOne + Hangouts + Maps + Photos + YouTube
  • micro: nano + CalendarGooglePrebuilt + PrebuiltExchange3Google + PrebuiltGmail + GoogleHome
  • nano: pico + FaceLock + Velvet
  • pico: GoogleBackupTransport + GoogleContactsSyncAdapter + GoogleFeedback + GoogleOneTimeInitializer + GooglePartnerSetup + PrebuiltGmsCore + GoogleServicesFramework + GoogleLoginService + GoogleLoginService + SetupWizard + Phonesky + GoogleCalendarSyncAdapter


설치하기

OpenGapps를 AOSP시스템에 설치하는 방법은 두 가지이다.


1. Pre-built binary

첫번째 방법은 OpenGapps 공식 홈페이지에서 pre-built 바이너리를 다운받고 이를 TWRP와 같은 것을 이용하여 AOSP 시스템에 올리는 것이다.


물론 공식 홈페이지에서 github의 파일 서버, 즉 Amazon S3를 사용하기 때문에 지역에 따라 빠를 수도, 느릴 수도 있다... (필자는 200 kb/s가 나왔었음.)


하지만 pre-built된 바이너리의 경우 필요하지 않은 앱까지 포함되어있을 수 있다. 


그 결과 AOSP를 올린 Google Pixel에서는 full version에 해당 하는 바이너리를 올리려고 할 때, 아래의 메시지와 같이 필요한 용량이 부족하다고 에러를 낸다. 


Error 70: Insufficient storage space available in the system partition.

해당 에러는 말 그대로 system partion의 용량이, 즉 /system의 용량이 부족하여 발생하는 문제인데, 해당 파티션 크기는 hardware-specific한 것이기 때문에 partition resizing을 하는 것은 불가능하다. (조사한 바로는 이렇다고 하는데, 해결 방법 있으면 댓글이나 메일로 알려주세요.)


2. Compile with AOSP

두번째 방법은 OpenGapps의 소스코드를 다운받아 AOSP 컴파일할때 같이 포함시키는 것이다. 


해당 방법이 앞선 방법과 무슨 차이가 있느냐는 AOSP에 있는 패키지와 OpenGapps에 있는 패키지의 목적이 같을 경우 굳이 두 개가 존재할 필요가 없어 제외시킬 수도 있고, 또한 pre-built된 바이너리를 이용할 때 불필요한 패키지를 선택할 수 없었던 것에서 원하는 패키지만 선택해서 컴파일이 가능하기 때문이다.


https://github.com/opengapps/aosp_build 에 나와있는 방법을 적용하면 AOSP와 같이 컴파일이 가능하다.


1. repo init을 한 디렉터리에서 .repo/manifest.xml 를 열어 맨 뒤에 있는 </manifest> 전에 아래 내용을 추가한다.

<remote name="opengapps" fetch="https://github.com/opengapps/"  />


<project path="vendor/opengapps/build" name="aosp_build" revision="master" remote="opengapps" />

<project path="vendor/opengapps/sources/all" name="all" clone-depth="1" revision="master" remote="opengapps" />


<!-- arm64 depends on arm -->

<project path="vendor/opengapps/sources/arm" name="arm" clone-depth="1" revision="master" remote="opengapps" />

<project path="vendor/opengapps/sources/arm64" name="arm64" clone-depth="1" revision="master" remote="opengapps" />


<project path="vendor/opengapps/sources/x86" name="x86" clone-depth="1" revision="master" remote="opengapps" />

<project path="vendor/opengapps/sources/x86_64" name="x86_64" clone-depth="1" revision="master" remote="opengapps" />


2. repo sync를 통해서 opengapps 소스코드를 가져온다.


3. device/[manufacturer]/[product]/device.mk를 열어 제일 상단에 아래 내용을 추가한다.

GAPPS_VARIANT := stock

device/[manufacturer]/[product]/device.mk는 디바이스별로 조금씩 다르다.

- Google Pixel: device/google/marlin/device-sailfish.mk

- Google Nexus 5x: device/lge/bullhead/device.mk


예시로 stock을 입력을 하였는데, 각자 필요한 패키지가 들어있는 것을 선택하면 된다.


그리고 해당 값을 바꿨을 경우엔 기존에 빌드했던거 날리고 다시 컴파일 해야 한다.


4. device/[manufacturer]/[product]/device.mk를 열어 제일 하단에 아래 내용을 추가한다.

$(call inherit-product, vendor/opengapps/build/opengapps-packages.mk)

만약에 OpenGapps를 빼고 컴파일 하고 싶다고 하면, 위 구문만 지우면 된다.


5. AOSP를 빌드한다.


가 끝이면 얼마나 행복한가. 이 글을 쓰게된 이유고, 내가 겪었던 문제에 대해 이야기 해보자.


트러블 슈팅

Product cannot have overlay in vendor tree

[979/1044] including ./vendor/opengapps/build/modules/Chrome/Android.mk ...

lunzip: Output file 'vendor/opengapps/sources/arm64/app/com.android.chrome/24/nodpi/339608752.apk' already exists, skipping.

Warning: lz decompress command failed for vendor/opengapps/sources/arm64/app/com.android.chrome/24/nodpi/339608752.apk.lz

[1044/1044] including ./vendor/opengapps/build/modules/talkback/Android.mk ...

PRODUCT_COPY_FILES device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml ignored.

PRODUCT_COPY_FILES device/lge/bullhead/fstab.bullhead:root/fstab.bullhead ignored.

PRODUCT_COPY_FILES device/lge/bullhead/audio_effects.conf:system/etc/audio_effects.conf ignored.

No private recovery resources for TARGET_DEVICE bullhead

build/core/tasks/vendor_module_check.mk:81: error: Error: Product "aosp_bullhead" cannot have overlay in vendor tree: vendor/opengapps/build/overlay/pico vendor/opengapps/build/overlay/webview/24 vendor/opengapps/build/overlay/browser vendor/opengapps/build/overlay/dialer vendor/opengapps/build/overlay/mms.

15:55:38 ckati failed with: exit status 1

build/core/main.mk:21: recipe for target 'run_soong_ui' failed

make: *** [run_soong_ui] Error 1


#### make failed to build some targets (46 seconds) ####

위 에러는 vendor/opengapps/build/opengapps-packages.mk 에서 DEVICE_PACKAGE_OVERLAYS 와 관련된 모든 것을 주석치면 된다.


vendor PRODUCT_COPY_FILES file has unknown owner
Product "[TARGET]" cannot have overlay in vendor tree

system/sepolicy/Android.mk:79: warning: BOARD_SEPOLICY_VERS not specified, assuming current platform version

[1044/1065] including vendor/opengapps/build/modules/SetupWizard/Android.mk ...

WARNING: No APK found compatible with API level 28 for package com.google.android.setupwizard.default on arm64

WARNING: No APK found compatible with API level 28 for package com.google.android.setupwizard.default on arm

[1065/1065] including vendor/opengapps/build/modules/talkback/Android.mk ...

build/make/core/tasks/vendor_module_check.mk:82: error: Error: Product "aosp_marlin" cannot have overlay in vendor tree: vendor/opengapps/build/overlay/pico vendor/opengapps/build/overlay/assistant/28 vendor/opengapps/build/overlay/webview/24 vendor/opengapps/build/overlay/browser vendor/opengapps/build/overlay/dialer vendor/opengapps/build/overlay/mms vendor/opengapps/build/overlay/pixelicons/26 vendor/opengapps/build/overlay/pixellauncher/28.

06:53:43 ckati failed with: exit status 1


#### failed to build some targets (53 seconds) ####


[717/1044] including ./system/sepolicy/Android.mk ...

./system/sepolicy/Android.mk:107: warning: BOARD_SEPOLICY_VERS not specified, assuming current platform version

[979/1044] including ./vendor/opengapps/build/modules/Chrome/Android.mk ...

lunzip: Output file 'vendor/opengapps/sources/arm64/app/com.android.chrome/24/nodpi/339608752.apk' already exists, skipping.

Warning: lz decompress command failed for vendor/opengapps/sources/arm64/app/com.android.chrome/24/nodpi/339608752.apk.lz

[1044/1044] including ./vendor/opengapps/build/modules/talkback/Android.mk ...

PRODUCT_COPY_FILES device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml ignored.

PRODUCT_COPY_FILES device/lge/bullhead/fstab.bullhead:root/fstab.bullhead ignored.

PRODUCT_COPY_FILES device/lge/bullhead/audio_effects.conf:system/etc/audio_effects.conf ignored.

No private recovery resources for TARGET_DEVICE bullhead

build/core/tasks/vendor_module_check.mk:88: error: Error: vendor PRODUCT_COPY_FILES file "vendor/opengapps/sources/all/framework/24/com.google.android.pano.v1.jar:system/framework/com.google.android.pano.v1.jar" has unknown owner.

14:22:58 ckati failed with: exit status 1

build/core/main.mk:21: recipe for target 'run_soong_ui' failed

make: *** [run_soong_ui] Error 1


#### make failed to build some targets (56 seconds) ####

위 에러는 device/[manufacturer]/[product]/aosp.mk 에서 PRODUCT_RESTRICT_VENDOR_FILES := false로 바꿔주면 된다.


aosp.mk도 앞선 device.mk와 같이 조금씩 경로가 다르다.

- Google Pixel: device/google/marlin/aosp_sailfish.mk

- Google Nexus 5x: device/lge/bullhead/aosp_bullhead.mk


Call stack 보여주면서 Aborted

    #09 pc 000000000002082f  /lib/x86_64-linux-gnu/libc-2.23.so (__libc_start_main+239)

      __libc_start_main

      /build/glibc-Cl5G7W/glibc-2.23/csu/../csu/libc-start.c:291

    #10 pc 000000000000b308  /data/android_build/nexus_5x/out/host/linux-x86/bin/dex2oatd (???)


Fault message: 

/bin/bash: line 1: 31659 Aborted                 ( ANDROID_LOG_TAGS="*:e" out/host/linux-x86/bin/dex2oatd --runtime-arg -Xms64m --runtime-arg -Xmx512m --runtime-arg -classpath --runtime-arg "&" --boot-image=out/target/product/sailfish/dex_bootjars/system/framework/boot.art --dex-file=vendor/opengapps/sources/arm64/app/com.google.android.apps.docs.editors.docs/21/480/182520545.apk --dex-location=/system/app/EditorsDocs/EditorsDocs.apk --oat-file=out/target/product/sailfish/obj/APPS/EditorsDocs_intermediates/oat/arm64/package.odex --android-root=out/target/product/sailfish/system --instruction-set=arm64 --instruction-set-variant=generic --instruction-set-features=default --runtime-arg -Xnorelocate --compile-pic --no-generate-debug-info --generate-build-id --abort-on-hard-verifier-error --force-determinism --no-inline-from=core-oj.jar --compiler-filter=quicken )

[ 56% 220/392] build out/target/product/sailfish/obj/APPS/Maps_intermediates/oat/arm64/package.odex

ninja: build stopped: subcommand failed.

20:49:02 ninja failed with: exit status 1

build/core/main.mk:21: recipe for target 'run_soong_ui' failed

make: *** [run_soong_ui] Error 1


#### make failed to build some targets (04:57 (mm:ss)) ####

위 에러는 현재 WITH_DEXPREOPT=false를 환경 변수로 줘서 make를 실행시키니 컴파일이 진행이 된다.


Out of space? the tree size ~

Running:  mkuserimg.sh -s /tmp/tmpeNCQLe out/target/product/sailfish/obj/PACKAGING/systemimage_intermediates/system.img ext4 / 2113941504 -D out/target/product/sailfish/system -L / out/target/product/sailfish/obj/ETC/file_contexts.bin_intermediates/file_contexts.bin

make_ext4fs -s -T -1 -S out/target/product/sailfish/obj/ETC/file_contexts.bin_intermediates/file_contexts.bin -L / -l 2113941504 -a / out/target/product/sailfish/obj/PACKAGING/systemimage_intermediates/system.img /tmp/tmpeNCQLe out/target/product/sailfish/system

error: ext4_allocate_best_fit_partial: failed to allocate 536 blocks, out of space?

Creating filesystem with parameters:

    Size: 2113941504

    Block size: 4096

    Blocks per group: 32768

    Inodes per group: 8064

    Inode size: 256

    Journal blocks: 8064

    Label: /

    Blocks: 516099

    Block groups: 16

    Reserved block group size: 127

Out of space? the tree size of out/target/product/sailfish/system is (MB): 

2321 out/target/product/sailfish/system

The max is 2048 MB.

ninja: build stopped: subcommand failed.

18:24:32 ninja failed with: exit status 1

build/core/main.mk:21: recipe for target 'run_soong_ui' failed

make: *** [run_soong_ui] Error 1


#### make failed to build some targets (16 seconds) ####

Nexus 5x에 대해서는 문제 없이 진행이 된 것을 확인할 수 있고, Pixel은 여전히 용량이 부족하다는 문제로 /system에 대한 즉 system.img가 컴파일이 안된다.


device/google/marlin/sailfish/BoardConfig.mk 에 보면 BOARD_SYSTEMIMAGE_PARTITION_SIZE := 2147483648 라고 나와있고 이는 2GB인 것으로 보인다.


이는  hardware-specific한 것이기 때문에 따로 조정이 불가능하다고 한다.


컴파일 결과 2321MB, 즉 2.3GB가량이 되어야 하기 때문에 사용할 수 없다.


이후 Full, Mini로 바꿔서 컴파일 해봤는데, 여전히 2321MB라고 나오기래 make clobber를 실행하여 기존에 컴파일한 것을 날리고 다시 시도하였다.


컴파일 하는 중에 찾아보니 make clean과 make clobber에 차이가 있다고 한다.


make clean = rm -rf $out = rm -rf out/target/product/sailfish

make clobber = rm -rf out


Created filesystem with 2423/129024 inodes and 442622/516099 blocks

Running:  build_verity_tree -A aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7 out/target/product/sailfish/obj/PACKAGING/systemimage_intermediates/system.img /tmp/tmp_NNEQx_verity_images/verity.img

3a4a35a53a44b11d867f69c67e8a02e23c430964247b1201621d33f7756edbc6 aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7

Running:  system/extras/verity/build_verity_metadata.py build 2113941504 /tmp/tmp_NNEQx_verity_images/verity_metadata.img 3a4a35a53a44b11d867f69c67e8a02e23c430964247b1201621d33f7756edbc6 aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7 /dev/block/platform/soc/624000.ufshc/by-name/system verity_signer build/target/product/security/verity.pk8

['verity_signer', '/tmp/tmpMtfPer.table', 'build/target/product/security/verity.pk8', '/tmp/tmpLpAHBZ.sig']

appending /tmp/tmp_NNEQx_verity_images/verity_metadata.img to /tmp/tmp_NNEQx_verity_images/verity.img

Running:  fec -e -p 0 out/target/product/sailfish/obj/PACKAGING/systemimage_intermediates/system.img /tmp/tmp_NNEQx_verity_images/verity.img /tmp/tmp_NNEQx_verity_images/verity_fec.img

encoding RS(255, 253) to '/tmp/tmp_NNEQx_verity_images/verity_fec.img' for input files:

1: 'out/target/product/sailfish/obj/PACKAGING/systemimage_intermediates/system.img'

2: '/tmp/tmp_NNEQx_verity_images/verity.img'

appending /tmp/tmp_NNEQx_verity_images/verity_fec.img to /tmp/tmp_NNEQx_verity_images/verity.img

Running:  append2simg out/target/product/sailfish/obj/PACKAGING/systemimage_intermediates/system.img /tmp/tmp_NNEQx_verity_images/verity.img


[100% 79827/79827] Install system fs image: out/target/product/sailfish/system.img

out/target/product/sailfish/system.img+ maxsize=2192424960 blocksize=135168 total=1812982644 reserve=22167552


#### make completed successfully (01:33:50 (hh:mm:ss)) ####

이리하여 Gapps에 포함된 AOSP를 컴파일에 성공하였다.


정리해 놓은 내용들을 의식의 흐름대로 다시 작성해서 내용이 깔끔하지 않을 수 있지만, 제가 겪었던 문제들이 참고가 되셨음 한다. Fin.


참고

https://opengapps.org/

https://github.com/opengapps/aosp_build

https://github.com/opengapps/aosp_build/issues/63

https://github.com/opengapps/aosp_build/issues/146

https://qiita.com/popondeli/items/f63960f8f5932dd60b57

https://stackoverflow.com/questions/34560562/how-to-increase-system-img-partition-size

https://github.com/opengapps/opengapps/wiki/Advanced-Features-and-Options#downsizing
https://gsmaker.wordpress.com/2013/03/20/doc-make-clean-vs-make-clobber/