[컴][리눅스] Android framework build


환경

  • VMWare Player + Ubuntu 12.04 LTS 64bit
  • 3GB memory
  • CPU 1 core (Intel Core i3-2100 CPU @ 3.1GHz)
  • android source version 4.3.2.1 (2013/07/31)
  • HDD : 대략 Ubuntu 용량까지 적어도 40GB 는 있어야 한다.

http://tools.android.com/build

java sdk 6

sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
(sudo add-apt-repository ppa:webupd8team/java)
sudo apt-get update
sudo apt-get install sun-java6-jdk
sudo apt-get install oracle-java6-installer
sudo apt-get install oracle-java6-set-default


etc

sudo apt-get install python
sudo apt-get install git-core
sudo apt-get install libgl1-mesa-dri:i386

sudo apt-get install git gnupg flex bison gperf build-essential \
  zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
  libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
  libgl1-mesa-dev g++-multilib mingw32 tofrodos \
  python-markdown libxml2-utils xsltproc zlib1g-dev:i386


sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so


usb connection setting - for Ubuntu 12.04

http://source.android.com/source/initializing.html#configuring-usb-access

setting up ccache

clean 이나 다른 build 등을 해서 locality 가 자꾸 무너지는 경우에 유용
skip

.bash 에 output director 지정

export OUT_DIR_COMMON_BASE=<path-to-your-out-directory>
skip


repo, 2013.08.01

mkdir ~/bin
PATH=~/bin:$PATH
curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
chmod +x ~/bin/repo

작업 디렉토리

mkdir JELLY_SOURCE
cd JELLY_SOURCE

  • master's repo
    • repo init -u https://android.googlesource.com/platform/manifest
  • branch's repo
    • repo init -u https://android.googlesource.com/platform/manifest -b android-4.0.1_r1
    • ref. 4 에서 branch version 을 알 수 있다.

이름, email 입력

repo sync

vmware 에서 약 2시간 정도 걸렸다.
3GB memory
core 2

setting up build environment

source build/envsetup.sh


apk 파일을 odex 없이 만드려면[ref. 5]

  • 모든 apk 를 odex 없이 만드려면
    • make WITH_DEXPREOPT=true 를 하던지,
    • build/core/package.mk 에 LOCAL_DEX_PREOPT := false 를 true 로 수정하면 된다.
  • 개개의 apk 에 대해 설정하려면
    • packages/apps/Contacts/Android.mk 에 LOCAL_DEX_PREOPT := false 를 추가 하면 된다.


start to build

빌드하는데 약 30GB 정도가 필요하다고 한다.

source /etc/profile.d/jdk.sh  # $JAVA_HOME 설정

make + make sdk 를 하지 않고, make sdk_win 만 build 를 하게 되면, error 3 이 발생한다. 그래서 한 번 full build 를 해주고, clean 을 하지 않을 상태로 make sdk 를 먼저 해주고, make sdk_win 을 해줘야 한다. 그러므로,

lunch full-eng
make -j1 (약 5시간, -j 옵션은 core 가 여러개 일때 필요하다. 여기선 참고로 적는다.)
               make -j2 (약 4시간)

lunch sdk-eng
make -j1 sdk (약 1시간)
make -j1 sdk_win


============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.3.2.1.000.000
TARGET_PRODUCT=sdk
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
TARGET_CPU_VARIANT=generic
HOST_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-3.5.0-37-generic-x86_64-with-Ubuntu-12.04-precise
HOST_BUILD_TYPE=release
BUILD_ID=OPENMASTER
OUT_DIR=out
============================================


error 1

Module 'bluetooth-health'in PRODUCT_PACKAGES has nothing to install!
>> Enforce no nonexistent modules in PRODUCT_PACKAGES for sdk builds

Modify /core/main.mk diff

error 2

