OSDN Git Service

Support to configure and build multiple custom images.
authorYing Wang <wangying@google.com>
Fri, 13 Mar 2015 01:30:39 +0000 (18:30 -0700)
committerYing Wang <wangying@google.com>
Sat, 14 Mar 2015 00:06:54 +0000 (00:06 +0000)
Build additional images requested by the product makefile.
This script gives the ability to build multiple additional images and
you can configure what modules/files to include in each image.
1. Define PRODUCT_CUSTOM_IMAGE_MAKEFILES in your product makefile.
   PRODUCT_CUSTOM_IMAGE_MAKEFILES is a list of makefiles.
   Each makefile configures an image.
   For image configuration makefile foo/bar/xyz.mk, the built image
   file name
   will be xyz.img. So make sure they won't conflict.
2. In each image's configuration makefile, you can define variables:
  - CUSTOM_IMAGE_MOUNT_POINT, the mount point, such as "oem", "odm"
    etc.
  - CUSTOM_IMAGE_PARTITION_SIZE
  - CUSTOM_IMAGE_FILE_SYSTEM_TYPE
  - CUSTOM_IMAGE_DICT_FILE, a text file defining a dictionary
    accepted by BuildImage() in tools/releasetools/build_image.py.
  - CUSTOM_IMAGE_MODULES, a list of module names you want to include
    in the image; Not only the module itself will be installed to proper
    path in the image, you can also piggyback additional files/directories
    with the module's LOCAL_PICKUP_FILES.
  - CUSTOM_IMAGE_COPY_FILES, a list of "<src>:<dest>" to be copied to
    the image. <dest> is relativ to the root of the image.

To build all those images, run "make custom_images".

Bug: 19609718
Change-Id: Ic73587e08503a251be27797c7b00329716051927
(cherry picked from commit 5fcf1094f9cf4d57c2598237f99621f254130d71)

core/base_rules.mk
core/clear_vars.mk
core/envsetup.mk
core/tasks/build_custom_images.mk [new file with mode: 0644]
core/tasks/tools/build_custom_image.mk [new file with mode: 0644]
tools/releasetools/build_image.py

index ec3b59f..dfed3ea 100644 (file)
@@ -116,6 +116,8 @@ ifeq ($(my_module_path),)
     partition_tag := _VENDOR
   else ifeq (true,$(LOCAL_OEM_MODULE))
     partition_tag := _OEM
+  else ifeq (true,$(LOCAL_ODM_MODULE))
+    partition_tag := _ODM
   else
     # The definition of should-install-to-system will be different depending
     # on which goal (e.g., sdk or just droid) is being built.
index bf81ebf..d5a5f03 100644 (file)
@@ -131,6 +131,7 @@ LOCAL_PROTO_JAVA_OUTPUT_PARAMS:=
 LOCAL_NO_CRT:=
 LOCAL_PROPRIETARY_MODULE:=
 LOCAL_OEM_MODULE:=
+LOCAL_ODM_MODULE:=
 LOCAL_PRIVILEGED_MODULE:=
 LOCAL_MODULE_OWNER:=
 LOCAL_CTS_TEST_PACKAGE:=
index 124a91b..ad78be3 100644 (file)
@@ -120,6 +120,7 @@ endif
 TARGET_COPY_OUT_SYSTEM := system
 TARGET_COPY_OUT_DATA := data
 TARGET_COPY_OUT_OEM := oem
+TARGET_COPY_OUT_ODM := odm
 TARGET_COPY_OUT_ROOT := root
 TARGET_COPY_OUT_RECOVERY := recovery
 ###########################################
@@ -343,7 +344,7 @@ $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_APPS := $(TARGET_OUT_VENDOR_APPS)
 
 TARGET_OUT_OEM := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_OEM)
 TARGET_OUT_OEM_EXECUTABLES := $(TARGET_OUT_OEM)/bin
-ifneq ($(filter %64,$(TARGET_ARCH)),)
+ifeq ($(TARGET_IS_64_BIT),true)
 TARGET_OUT_OEM_SHARED_LIBRARIES := $(TARGET_OUT_OEM)/lib64
 else
 TARGET_OUT_OEM_SHARED_LIBRARIES := $(TARGET_OUT_OEM)/lib
