4/10/2015

Device.mk의 PRODUCT Flags 의 종류와 기능들

1. Android 기본 Build 방법

  • STEP1 - Android Build 준비를 위해 기본설정 
lunch/m/mm/mmm/cgrep/jgrep 등 기본명령어들 사용가능 
$ source build/envsetup.sh    // 설정시 vendor와 관련된 shell script 확장 및 build의 기본명령어 실행가능
including device/fsl/imx6dq/vendorsetup.sh
including device/fsl/imx6sl/vendorsetup.sh
including device/fsl/imx6sx/vendorsetup.sh
......

상위 Shell Script를 보면, 지원되는 기능을 쉽게 알수 있으며, 분석도 쉽다. 

  • STEP2 - Android Board 관련설정 
lunch를 이용하여, boardname 과 Build Type를 선택 (ProductName-BuildMode)
$ lunch 
or
$ lunch board-user/userdebug/eng   //3개 중 선택하여 설정  

  • STEP3 - Android Build 
상위에서 설정한 Build Type과 Board 설정으로 Android를 전체 Build 진행 
$ make 2>&1 | tee build-log.txt   //전체 Build 하며, 에러가 발생시 이를 멈추지 말고 진행하고 로그를 남김 

Android Build 구조 

Android Build 방법

Android Source 구조 



$ hmm    // 상위 source build/envsetup.sh  이후 가능하며, envsetup.sh shellscript
...
Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
- lunch:      lunch <product_name>-<build_variant>
              Selects <product_name> as the product to build, and <build_variant> as the variant to
              build, and stores those selections in the environment to be read by subsequent
              invocations of 'm' etc.
- tapas:      tapas [<App1> <App2> ...] [arm|x86|mips|arm64|x86_64|mips64] [eng|userdebug|user]
- croot:      Changes directory to the top of the tree, or a subdirectory thereof.
- m:          Makes from the top of the tree.
- mm:         Builds all of the modules in the current directory, but not their dependencies.
- mmm:        Builds all of the modules in the supplied directories, but not their dependencies.
              To limit the modules being built use the syntax: mmm dir/:target1,target2.