## Running sdk/eclipse/scripts/create_all_symlinks.sh
### Starting tools/base: gradlew publishLocal
sdk/eclipse/scripts/create_all_symlinks.sh: line 285: cd: tools/base: No such file or directory
make: *** [out/host/linux-x86/obj/EXECUTABLES/monitor_intermediates/monitor] Error 1

repo init -u https://android.googlesource.com/platform/manifest -g all,tools
repo sync

error 3

No rule to make target `out/host/linux-x86/bin/emugen', needed by `out/host/windows-x86/obj/STATIC_LIBRARIES/lib_renderControl_dec_intermediates/renderControl_dec.cpp'

>> https://groups.google.com/forum/#!topic/android-building/Zmnrf6DRgjg

lunch full-eng
make

lunch sdk-eng
make sdk
make win_sdk


결과


SRC_DIR/out/host/windows/sdk/android-sdk_eng.namh_windows.zip


full build 결과
...
+ ENABLE_SPARSE_IMAGE=
+ '[' out/target/product/generic/cache = -s ']'
+ '[' 6 -ne 5 -a 6 -ne 6 ']'
+ SRC_DIR=out/target/product/generic/cache
+ '[' '!' -d out/target/product/generic/cache ']'
+ OUTPUT_FILE=out/target/product/generic/cache.img
+ EXT_VARIANT=ext4
+ MOUNT_POINT=cache
+ SIZE=69206016
+ FC=out/target/product/generic/root/file_contexts
+ case $EXT_VARIANT in
+ '[' -z cache ']'
+ '[' -z 69206016 ']'
+ '[' -n out/target/product/generic/root/file_contexts ']'
+ FCOPT='-S out/target/product/generic/root/file_contexts'
+ MAKE_EXT4FS_CMD='make_ext4fs  -S out/target/product/generic/root/file_contexts -l 69206016 -a cache out/target/product/generic/cache.img out/target/product/generic/cache'
+ echo make_ext4fs -S out/target/product/generic/root/file_contexts -l 69206016 -a cache out/target/product/generic/cache.img out/target/product/generic/cache
make_ext4fs -S out/target/product/generic/root/file_contexts -l 69206016 -a cache out/target/product/generic/cache.img out/target/product/generic/cache
+ make_ext4fs -S out/target/product/generic/root/file_contexts -l 69206016 -a cache out/target/product/generic/cache.img out/target/product/generic/cache
Creating filesystem with parameters:
    Size: 69206016
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 4224
    Inode size: 256
    Journal blocks: 1024
    Label: 
    Blocks: 16896
    Block groups: 1
    Reserved block group size: 7
Created filesystem with 11/4224 inodes and 1302/16896 blocks
+ '[' 0 -ne 0 ']'
out/target/product/generic/cache.img maxsize=70654848 blocksize=2112 total=69206016 reserve=713856