@@ -357,6 +358,20 @@ $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_EXECUTABLES := $(TARGET_OUT_OEM_EXEC
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_SHARED_LIBRARIES := $(TARGET_OUT_OEM)/lib
 $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_OEM_APPS := $(TARGET_OUT_OEM_APPS)
 
+TARGET_OUT_ODM := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ODM)
+TARGET_OUT_ODM_EXECUTABLES := $(TARGET_OUT_ODM)/bin
+ifeq ($(TARGET_IS_64_BIT),true)
+TARGET_OUT_ODM_SHARED_LIBRARIES := $(TARGET_OUT_ODM)/lib64
+else
+TARGET_OUT_ODM_SHARED_LIBRARIES := $(TARGET_OUT_ODM)/lib
+endif
+TARGET_OUT_ODM_APPS := $(TARGET_OUT_ODM)/app
+TARGET_OUT_ODM_ETC := $(TARGET_OUT_ODM)/etc
+
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_EXECUTABLES := $(TARGET_OUT_ODM_EXECUTABLES)
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_SHARED_LIBRARIES := $(TARGET_OUT_ODM)/lib
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_APPS := $(TARGET_OUT_ODM_APPS)
+
 TARGET_OUT_UNSTRIPPED := $(PRODUCT_OUT)/symbols
 TARGET_OUT_EXECUTABLES_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/system/bin
 TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/system/lib