- mma:        Builds all of the modules in the current directory, and their dependencies.
- mmma:       Builds all of the modules in the supplied directories, and their dependencies.
- provision:  Flash device with all required partitions. Options will be passed on to fastboot.
- cgrep:      Greps on all local C/C++ files.
- ggrep:      Greps on all local Gradle files.
- jgrep:      Greps on all local Java files.
- resgrep:    Greps on all local res/*.xml files.
- mangrep:    Greps on all local AndroidManifest.xml files.
- mgrep:      Greps on all local Makefiles files.
- sepgrep:    Greps on all local sepolicy files.
- sgrep:      Greps on all local source files.
- godir:      Go to the directory containing a file.
- allmod:     List all modules.
- gomod:      Go to the directory containing a module.
- pathmod:    Get the directory containing a module.
- refreshmod: Refresh list of modules for allmod/gomod.

Environment options:
- SANITIZE_HOST: Set to 'true' to use ASAN for all host modules. Note that
                 ASAN_OPTIONS=detect_leaks=0 will be set by default until the
                 build is leak-check clean.
- ANDROID_QUIET_BUILD: set to 'true' to display only the essential messages.



1.2 Vendor Shell Script 

각 Vendor Shell Script에서 board name 과 Build Type를 쉽게 추가되는 것을 확인되며, 아래의 이름으로 lunch로 실행

$ cat device/fsl/imx6sx/vendorsetup.sh //boardname 과 user/userdebug 확인 (lunch에서 설정가능)
add_lunch_combo sabresd_6sx-user
add_lunch_combo sabresd_6sx-userdebug
add_lunch_combo sabreauto_6sx-user
add_lunch_combo sabreauto_6sx-userdebug 

상위 STEP2에서 여기서 등록된 lunch로 설정 i.MX6 의 경우 아래와 같다.  

$ lunch sabresd_6sx-userdebug
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=9
TARGET_PRODUCT=sabresd_6sx
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=cortex-a9
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.15.0-128-generic-x86_64-Ubuntu-16.04.3-LTS
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=2.2.0-ga-rc3
OUT_DIR=out
============================================

i.MX6의 경우 별도의 DSP가 존재하지 않으며, ARM의 neon mode를 이용하여 DSP역할을 해주는 것으로 보인다. 

$ lunch sabresd_6sx-eng

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=9
TARGET_PRODUCT=sabresd_6sx
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=cortex-a9
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.15.0-128-generic-x86_64-Ubuntu-16.04.3-LTS
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=2.2.0-ga-rc3
OUT_DIR=out
============================================

1.2 Android PRODUCT 와 BUILD_VARIANT

 lunch에서 boardname 과 build type를 설정  
  1. TARGET_PRODUCT : 상위 Board Name 
  2. TARGET_BUILD_VARIANT : Build Type 이며, eng/user/userdebug

PRODUCT_PACKAGES
LOCAL_MODULE_TAGS 

$ find . -name default.prop
$ cat ./development/vndk/tools/definition-tool/tests/testdata/test_vndk_lib_dir/vndk_versioned_multiple/vendor/default.prop 
ro.vndk.version=29
각 LOCAL_MODULE_TAGS 의 설정으로 기본은 optional 

default.prop (default.property 의 약어로 상위와 같이 설정확인)

개발자 버전으로 enginerring build로 개발자들이 가장 많이 사용 
• eng: development configuration with additional debugging tools
— Installs modules tagged with: eng and/or debug.
— Installs modules according to the product definition files, in addition to tagged modules.
— ro.secure=0
— ro.debuggable=1
— ro.kernel.android.checkjni=1
— adb is enabled by default. //adb 사용가능

• user: limited access; suited for production
— Installs modules tagged with user.
— Installs modules according to the product definition files, in addition to tagged modules.
— ro.secure=1
— ro.debuggable=0
— adb is disabled by default.//adb 사용불가능

• userdebug: like user but with root access and debuggability; preferred for debugging
— Installs modules tagged with debug.
— ro.debuggable=1
— adb is enabled by default. // adb 사용가능 

Build-variants 


2. build/core/main.mk 

상위 전체 make를 하면, 상위 main.mk가 호출되면서 Build가 진행된다. 

Android Makefile과 환경설정설명
  http://elinux.org/Android_Device

Android Kernel 구성 


2.1 Boardconfig.mk 분석 

Android의 Build할 경우 Board의 전체 Config이며, 가장중요한 파일이며, 이파일 기반으로 분석을 시작해야한다. 
복잡한 경우에는 추가되는 부수적인 BoardCommonConfig.mk 이던지 추가하여 공통사항들을 설정한다. 

$ find . -name BoardConfig.mk  // 기본위치파악 
device/Vendor/ARCH/BoardName/BoardConfig.mk   
....  
상위와 같이 device/Vendor/ARCH/BoardName/BoardConfig.mk에 존재하며 이곳에 manifest.xml를 비롯하여 각종중요파일들이 같이 존재한다.
  1. init.rc/init%hardware$.rc:  init 후 script 기능
  2. ueventd.%hardware%.rc:  udev 기능 설정 
  3. 이외 파일 아래 설명 

BoardConfig.mk 가 있는 곳에 모든 관련설정이 포함하고 있으며, 이곳에 없다면, 같은 디렉토리의 다른 Makefile를 참조하자 

  • BoardConfig.mk 분석 (i.MX6)
가장먼저 분석해야할 각 Board의 세부 Config 내용이며, Device Tree를 비롯하여 세부 설정사항들을 알수 있음 
$ vi ./device/fsl/imx6sx/sabresd_6sx/BoardConfig.mk 
#
# 주석 
#

IMX_DEVICE_PATH := device/fsl/imx6sx/sabresd_6sx

#
# include로 확장 
# 
include $(IMX_DEVICE_PATH)/build_id.mk
include device/fsl/imx6sx/BoardConfigCommon.mk

ifeq ($(PREBUILT_FSL_IMX_CODEC),true)
-include $(FSL_CODEC_PATH)/fsl-codec/fsl-codec.mk
endif
.....
BOARD_PREBUILT_DTBOIMAGE := out/target/product/sabresd_6sx/dtbo-imx6sx.img
TARGET_BOOTLOADER_CONFIG := imx6sx:imx6sxsabresdandroid_defconfig

# imx6sx default dts
TARGET_BOARD_DTS_CONFIG := imx6sx:imx6sx-sdb.dtb
TARGET_KERNEL_DEFCONFIG := imx_v7_android_defconfig

  • AndroidBoard.mk
BoardConfig.mk 와 같은위치에 존재하는 AndroidBoard.mk 있으며, Build되는 전체구조와 순서를 쉽게 파악 알수 있다 

$ vi ./device/fsl/imx6sx/sabresd_6sx/AndroidBoard.mk 
include device/fsl/common/build/dtbo.mk
include device/fsl/common/build/imx-recovery.mk
include device/fsl/common/build/gpt.mk
include $(FSL_PROPRIETARY_PATH)/fsl-proprietary/media-profile/media-profile.mk
ifneq ($(PRODUCT_IMX_CAR),true)
include $(FSL_PROPRIETARY_PATH)/fsl-proprietary/sensor/fsl-sensor.mk
endif

ifneq ($(BOARD_OTA_BOOTLOADERIMAGE),)
  INSTALLED_RADIOIMAGE_TARGET += $(PRODUCT_OUT)/bootloader.img
  BOARD_PACK_RADIOIMAGES += bootloader.img
endif

  • AndroidProducts.mk
상위와 같은 위치에 존재하며, 상위 LUNCH 설정하며, PRODUCT_MAKEFILES을 분석을 하면 쉽게 제품의 구조를 파악가능 
build/target/product/AndroidProducts.mk 와 같이 보자.

$ vi ./device/fsl/imx6sx/sabredsd_6sx/AndroidProducts.mk
# Copied from build/target/product/AndroidProducts.mk

PRODUCT_MAKEFILES := \
  $(LOCAL_DIR)/evk_6sl/evk_6sl.mk

COMMON_LUNCH_CHOICES := \
  evk_6sl-user \
  evk_6sl-userdebug




2.2 Device.mk 와 device_xxx.mk

Android에서 사용되어지는 Device의 빌드할 경우 관련 설정 및 Build 파일로 만약 새로운 Device를 추가한다면, 이 Makefile도 추가해야한다.

Device.mk를 분석을 해보면, 아래와 같이
PRODUCT라는 FLAG들이 많다는 것을 알며, 이것의 종류가 좀 있다고 느껴진다.


2.3  AndroidProduct.mk 의 PRODUCT_MAKEFILES

상위에서 설명한 AndroidProduct.mk에 PRODUCT_MAKEFILES들을 분석하면 다음과 같이 구조가 나온다.
  1. PRODUCT_PACKAGES 
  2. PRODUCT_COPY_FILES
  3. PRODUCT_PROPERTY_OVERRIDES
  4. PRODUCT_DEFAULT_PROPERTY_OVERRIDES
  5. PRODUCT_CHARACTERISTICS
  6. PRODUCT_AAPT_CONFIG
  7. PRODUCT_AAPT_PREF_CONFIG
  8. PRODUCT_TAGS

2.4 NDK의 Android.mk 와 Application.mk 

상위 Android.mk에 LOCAL_MODULE_TAGS에 

여러 *.mk에 있다고 하니, 여러군데를 일단 분석을 해보았고, 기본이 되는
device/hardkernel/odroidx2/device.mk 이 부분 기반을 보니,


NDK와 Android.mk와 Application.mk 

  • Build 구조이해 
구글문서로 new Device를 추가하는 법인데, 쉽게 빌드구조를 이해가능 

Android Song 빌드구조 

Android USB