Installed file list: out/target/product/generic/installed-files.txt
Target system fs image: out/target/product/generic/obj/PACKAGING/systemimage_intermediates/system.img
Running:  mkuserimg.sh out/target/product/generic/system out/target/product/generic/obj/PACKAGING/systemimage_intermediates/system.img ext4 system 576716800 out/target/product/generic/root/file_contexts
+ echo 'in mkuserimg.sh PATH=out/host/linux-x86/bin/:/usr/lib/jvm/java-6-oracle/bin:/home/namh/jelly_src/out/host/linux-x86/bin:/home/namh/jelly_src/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7/bin:/home/namh/jelly_src/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7/bin:/home/namh/jelly_src/prebuilts/gcc/linux-x86/mips/mipsel-linux-android-4.7/bin:/home/namh/jelly_src/development/emulator/qtools:/home/namh/jelly_src/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7/bin:/home/namh/jelly_src/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7/bin:/home/namh/jelly_src/development/scripts:/home/namh/jelly_src/prebuilts/devtools/tools:/home/namh/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/lib/jvm/java-6-oracle/bin:/usr/lib/jvm/java-6-oracle/db/bin:/usr/lib/jvm/java-6-oracle/jre/bin'
in mkuserimg.sh PATH=out/host/linux-x86/bin/:/usr/lib/jvm/java-6-oracle/bin:/home/namh/jelly_src/out/host/linux-x86/bin:/home/namh/jelly_src/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7/bin:/home/namh/jelly_src/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7/bin:/home/namh/jelly_src/prebuilts/gcc/linux-x86/mips/mipsel-linux-android-4.7/bin:/home/namh/jelly_src/development/emulator/qtools:/home/namh/jelly_src/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7/bin:/home/namh/jelly_src/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7/bin:/home/namh/jelly_src/development/scripts:/home/namh/jelly_src/prebuilts/devtools/tools:/home/namh/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/lib/jvm/java-6-oracle/bin:/usr/lib/jvm/java-6-oracle/db/bin:/usr/lib/jvm/java-6-oracle/jre/bin
+ ENABLE_SPARSE_IMAGE=
+ '[' out/target/product/generic/system = -s ']'
+ '[' 6 -ne 5 -a 6 -ne 6 ']'
+ SRC_DIR=out/target/product/generic/system
+ '[' '!' -d out/target/product/generic/system ']'
+ OUTPUT_FILE=out/target/product/generic/obj/PACKAGING/systemimage_intermediates/system.img
+ EXT_VARIANT=ext4
+ MOUNT_POINT=system
+ SIZE=576716800
+ FC=out/target/product/generic/root/file_contexts
+ case $EXT_VARIANT in
+ '[' -z system ']'
+ '[' -z 576716800 ']'
+ '[' -n out/target/product/generic/root/file_contexts ']'
+ FCOPT='-S out/target/product/generic/root/file_contexts'
+ MAKE_EXT4FS_CMD='make_ext4fs  -S out/target/product/generic/root/file_contexts -l 576716800 -a system out/target/product/generic/obj/PACKAGING/systemimage_intermediates/system.img out/target/product/generic/system'
+ echo make_ext4fs -S out/target/product/generic/root/file_contexts -l 576716800 -a system out/target/product/generic/obj/PACKAGING/systemimage_intermediates/system.img out/target/product/generic/system
make_ext4fs -S out/target/product/generic/root/file_contexts -l 576716800 -a system out/target/product/generic/obj/PACKAGING/systemimage_intermediates/system.img out/target/product/generic/system
+ make_ext4fs -S out/target/product/generic/root/file_contexts -l 576716800 -a system out/target/product/generic/obj/PACKAGING/systemimage_intermediates/system.img out/target/product/generic/system
Creating filesystem with parameters:
    Size: 576716800
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 7040
    Inode size: 256
    Journal blocks: 2200
    Label: 
    Blocks: 140800
    Block groups: 5
    Reserved block group size: 39
Created filesystem with 1156/35200 inodes and 64194/140800 blocks
+ '[' 0 -ne 0 ']'
Install system fs image: out/target/product/generic/system.img
out/target/product/generic/system.img+ maxsize=588791808 blocksize=2112 total=576716800 reserve=5947392



make sdk 결과