diff --git a/core/tasks/build_custom_images.mk b/core/tasks/build_custom_images.mk
new file mode 100644 (file)
index 0000000..263b81a
--- /dev/null
@@ -0,0 +1,58 @@
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Build additional images requested by the product makefile.
+# This script gives the ability to build multiple additional images and you can
+# configure what modules/files to include in each image.
+# 1. Define PRODUCT_CUSTOM_IMAGE_MAKEFILES in your product makefile.
+#    PRODUCT_CUSTOM_IMAGE_MAKEFILES is a list of makefiles.
+#    Each makefile configures an image.
+#    For image configuration makefile foo/bar/xyz.mk, the built image file name
+#    will be xyz.img. So make sure they won't conflict.
+# 2. In each image's configuration makefile, you can define variables:
+#   - CUSTOM_IMAGE_MOUNT_POINT, the mount point, such as "oem", "odm" etc.
+#   - CUSTOM_IMAGE_PARTITION_SIZE
+#   - CUSTOM_IMAGE_FILE_SYSTEM_TYPE
+#   - CUSTOM_IMAGE_DICT_FILE, a text file defines a dictionary accepted by
+#     BuildImage() in tools/releasetools/build_image.py.
+#   - CUSTOM_IMAGE_MODULES, a list of module names you want to include in
+#     the image; Not only the module itself will be installed to proper path in
+#     the image, you can also piggyback additional files/directories with the
+#     module's LOCAL_PICKUP_FILES.
+#   - CUSTOM_IMAGE_COPY_FILES, a list of "<src>:<dest>" to be copied to the
+#     image. <dest> is relativ to the root of the image.
+#
+# To build all those images, run "make custom_images".
+
+ifneq ($(filter $(MAKECMDGOALS),custom_images),)
+
+.PHONY: custom_images
+
+custom_image_parameter_variables := \
+  CUSTOM_IMAGE_MOUNT_POINT \
+  CUSTOM_IMAGE_PARTITION_SIZE \
+  CUSTOM_IMAGE_FILE_SYSTEM_TYPE \
+  CUSTOM_IMAGE_DICT_FILE \
+  CUSTOM_IMAGE_MODULES \
+  CUSTOM_IMAGE_COPY_FILES \
+
+# We don't expect product makefile to inherit/override PRODUCT_CUSTOM_IMAGE_MAKEFILES,
+# so we don't put it in the _product_var_list.
+$(foreach mk, $(PRODUCT_CUSTOM_IMAGE_MAKEFILES),\
+  $(eval my_custom_imag_makefile := $(mk))\
+  $(eval include $(BUILD_SYSTEM)/tasks/tools/build_custom_image.mk))
+
+endif
diff --git a/core/tasks/tools/build_custom_image.mk b/core/tasks/tools/build_custom_image.mk
new file mode 100644 (file)
index 0000000..fa9cda2
--- /dev/null
@@ -0,0 +1,105 @@
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+# Define rule to build one custom image.
+# Input variables: my_custom_imag_makefile
+
+$(call clear-var-list, $(custom_image_parameter_variables))
+
+include $(my_custom_imag_makefile)
+
+my_custom_image_name := $(basename $(notdir $(my_custom_imag_makefile)))
+
+intermediates := $(call intermediates-dir-for,PACKAGING,$(my_custom_image_name))
+my_built_custom_image := $(intermediates)/$(my_custom_image_name).img
+my_staging_dir := $(intermediates)/$(my_custom_image_name)
+
+# Collect CUSTOM_IMAGE_MODULES's installd files and their PICKUP_FILES.
+my_built_modules :=
+my_copy_pairs :=
+my_pickup_files :=
+
+$(foreach m,$(CUSTOM_IMAGE_MODULES),\
+  $(eval _pickup_files := $(strip $(ALL_MODULES.$(m).PICKUP_FILES)\
+    $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).PICKUP_FILES)))\
+  $(eval _built_files := $(strip $(ALL_MODULES.$(m).BUILT_INSTALLED)\
+    $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).BUILT_INSTALLED)))\
+  $(if $(_pickup_files)$(_built_files),,\
+    $(warning Unknown installed file for module '$(m)'))\
+  $(eval my_pickup_files += $(_pickup_files))\
+  $(foreach i, $(_built_files),\
+    $(eval bui_ins := $(subst :,$(space),$(i)))\
+    $(eval ins := $(word 2,$(bui_ins)))\
+    $(if $(filter $(TARGET_OUT_ROOT)/%,$(ins)),\
+      $(eval bui := $(word 1,$(bui_ins)))\
+      $(eval my_built_modules += $(bui))\
+      $(eval my_copy_dest := $(patsubst $(PRODUCT_OUT)/%,%,$(ins)))\
+      $(eval my_copy_dest := $(subst /,$(space),$(my_copy_dest)))\
+      $(eval my_copy_dest := $(wordlist 2,999,$(my_copy_dest)))\
+      $(eval my_copy_dest := $(subst $(space),/,$(my_copy_dest)))\
+      $(eval my_copy_pairs += $(bui):$(my_staging_dir)/$(my_copy_dest)))\
+  ))
+
+# Collect CUSTOM_IMAGE_COPY_FILES.
+my_image_copy_files :=
+$(foreach f,$(CUSTOM_IMAGE_COPY_FILES),\
+  $(eval pair := $(subst :,$(space),$(f)))\
+  $(eval src := $(word 1,$(pair)))\
+  $(eval my_image_copy_files += $(src))\
+  $(eval my_copy_pairs += $(src):$(my_staging_dir)/$(word 2,$(pair))))
+
+$(my_built_custom_image): PRIVATE_INTERMEDIATES := $(intermediates)
+$(my_built_custom_image): PRIVATE_MOUNT_POINT := $(CUSTOM_IMAGE_MOUNT_POINT)
+$(my_built_custom_image): PRIVATE_PARTITION_SIZE := $(CUSTOM_IMAGE_PARTITION_SIZE)
+$(my_built_custom_image): PRIVATE_FILE_SYSTEM_TYPE := $(CUSTOM_IMAGE_FILE_SYSTEM_TYPE)
+$(my_built_custom_image): PRIVATE_STAGING_DIR := $(my_staging_dir)
+$(my_built_custom_image): PRIVATE_COPY_PAIRS := $(my_copy_pairs)
+$(my_built_custom_image): PRIVATE_PICKUP_FILES := $(my_pickup_files)
+$(my_built_custom_image): PRIVATE_DICT_FILE := $(CUSTOM_IMAGE_DICT_FILE)
+$(my_built_custom_image): $(INTERNAL_USERIMAGES_DEPS) $(my_built_modules) $(my_image_copy_files) \
+  $(CUSTOM_IMAGE_DICT_FILE)
+       @echo "Build image $@"
+       $(hide) rm -rf $(PRIVATE_INTERMEDIATES) && mkdir -p $(PRIVATE_INTERMEDIATES)
+       $(hide) rm -rf $(PRIVATE_STAGING_DIR) && mkdir -p $(PRIVATE_STAGING_DIR)
+       # Copy all the files.
+       $(hide) $(foreach p,$(PRIVATE_COPY_PAIRS),\
+                 $(eval pair := $(subst :,$(space),$(p)))\
+                 mkdir -p $(dir $(word 2,$(pair)));\
+                 cp -Rf $(word 1,$(pair)) $(word 2,$(pair));)
+       $(if $($(PRIVATE_PICKUP_FILES)),$(hide) cp -Rf $(PRIVATE_PICKUP_FILES) $(PRIVATE_STAGING_DIR))
+       # Generate the dict.
+       $(hide) echo "# For all accepted properties, see BuildImage() in tools/releasetools/build_image.py" > $(PRIVATE_INTERMEDIATES)/image_info.txt
+       $(hide) echo "mount_point=$(PRIVATE_MOUNT_POINT)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt
+       $(hide) echo "fs_type=$(PRIVATE_FILE_SYSTEM_TYPE)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt
+       $(hide) echo "partition_size=$(PRIVATE_PARTITION_SIZE)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt
+       $(if $(PRIVATE_DICT_FILE),\
+         $(hide) echo "# Properties from $(PRIVATE_DICT_FILE)" >> $(PRIVATE_INTERMEDIATES)/image_info.txt;\
+         cat $(PRIVATE_DICT_FILE) >> $(PRIVATE_INTERMEDIATES)/image_info.txt)
+       # Generate the image.
+       $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
+         ./build/tools/releasetools/build_image.py \
+         $(PRIVATE_STAGING_DIR) $(PRIVATE_INTERMEDIATES)/image_info.txt $@
+
+my_installed_custom_image := $(PRODUCT_OUT)/$(notdir $(my_built_custom_image))
+$(my_installed_custom_image) : $(my_built_custom_image)
+       $(call copy-file-to-new-target-with-cp)
+
+.PHONY: $(my_custom_image_name)
+custom_images $(my_custom_image_name) : $(my_installed_custom_image)
+
+# Archive the built image.
+$(call dist-for-goals, $(my_custom_image_name) custom_images,$(my_installed_custom_image))
index 302aa0c..24d5665 100755 (executable)
@@ -368,23 +368,28 @@ def main(argv):
   out_file = argv[2]
 
   glob_dict = LoadGlobalDict(glob_dict_file)
