전체 과정을 간략히 설명하면,
TARGET_BUILD_VARIANT에 따라서 System Property와 설치될 모듈을
결정합니다. 그 과정을 Makefile을 따라가면서 확인해
보겠습니다.
시작은 open_src폴더 아래 Makefile에서 build/core/main.mk로 이동합니다.
/Makefile
### DO NOT EDIT THIS FILE ### include build/core/main.mk ### DO NOT EDIT THIS FILE ### |
아래 build/core/main.mk를 보면 환경변수
TARGET_BUILD_VARIANT에 따라서 System Property를 다르게 설정하고
있습니다.
Part 1 : /build/core/main.mk
##
user/userdebug ## user_variant := $(filter
userdebug user,$(TARGET_BUILD_VARIANT)) enable_target_debugging
:= true ifneq
(,$(user_variant)) # Target is secure in user builds. ADDITIONAL_DEFAULT_PROPERTIES +=
ro.secure=1 tags_to_install := user ifeq ($(user_variant),userdebug) # Pick up some extra useful tools tags_to_install += debug else # Disable debugging in plain user builds. enable_target_debugging := endif # TODO: Always set WITH_DEXPREOPT (for user
builds) once it works on OSX. # Also, remove the corresponding block in
config/product_config.make. ifeq ($(HOST_OS)-$(WITH_DEXPREOPT_buildbot),linux-true) WITH_DEXPREOPT := true endif # Disallow mock locations by default for
user builds ADDITIONAL_DEFAULT_PROPERTIES +=
ro.allow.mock.location=0 else
# !user_variant # Turn on checkjni for non-user builds. ADDITIONAL_BUILD_PROPERTIES +=
ro.kernel.android.checkjni=1 # Set device insecure for non-user builds. ADDITIONAL_DEFAULT_PROPERTIES +=
ro.secure=0 # Allow mock locations by default for non
user builds ADDITIONAL_DEFAULT_PROPERTIES +=
ro.allow.mock.location=1 endif
# !user_variant ifeq
(true,$(strip $(enable_target_debugging))) # Target is more debuggable and adbd is on
by default ADDITIONAL_DEFAULT_PROPERTIES +=
ro.debuggable=1 persist.service.adb.enable=1 # Include the debugging/testing OTA keys in
this build. INCLUDE_TEST_OTA_KEYS := true else
# !enable_target_debugging # Target is less debuggable and adbd is off
by default ADDITIONAL_DEFAULT_PROPERTIES +=
ro.debuggable=0 persist.service.adb.enable=0 endif
# !enable_target_debugging ##
eng ## ifeq
($(TARGET_BUILD_VARIANT),eng) tags_to_install
:= user debug eng # Don't require the setup wizard on eng
builds #eng모드에서
ro.setupwizard.mode property를 뺍니다. ADDITIONAL_BUILD_PROPERTIES := $(filter-out
ro.setupwizard.mode=%,\ $(call collapse-pairs,
$(ADDITIONAL_BUILD_PROPERTIES))) endif |
TARGET_BUILD_VARIANT에 따른 동작은 아래와 같습니다. Android.mk의 정의된 LOCAL_MODULE_TAGS를 정의하지 않은 모듈은 기본이 user 태그입니다. 따라서 이전에 eng로 설정되어 있는 모듈들이 설치되지 않은 이유는
명시적으로 eng태그를 설정해 주었기 때문입니다.
TARGET_BUILD_VARIANT |
Actions |
eng |
- Installs
modules tagged with: eng, debug, user, and/or development. - Installs
non-APK modules that have no tags specified. - Installs
APKs according to the product definition files, in addition to tagged APKs. - ro.secure=0 - ro.debuggable=1 - ro.kernel.android.checkjni=1 - adb is
enabled by default. |
user |
- Installs
modules tagged with user. - Installs
non-APK modules that have no tags specified. - Installs
APKs according to the product definition files; tags are ignored for APK
modules. - ro.secure=1 - ro.debuggable=0 - adb is
disabled by default. |
userdebug |
The same
as user, except: - Also
installs modules tagged with debug. -
ro.debuggable=1 - adb is
enabled by default. |
빌드시 build/tools/findleaves.sh를 사용해서 각 폴더의 첫번째 Android.mk파일을 모두 찾아서 Makefile에 추가합니다. 하위 폴더에 Android.mk파일이 존재하더라도 상위 폴더에 Android.mk가 존재하면 상위 폴더에 있는 Android.mk까지만
찾습니다.
그리고 현재 Product설정파일의
TARGET_DEVICE의 BoardConfig.mk를 포함시킵니다.
Part 2 : /build/core/main.mk
#
Can't use first-makefiles-under here because #
--mindepth=2 makes the prunes not work. subdir_makefiles += \ $(shell build/tools/findleaves.sh
--prune="./out" $(subdirs) Android.mk) #
Boards may be defined under $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE) #
or under vendor/*/$(TARGET_DEVICE).
Search in both places, but #
make sure only one exists. #
Real boards should always be associated with an OEM vendor. board_config_mk
:= \ $(strip $(wildcard \
$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \
vendor/*/$(TARGET_DEVICE)/BoardConfig.mk \ )) ifeq
($(board_config_mk),) $(error No config file found for
TARGET_DEVICE $(TARGET_DEVICE)) endif ifneq
($(words $(board_config_mk)),1) $(error Multiple board config files for
TARGET_DEVICE $(TARGET_DEVICE): $(board_config_mk)) endif include $(board_config_mk) TARGET_DEVICE_DIR
:= $(patsubst %/,%,$(dir $(board_config_mk))) board_config_mk
:= #
Clean up/verify variables defined by the board config file. TARGET_BOOTLOADER_BOARD_NAME
:= $(strip $(TARGET_BOOTLOADER_BOARD_NAME)) # #
Include all of the makefiles in the system # ifneq
($(ONE_SHOT_MAKEFILE),) #
We've probably been invoked by the "mm" shell function #
with a subdirectory's makefile. include
$(ONE_SHOT_MAKEFILE) #
Change CUSTOM_MODULES to include only modules that were #
defined by this makefile; this will install all of those #
modules as a side-effect. Do this
after including ONE_SHOT_MAKEFILE #
so that the modules will be installed in the same place they #
would have been with a normal make. CUSTOM_MODULES
:= $(sort $(call get-tagged-modules,$(ALL_MODULE_TAGS),)) FULL_BUILD
:= INTERNAL_DEFAULT_DOCS_TARGETS
:= #
Stub out the notice targets, which probably aren't defined #
when using ONE_SHOT_MAKEFILE. NOTICE-HOST-%:
; NOTICE-TARGET-%:
; else include $(subdir_makefiles) endif # ------------------------------------------------------------------- # All module makefiles have
been included at this point. #
------------------------------------------------------------------- |
build/tools/findleaves.sh 동작 예제
$find hardware –name “*.mk” hardware/libhardware/Android.mk hardware/libhardware/modules/overlay/Android.mk hardware/libhardware_legacy/Android.mk hardware/libhardware_legacy/flashlight/Android.mk hardware/libhardware_legacy/gps/Android.mk hardware/libhardware_legacy/led/Android.mk hardware/libhardware_legacy/mount/Android.mk hardware/libhardware_legacy/power/Android.mk hardware/libhardware_legacy/qemu/Android.mk hardware/libhardware_legacy/qemu_tracing/Android.mk hardware/libhardware_legacy/tests/gpstest/Android.mk hardware/libhardware_legacy/uevent/Android.mk hardware/libhardware_legacy/vibrator/Android.mk hardware/libhardware_legacy/wifi/Android.mk hardware/ril/libril/Android.mk hardware/ril/rild/Android.mk hardware/ril/gpstest/Android.mk hardware/ril/libsecril-client/Android.mk hardware/ril/rilclient-test/Android.mk hardware/ril/secril_multi/Android.mk hardware/modules/sensors/Android.mk hardware/msm7k/Android.mk hardware/msm7k/libaudio/Android.mk hardware/msm7k/libcamera/Android.mk hardware/msm7k/libcopybit/Android.mk hardware/msm7k/librpc/Android.mk hardware/msm7k/yuv420sp2rgb/Android.mk $ ./build/tools/findleaves.sh
hardware Android.mk hardware/libhardware/Android.mk
=> 폴더구조의 첫번째 Android.mk만 포함됨 hardware/libhardware_legacy/Android.mk hardware/modules/sensors/Android.mk hardware/msm7k/Android.mk hardware/ril/gpstest/Android.mk hardware/ril/libril/Android.mk hardware/ril/libsecril-client/Android.mk hardware/ril/rilclient-test/Android.mk hardware/ril/rild/Android.mk hardware/ril/secril_multi/Android.mk |
hardware/msm7k/Android.mk 파일에서 아래와 같이
하위의 Android.mk파일을 상황에 따라서 include를
하여 필요한 모듈만 컴파일하여 추가시킬 때 사용할 수 있습니다. (이것을 사용해서 Samsung의 Open Source쪽 변경 소스 관리를 할 수 있을
것으로 보입니다. )
ifneq ($(filter capella7200,
surf, $(TARGET_DEVICE)), ) include $(all-subdir-makefiles) endif |
설치될 모듈들을 선택하고, LOCAL_OVERRIDES_PACKAGES로 선택된 Package를
항목에서 삭제합니다.
Part 3 : build/core/main.mk
#
------------------------------------------------------------------- #
Figure out our module sets. #
Of the modules defined by the component makefiles, #
determine what we actually want to build. #
If a module has the "restricted" tag on it, it #
poisons the rest of the tags and shouldn't appear #
on any list. Default_MODULES
:= $(sort $(ALL_DEFAULT_INSTALLED_MODULES) \
$(ALL_BUILT_MODULES) \ $(CUSTOM_MODULES)) #
TODO: Remove the 3 places in the tree that use #
ALL_DEFAULT_INSTALLED_MODULES and get rid of it from this list. ifdef
FULL_BUILD # The base list of modules to build for
this product is specified # by the appropriate product definition
file, which was included # by product_config.make. user_PACKAGES := $(call
module-installed-files, \ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES)) ifeq (0,1) $(info user packages for $(TARGET_DEVICE)
($(INTERNAL_PRODUCT)):) $(foreach p,$(user_PACKAGES),$(info
: $(p))) $(error done) endif else # We're not doing a full build, and are
probably only including # a subset of the module makefiles. Don't try to build any modules # requested by the product, because we
probably won't have rules # to build them. user_PACKAGES := endif #
Use tags to get the non-APPS user modules.
Use the product #
definition files to get the APPS user modules. user_MODULES := $(sort $(call
get-tagged-modules,user,_class@APPS restricted)) user_MODULES := $(user_MODULES)
$(user_PACKAGES) eng_MODULES := $(sort $(call
get-tagged-modules,eng,restricted)) debug_MODULES := $(sort $(call
get-tagged-modules,debug,restricted)) tests_MODULES := $(sort $(call
get-tagged-modules,tests,restricted)) ifeq
($(strip $(tags_to_install)),) $(error
ASSERTION FAILED: tags_to_install should not be empty) endif modules_to_install := $(sort
$(Default_MODULES) \ $(foreach
tag,$(tags_to_install),$($(tag)_MODULES))) # Some packages may override
others using LOCAL_OVERRIDES_PACKAGES. # Filter out (do not install)
any overridden packages. overridden_packages
:= $(call get-package-overrides,$(modules_to_install)) ifdef
overridden_packages # old_modules_to_install :=
$(modules_to_install) modules_to_install := \ $(filter-out $(foreach
p,$(overridden_packages),$(p) %/$(p).apk), \ $(modules_to_install)) endif |
추가로Android의 모든 Application은 고유한 Key를 사용해서 Signning을 수행해야 합니다. 어떤 Key로 Signning을
할지를 결정은 LOCAL_CERTIFICATE에 기술합니다.
packages/apps/Camera/Android.mk
LOCAL_PATH:=
$(call my-dir) include
$(CLEAR_VARS) LOCAL_MODULE_TAGS
:= user LOCAL_SRC_FILES
:= $(call all-java-files-under, src) LOCAL_PACKAGE_NAME
:= Camera LOCAL_CERTIFICATE := media #LOCAL_CERTIFICATE :=
vendor/samsung/products/security/media
=> 명시적으로 선택가능 LOCAL_STATIC_JAVA_LIBRARIES
:= googlelogin-client #include
$(BUILD_PACKAGE) #
Use the following include to make our test apk. #include
$(call all-makefiles-under,$(LOCAL_PATH)) |
package.mk파일을 보시면 LOCAL_CERTIFICATE가 설정되지 않으면 testkey가
사용되며, 관련 private와 certificate는
/build/target/product/security/폴더에 있는 key값을 사용합니다.
mkkey.sh => key값을
생성하기 위한 명령어, Samsung Android폰 개발시 고유한 key를 생성해서 출시해야함. media.pk8 media.x509.pem platform.pk8 platform.x509.pem shared.pk8 shared.x509.pem testkey.pk8 testkey.x509.pem |
/build/core/package.mk
#
Pick a key to sign the package with.
If this package hasn't specified #
an explicit certificate, use the default. #
Secure release builds will have their packages signed after the fact, #
so it's ok for these private keys to be in the clear. ifeq ($(LOCAL_CERTIFICATE),) LOCAL_CERTIFICATE := testkey endif # If this is not an absolute
certificate, assign it to a generic one. ifeq ($(dir $(strip
$(LOCAL_CERTIFICATE))),./) LOCAL_CERTIFICATE :=
$(SRC_TARGET_DIR)/product/security/$(LOCAL_CERTIFICATE) endif private_key :=
$(LOCAL_CERTIFICATE).pk8 certificate :=
$(LOCAL_CERTIFICATE).x509.pem $(LOCAL_BUILT_MODULE):
$(private_key) $(certificate) $(SIGNAPK_JAR) $(LOCAL_BUILT_MODULE):
PRIVATE_PRIVATE_KEY := $(private_key) $(LOCAL_BUILT_MODULE):
PRIVATE_CERTIFICATE := $(certificate) PACKAGES.$(LOCAL_PACKAGE_NAME).PRIVATE_KEY
:= $(private_key) PACKAGES.$(LOCAL_PACKAGE_NAME).CERTIFICATE
:= $(certificate) #
Define the rule to build the actual package. $(LOCAL_BUILT_MODULE):
$(AAPT) | $(ZIPALIGN) $(LOCAL_BUILT_MODULE):
PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries) $(LOCAL_BUILT_MODULE):
$(all_res_assets) $(jni_shared_libraries) $(full_android_manifest) @echo "target Package:
$(PRIVATE_MODULE) ($@)" $(create-empty-package) $(add-assets-to-package) ifneq
($(jni_shared_libraries),) $(add-jni-shared-libs-to-package) endif ifneq
($(full_classes_jar),) $(add-dex-to-package) endif $(sign-package) @# Alignment must happen after all other
zip operations. $(align-package) #
Save information about this package PACKAGES.$(LOCAL_PACKAGE_NAME).OVERRIDES
:= $(strip $(LOCAL_OVERRIDES_PACKAGES)) PACKAGES.$(LOCAL_PACKAGE_NAME).RESOURCE_FILES
:= $(all_resources) PACKAGES
:= $(PACKAGES) $(LOCAL_PACKAGE_NAME) |