Package SDK Stubs: out/target/common/obj/PACKAGING/android_jar_intermediates/android.jar
Checking API: uiautomator-checkapi-last
Checking API: uiautomator-checkapi-current
target Java: android_uiautomator (out/target/common/obj/JAVA_LIBRARIES/android_uiautomator_intermediates/classes)
Copying: out/target/common/obj/JAVA_LIBRARIES/android_uiautomator_intermediates/classes-jarjar.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/android_uiautomator_intermediates/emma_out/lib/classes-jarjar.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/android_uiautomator_intermediates/classes.jar
target Static Jar: android_uiautomator (out/target/common/obj/JAVA_LIBRARIES/android_uiautomator_intermediates/javalib.jar)
Package android-support-v4.jar: out/target/common/obj/PACKAGING/android-support-v4_intermediates/android-support-v4.jar
target Static Jar: android-support-v7-gridlayout (out/target/common/obj/JAVA_LIBRARIES/android-support-v7-gridlayout_intermediates/javalib.jar)
Package android-support-v7-gridlayout.jar: out/target/common/obj/PACKAGING/android-support-v7-gridlayout_intermediates/android-support-v7-gridlayout.jar
target Static Jar: android-support-v7-appcompat (out/target/common/obj/JAVA_LIBRARIES/android-support-v7-appcompat_intermediates/javalib.jar)
Package android-support-v7-appcompat.jar: out/target/common/obj/PACKAGING/android-support-v7-appcompat_intermediates/android-support-v7-appcompat.jar
target Static Jar: android-support-v7-mediarouter (out/target/common/obj/JAVA_LIBRARIES/android-support-v7-mediarouter_intermediates/javalib.jar)
Package android-support-v7-mediarouter.jar: out/target/common/obj/PACKAGING/android-support-v7-mediarouter_intermediates/android-support-v7-mediarouter.jar
Package android-support-v13.jar: out/target/common/obj/PACKAGING/android-support-v13_intermediates/android-support-v13.jar
Import includes file: out/host/linux-x86/obj/EXECUTABLES/atree_intermediates/import_includes
host C++: atree <= build/tools/atree/atree.cpp
host C++: atree <= build/tools/atree/files.cpp
host C++: atree <= build/tools/atree/fs.cpp
Export includes file: build/tools/atree/Android.mk -- out/host/linux-x86/obj/EXECUTABLES/atree_intermediates/export_includes
host Executable: atree (out/host/linux-x86/obj/EXECUTABLES/atree_intermediates/atree)
Install: out/host/linux-x86/bin/atree
Import includes file: out/host/linux-x86/obj/EXECUTABLES/line_endings_intermediates/import_includes
host C: line_endings <= development/tools/line_endings/line_endings.c
Export includes file: development/tools/line_endings/Android.mk -- out/host/linux-x86/obj/EXECUTABLES/line_endings_intermediates/export_includes
host Executable: line_endings (out/host/linux-x86/obj/EXECUTABLES/line_endings_intermediates/line_endings)
Install: out/host/linux-x86/bin/line_endings
Package SDK: out/host/linux-x86/sdk/android-sdk_eng.namh_linux-x86.zip
SDK: warning: including GNU target out/target/product/generic/system/lib/libgccdemangle.so

make win_sdk

====== [Windows SDK] Build android-sdk_eng.namh_windows ======

MAIN_SDK_NAME: android-sdk_eng.namh_linux-x86
WIN_SDK_NAME : android-sdk_eng.namh_windows
WIN_SDK_DIR  : out/host/windows/sdk
WIN_SDK_ZIP  : out/host/windows/sdk/android-sdk_eng.namh_windows.zip
Windows SDK generated at out/host/windows/sdk/android-sdk_eng.namh_windows.zip

====== [Windows SDK] Done ======

images

~/WORKING_DIRECTORY/out/target/product/generic
빌드가 끝나면, 위의 경로에서 .img 들을 찾을 수 있다.

  • system.img : 
    • /home/namh/jelly_src/out/target/product/generic/system 의 묶음
  • ramdisk.img
    • /home/namh/jelly_src/out/target/product/generic/root
  • userdata.img
    • /home/namh/jelly_src/out/target/product/generic/data
    • /home/namh/jelly_src/out/target/common/obj/APPS