-  image_filename = os.path.basename(out_file)
-  mount_point = ""
-  if image_filename == "system.img":
-    mount_point = "system"
-  elif image_filename == "userdata.img":
-    mount_point = "data"
-  elif image_filename == "cache.img":
-    mount_point = "cache"
-  elif image_filename == "vendor.img":
-    mount_point = "vendor"
-  elif image_filename == "oem.img":
-    mount_point = "oem"
+  if "mount_point" in glob_dict:
+    # The caller knows the mount point and provides a dictionay needed by BuildImage().
+    image_properties = glob_dict
   else:
-    print >> sys.stderr, "error: unknown image file name ", image_filename
-    exit(1)
+    image_filename = os.path.basename(out_file)
+    mount_point = ""
+    if image_filename == "system.img":
+      mount_point = "system"
+    elif image_filename == "userdata.img":
+      mount_point = "data"
+    elif image_filename == "cache.img":
+      mount_point = "cache"
+    elif image_filename == "vendor.img":
+      mount_point = "vendor"
+    elif image_filename == "oem.img":
+      mount_point = "oem"
+    else:
+      print >> sys.stderr, "error: unknown image file name ", image_filename
+      exit(1)
+
+    image_properties = ImagePropFromGlobalDict(glob_dict, mount_point)
 
-  image_properties = ImagePropFromGlobalDict(glob_dict, mount_point)
   if not BuildImage(in_dir, image_properties, out_file):
     print >> sys.stderr, "error: failed to build %s from %s" % (out_file, in_dir)
     exit(1)