참고로, 이 .img 를 unpack 할 수 있다.(참고: http://i5on9i.blogspot.kr/2013/08/img-img.html)


system.img 에서 apk 들을 보면, .odex 파일과 .apk 파일로 나눠져 있다. 그런데 이 녀석들을 compile option 을 줘서 .apk 파일 하나로 생성되게 할 수 있다. 물론 빌드하기 전에 옵션을 만져줘야 한다.[ref. 5][ref. 6]


build process[ref. 7, 8]



emulator 에서 image 실행

make full-eng 만 한 상태라면 아래 경로에 있을 것이다.[ref. 1]
~/WORKING_DIRECTORY/out/target/product/generic
이 .img 들을 가지고 아래 처럼 하면, emulator 로 실행할 수 있다.
<android_sdk>\tools\emulator.exe -system system.img -ramdisk ramdisk.img -data userdata.img
see also : http://i5on9i.blogspot.kr/2013/08/command-avd.html


error - Segmentation fault
namh@ubuntu:~/jelly_src$ ./out/host/linux-x86/bin/emulator -system out/target/product/generic -kernel prebuilts/qemu-kernel/arm/kernel-qemu -verbose
emulator: WARNING: Please note that the -system option should now be used to point to the initial
system image (like the obsolete -image option). To point to the system directory
please now use '-sysdir ' instead.

emulator: autoconfig: -system out/target/product/generic/system.img
emulator: autoconfig: -ramdisk out/target/product/generic/ramdisk.img
emulator: autoconfig: -datadir out/target/product/generic
emulator: autoconfig: -data out/target/product/generic/userdata-qemu.img
emulator: Found target ABI=armeabi-v7a, architecture=arm
emulator: Found target API level: 18
emulator: using core hw config path: out/target/product/generic/hardware-qemu.ini
emulator: autoconfig: -skin HVGA
emulator: autoconfig: -skindir (null)
emulator: keyset loaded from: /home/namh/.android/default.keyset
emulator: skin name 'HVGA' aliased to '320x480'
emulator: found magic skin width=320 height=480 bpp=16

emulator: Using initial system image: out/target/product/generic/system.img
emulator: WARNING: system partition size adjusted to match image file (550 MB > 200 MB)

emulator: autoconfig: -initdata out/target/product/generic/userdata.img
emulator: WARNING: data partition size adjusted to match image file (550 MB > 200 MB)

emulator: autoconfig: -cache out/target/product/generic/cache.img
emulator: autoconfig: -sdcard out/target/product/generic/system.img
emulator: Physical RAM size: 96MB

emulator: Found target ABI=armeabi-v7a
emulator: Auto-config: -qemu -cpu cortex-a8
Content of hardware configuration file:
  hw.cpu.arch = arm
  hw.cpu.model = cortex-a8
  hw.ramSize = 96
  hw.screen = touch
  hw.mainKeys = yes
  hw.trackBall = yes
  hw.keyboard = no
  hw.keyboard.lid = no
  hw.keyboard.charmap = qwerty2
  hw.dPad = yes
  hw.gsmModem = yes
  hw.gps = yes
  hw.battery = yes
  hw.accelerometer = yes
  hw.audioInput = yes
  hw.audioOutput = yes
  hw.sdCard = yes
  hw.sdCard.path = out/target/product/generic/system.img
  disk.cachePartition = yes
  disk.cachePartition.path = out/target/product/generic/cache.img
  disk.cachePartition.size = 66m
  hw.lcd.width = 320
  hw.lcd.height = 480
  hw.lcd.depth = 16
  hw.lcd.density = 160
  hw.lcd.backlight = yes
  hw.gpu.enabled = no
  hw.camera.back = emulated
  hw.camera.front = none
  vm.heapSize = 16
  hw.sensors.proximity = yes
  hw.sensors.magnetic_field = yes
  hw.sensors.orientation = yes
  hw.sensors.temperature = yes
  kernel.path = prebuilts/qemu-kernel/arm/kernel-qemu
  kernel.parameters =  android.checkjni=1
  disk.ramdisk.path = out/target/product/generic/ramdisk.img
  disk.systemPartition.initPath = out/target/product/generic/system.img
  disk.systemPartition.size = 550m
  disk.dataPartition.path = out/target/product/generic/out/target/product/generic/userdata-qemu.img
  disk.dataPartition.size = 550m
  avd.name = 
.
QEMU options list:
emulator: argv[00] = "./out/host/linux-x86/bin/emulator64-arm"
emulator: argv[01] = "-android-hw"
emulator: argv[02] = "out/target/product/generic/hardware-qemu.ini"
Concatenated QEMU options:
 ./out/host/linux-x86/bin/emulator64-arm -android-hw out/target/product/generic/hardware-qemu.ini
emulator: registered 'boot-properties' qemud service
emulator: nand_add_dev: system,size=0x22600000,initfile=out/target/product/generic/system.img
emulator: mapping 'system' NAND image to /tmp/android-namh/emulator-O2f423
WARNING: Data partition already in use. Changes will not persist!
emulator: nand_add_dev: userdata,size=0x22600000
emulator: mapping 'userdata' NAND image to /tmp/android-namh/emulator-KDwBdW
emulator: registered 'boot-properties' qemud service
emulator: Adding boot property: 'dalvik.vm.heapsize' = '16m'
emulator: Adding boot property: 'qemu.sf.lcd_density' = '160'
emulator: Adding boot property: 'qemu.hw.mainkeys' = '1'
emulator: Adding boot property: 'qemu.sf.fake_camera' = 'back'
emulator: nand_add_dev: cache,size=0x4200000,file=out/target/product/generic/cache.img
emulator: Initializing hardware OpenGLES emulation support
Segmentation fault (core dumped)

emulator 대신에 emulator-arm 으로 실행했더니 됐다. 이외에도 여러가지 case 가 있는 듯 하다. 아래 글을 참고 하자.



error - black screen

emulator 가 실행이 되지만, 계속 black screen 에 머물러 있다.

gingerbread 에서는 gingerbread branch 에서는 emulator 가 동작하지 않고, 이후 source version 에서 동작이 되었다고 한다. 이런 사례로 미루어 볼 때 최신 source 를 빌드하고 나서 emulator 가 동작안할 가능성도 있다.
http://source.android.com/source/known-issues.html
이 경우 동작하는 sdk 를 다운 받아서 emulator 를 실행해야 하는 듯 하다. 하지만 2013.8.05 일 최신 버전 master 를 다운받아서 나온 img 들은 최신 sdk 의 emulator 에서 동작하지 않았다.

emulator 에서 동작하는 img 를 만들어 보고 싶다면, release 된 버전을 가지고 compile 을 해 보는 것이 좋을 듯 하다. 참고로 emulator 는
lunch full-eng
를 해서 나온 .img 만 가능하다고 한다.[Choose a Target, Android Dev. Document]

근데, ref. 9 를 보면
  • lunch sdk_x86-eng
  • make sdk 
만 해서 emulator 를 build 하는 듯 하다.



기타


커널빌드
커널만 repo 에서 받아와서 빌드할 수 있다.(Building Kernels, android document)
full source 를 받았다면, 아래 경로에 source 가 있다.
device/<vendor>/<name> :
 /home/namh/jelly_src/device/samsung/maguro

빌드한 소스를 eclipse 와 연결하는 방법



See Also

  1. Tutorial: Android Internals - Building a Custom ROM, Pt. 1 of 2


References

  1. http://www.rodneybeede.com/How_to_build_an_Android_ROM_from_source.html
  2. Building and Testing Android Source, 2013년 2월
  3. 안드로이드 goldfish 디버그하기, 2011년 2월
  4. Codenames, Tags, and Build Numbers, Android branch 와 안드로이드 버전 이름 정보를 알 수 있다.
  5. Android 빌드 시 preload app 을 odex 없이 빌드하기., 2012년 1월 4일
  6. https://groups.google.com/forum/#!topic/android-building/oWrcDTkpH8g, 2010년
  7. http://developer.android.com/tools/building/index.html#detailed-build
  8. http://www.androes.com/176
  9. Android on x86: Understanding Android Device Emulation By Iggy Krajci and Darren Cummings, September 17, 2013



댓글 없음:

댓글 쓰기