Build build_image and build_super_image as modules.
Bug: 63866463
Test: TreeHugger
Test: `atest releasetools_test`
Test: `atest releasetools_py3_test`
Change-Id: I2059a4ced709d1b2ee331a9aaaa5ca30db4ebf6b
diff --git a/core/Makefile b/core/Makefile
index 488237f..e6bf05a 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1373,12 +1373,9 @@
endif
INTERNAL_USERIMAGES_DEPS := \
- $(BLK_ALLOC_TO_BASE_FS) \
- $(E2FSCK) \
+ $(BUILD_IMAGE) \
$(MKE2FS_CONF) \
- $(MKEXTUSERIMG) \
- $(SIMG2IMG) \
- $(TUNE2FS)
+ $(MKEXTUSERIMG)
ifeq ($(TARGET_USERIMAGES_USE_F2FS),true)
INTERNAL_USERIMAGES_DEPS += $(MKF2FSUSERIMG)
@@ -2298,16 +2295,17 @@
$(call generate-image-prop-dictionary, $(systemimage_intermediates)/system_image_info.txt,system, \
skip_fsck=true)
PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
- build/make/tools/releasetools/build_image.py \
- $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) $(TARGET_OUT) \
- || ( mkdir -p $${DIST_DIR}; cp $(INSTALLED_FILES_FILE) $${DIST_DIR}/installed-files-rescued.txt; \
- exit 1 )
+ $(BUILD_IMAGE) \
+ $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) $(TARGET_OUT) \
+ || ( mkdir -p $${DIST_DIR}; \
+ cp $(INSTALLED_FILES_FILE) $${DIST_DIR}/installed-files-rescued.txt; \
+ exit 1 )
endef
ifeq ($(BOARD_AVB_ENABLE),true)
$(BUILT_SYSTEMIMAGE): $(BOARD_AVB_SYSTEM_KEY_PATH)
endif
-$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE) $(BUILD_IMAGE_SRCS)
+$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE)
$(call build-systemimage-target,$@)
INSTALLED_SYSTEMIMAGE_TARGET := $(PRODUCT_OUT)/system.img
@@ -2488,17 +2486,17 @@
@mkdir -p $(userdataimage_intermediates) && rm -rf $(userdataimage_intermediates)/userdata_image_info.txt
$(call generate-image-prop-dictionary, $(userdataimage_intermediates)/userdata_image_info.txt,userdata,skip_fsck=true)
PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
- build/make/tools/releasetools/build_image.py \
- $(TARGET_OUT_DATA) $(userdataimage_intermediates)/userdata_image_info.txt $(INSTALLED_USERDATAIMAGE_TARGET) $(TARGET_OUT)
- $(hide) $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE))
+ $(BUILD_IMAGE) \
+ $(TARGET_OUT_DATA) $(userdataimage_intermediates)/userdata_image_info.txt \
+ $(INSTALLED_USERDATAIMAGE_TARGET) $(TARGET_OUT)
+ $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE))
endef
# We just build this directly to the install location.
INSTALLED_USERDATAIMAGE_TARGET := $(BUILT_USERDATAIMAGE_TARGET)
INSTALLED_USERDATAIMAGE_TARGET_DEPS := \
$(INTERNAL_USERIMAGES_DEPS) \
- $(INTERNAL_USERDATAIMAGE_FILES) \
- $(BUILD_IMAGE_SRCS)
+ $(INTERNAL_USERDATAIMAGE_FILES)
$(INSTALLED_USERDATAIMAGE_TARGET): $(INSTALLED_USERDATAIMAGE_TARGET_DEPS)
$(build-userdataimage-target)
@@ -2571,14 +2569,15 @@
@mkdir -p $(cacheimage_intermediates) && rm -rf $(cacheimage_intermediates)/cache_image_info.txt
$(call generate-image-prop-dictionary, $(cacheimage_intermediates)/cache_image_info.txt,cache,skip_fsck=true)
PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
- build/make/tools/releasetools/build_image.py \
- $(TARGET_OUT_CACHE) $(cacheimage_intermediates)/cache_image_info.txt $(INSTALLED_CACHEIMAGE_TARGET) $(TARGET_OUT)
- $(hide) $(call assert-max-image-size,$(INSTALLED_CACHEIMAGE_TARGET),$(BOARD_CACHEIMAGE_PARTITION_SIZE))
+ $(BUILD_IMAGE) \
+ $(TARGET_OUT_CACHE) $(cacheimage_intermediates)/cache_image_info.txt \
+ $(INSTALLED_CACHEIMAGE_TARGET) $(TARGET_OUT)
+ $(call assert-max-image-size,$(INSTALLED_CACHEIMAGE_TARGET),$(BOARD_CACHEIMAGE_PARTITION_SIZE))
endef
# We just build this directly to the install location.
INSTALLED_CACHEIMAGE_TARGET := $(BUILT_CACHEIMAGE_TARGET)
-$(INSTALLED_CACHEIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_CACHEIMAGE_FILES) $(BUILD_IMAGE_SRCS)
+$(INSTALLED_CACHEIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_CACHEIMAGE_FILES)
$(build-cacheimage-target)
.PHONY: cacheimage-nodeps
@@ -2642,9 +2641,10 @@
@mkdir -p $(systemotherimage_intermediates) && rm -rf $(systemotherimage_intermediates)/system_other_image_info.txt
$(call generate-image-prop-dictionary, $(systemotherimage_intermediates)/system_other_image_info.txt,system,skip_fsck=true)
PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
- build/make/tools/releasetools/build_image.py \
- $(TARGET_OUT_SYSTEM_OTHER) $(systemotherimage_intermediates)/system_other_image_info.txt $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) $(TARGET_OUT)
- $(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
+ $(BUILD_IMAGE) \
+ $(TARGET_OUT_SYSTEM_OTHER) $(systemotherimage_intermediates)/system_other_image_info.txt \
+ $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) $(TARGET_OUT)
+ $(call assert-max-image-size,$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
endef
# We just build this directly to the install location.
@@ -2795,9 +2795,10 @@
@mkdir -p $(vendorimage_intermediates) && rm -rf $(vendorimage_intermediates)/vendor_image_info.txt
$(call generate-image-prop-dictionary, $(vendorimage_intermediates)/vendor_image_info.txt,vendor,skip_fsck=true)
PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
- build/make/tools/releasetools/build_image.py \
- $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt $(INSTALLED_VENDORIMAGE_TARGET) $(TARGET_OUT)
- $(hide) $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET),$(BOARD_VENDORIMAGE_PARTITION_SIZE))
+ $(BUILD_IMAGE) \
+ $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt \
+ $(INSTALLED_VENDORIMAGE_TARGET) $(TARGET_OUT)
+ $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET),$(BOARD_VENDORIMAGE_PARTITION_SIZE))
endef
# We just build this directly to the install location.
@@ -2805,7 +2806,10 @@
ifdef BUILT_VENDOR_MANIFEST
$(INSTALLED_VENDORIMAGE_TARGET): $(BUILT_ASSEMBLED_VENDOR_MANIFEST)
endif
-$(INSTALLED_VENDORIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_VENDORIMAGE_FILES) $(INSTALLED_FILES_FILE_VENDOR) $(BUILD_IMAGE_SRCS)
+$(INSTALLED_VENDORIMAGE_TARGET): \
+ $(INTERNAL_USERIMAGES_DEPS) \
+ $(INTERNAL_VENDORIMAGE_FILES) \
+ $(INSTALLED_FILES_FILE_VENDOR)
$(build-vendorimage-target)
.PHONY: vendorimage-nodeps vnod
@@ -2850,14 +2854,18 @@
@mkdir -p $(productimage_intermediates) && rm -rf $(productimage_intermediates)/product_image_info.txt
$(call generate-image-prop-dictionary, $(productimage_intermediates)/product_image_info.txt,product,skip_fsck=true)
PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
- ./build/tools/releasetools/build_image.py \
- $(TARGET_OUT_PRODUCT) $(productimage_intermediates)/product_image_info.txt $(INSTALLED_PRODUCTIMAGE_TARGET) $(TARGET_OUT)
- $(hide) $(call assert-max-image-size,$(INSTALLED_PRODUCTIMAGE_TARGET),$(BOARD_PRODUCTIMAGE_PARTITION_SIZE))
+ $(BUILD_IMAGE) \
+ $(TARGET_OUT_PRODUCT) $(productimage_intermediates)/product_image_info.txt \
+ $(INSTALLED_PRODUCTIMAGE_TARGET) $(TARGET_OUT)
+ $(call assert-max-image-size,$(INSTALLED_PRODUCTIMAGE_TARGET),$(BOARD_PRODUCTIMAGE_PARTITION_SIZE))
endef
# We just build this directly to the install location.
INSTALLED_PRODUCTIMAGE_TARGET := $(BUILT_PRODUCTIMAGE_TARGET)
-$(INSTALLED_PRODUCTIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_PRODUCTIMAGE_FILES) $(INSTALLED_FILES_FILE_PRODUCT) $(BUILD_IMAGE_SRCS)
+$(INSTALLED_PRODUCTIMAGE_TARGET): \
+ $(INTERNAL_USERIMAGES_DEPS) \
+ $(INTERNAL_PRODUCTIMAGE_FILES) \
+ $(INSTALLED_FILES_FILE_PRODUCT)
$(build-productimage-target)
.PHONY: productimage-nodeps pnod
@@ -2948,14 +2956,20 @@
@mkdir -p $(system_extimage_intermediates) && rm -rf $(system_extimage_intermediates)/system_ext_image_info.txt
$(call generate-image-prop-dictionary, $(system_extimage_intermediates)/system_ext_image_info.txt,system_ext, skip_fsck=true)
PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
- ./build/tools/releasetools/build_image.py \
- $(TARGET_OUT_SYSTEM_EXT) $(system_extimage_intermediates)/system_ext_image_info.txt $(INSTALLED_SYSTEM_EXTIMAGE_TARGET) $(TARGET_OUT)
- $(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEM_EXTIMAGE_TARGET),$(BOARD_SYSTEM_EXTIMAGE_PARTITION_SIZE))
+ $(BUILD_IMAGE) \
+ $(TARGET_OUT_SYSTEM_EXT) \
+ $(system_extimage_intermediates)/system_ext_image_info.txt \
+ $(INSTALLED_SYSTEM_EXTIMAGE_TARGET) \
+ $(TARGET_OUT)
+ $(call assert-max-image-size,$(INSTALLED_PRODUCT_SERVICESIMAGE_TARGET),$(BOARD_PRODUCT_SERVICESIMAGE_PARTITION_SIZE))
endef
# We just build this directly to the install location.
INSTALLED_SYSTEM_EXTIMAGE_TARGET := $(BUILT_SYSTEM_EXTIMAGE_TARGET)
-$(INSTALLED_SYSTEM_EXTIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_SYSTEM_EXTIMAGE_FILES) $(INSTALLED_FILES_FILE_SYSTEM_EXT) $(BUILD_IMAGE_SRCS)
+$(INSTALLED_SYSTEM_EXTIMAGE_TARGET): \
+ $(INTERNAL_USERIMAGES_DEPS) \
+ $(INTERNAL_SYSTEM_EXTIMAGE_FILES) \
+ $(INSTALLED_FILES_FILE_SYSTEM_EXT)
$(build-system_extimage-target)
.PHONY: systemextimage-nodeps senod
@@ -2999,14 +3013,18 @@
@mkdir -p $(odmimage_intermediates) && rm -rf $(odmimage_intermediates)/odm_image_info.txt
$(call generate-userimage-prop-dictionary, $(odmimage_intermediates)/odm_image_info.txt, skip_fsck=true)
PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
- ./build/tools/releasetools/build_image.py \
- $(TARGET_OUT_ODM) $(odmimage_intermediates)/odm_image_info.txt $(INSTALLED_ODMIMAGE_TARGET) $(TARGET_OUT)
- $(hide) $(call assert-max-image-size,$(INSTALLED_ODMIMAGE_TARGET),$(BOARD_ODMIMAGE_PARTITION_SIZE))
+ $(BUILD_IMAGE) \
+ $(TARGET_OUT_ODM) $(odmimage_intermediates)/odm_image_info.txt \
+ $(INSTALLED_ODMIMAGE_TARGET) $(TARGET_OUT)
+ $(call assert-max-image-size,$(INSTALLED_ODMIMAGE_TARGET),$(BOARD_ODMIMAGE_PARTITION_SIZE))
endef
# We just build this directly to the install location.
INSTALLED_ODMIMAGE_TARGET := $(BUILT_ODMIMAGE_TARGET)
-$(INSTALLED_ODMIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_ODMIMAGE_FILES) $(INSTALLED_FILES_FILE_ODM) $(BUILD_IMAGE_SRCS)
+$(INSTALLED_ODMIMAGE_TARGET): \
+ $(INTERNAL_USERIMAGES_DEPS) \
+ $(INTERNAL_ODMIMAGE_FILES) \
+ $(INSTALLED_FILES_FILE_ODM)
$(build-odmimage-target)
.PHONY: odmimage-nodeps onod
@@ -3580,6 +3598,8 @@
brillo_update_payload \
brotli \
bsdiff \
+ build_image \
+ build_super_image \
build_verity_metadata \
build_verity_tree \
care_map_generator \
diff --git a/core/config.mk b/core/config.mk
index 5016ff2..730e029 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -579,7 +579,6 @@
FS_GET_STATS := $(HOST_OUT_EXECUTABLES)/fs_get_stats$(HOST_EXECUTABLE_SUFFIX)
MKEXTUSERIMG := $(HOST_OUT_EXECUTABLES)/mkuserimg_mke2fs
MKE2FS_CONF := system/extras/ext4_utils/mke2fs.conf
-BLK_ALLOC_TO_BASE_FS := $(HOST_OUT_EXECUTABLES)/blk_alloc_to_base_fs$(HOST_EXECUTABLE_SUFFIX)
MKSQUASHFSUSERIMG := $(HOST_OUT_EXECUTABLES)/mksquashfsimage.sh
MKF2FSUSERIMG := $(HOST_OUT_EXECUTABLES)/mkf2fsuserimg.sh
SIMG2IMG := $(HOST_OUT_EXECUTABLES)/simg2img$(HOST_EXECUTABLE_SUFFIX)
@@ -591,7 +590,8 @@
CHECK_LINK_TYPE := build/make/tools/check_link_type.py
CHECK_ELF_FILE := build/make/tools/check_elf_file.py
LPMAKE := $(HOST_OUT_EXECUTABLES)/lpmake$(HOST_EXECUTABLE_SUFFIX)
-BUILD_SUPER_IMAGE := build/make/tools/releasetools/build_super_image.py
+BUILD_IMAGE := $(HOST_OUT_EXECUTABLES)/build_image$(HOST_EXECUTABLE_SUFFIX)
+BUILD_SUPER_IMAGE := $(HOST_OUT_EXECUTABLES)/build_super_image$(HOST_EXECUTABLE_SUFFIX)
PROGUARD_HOME := external/proguard
PROGUARD := $(PROGUARD_HOME)/bin/proguard.sh
diff --git a/core/tasks/oem_image.mk b/core/tasks/oem_image.mk
index 489feeb..a847b9d 100644
--- a/core/tasks/oem_image.mk
+++ b/core/tasks/oem_image.mk
@@ -34,10 +34,10 @@
@mkdir -p $(TARGET_OUT_OEM)
@mkdir -p $(oemimage_intermediates) && rm -rf $(oemimage_intermediates)/oem_image_info.txt
$(call generate-image-prop-dictionary, $(oemimage_intermediates)/oem_image_info.txt,oem,skip_fsck=true)
- $(hide) PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
- build/make/tools/releasetools/build_image.py \
- $(TARGET_OUT_OEM) $(oemimage_intermediates)/oem_image_info.txt $@ $(TARGET_OUT)
- $(hide) $(call assert-max-image-size,$@,$(BOARD_OEMIMAGE_PARTITION_SIZE))
+ PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
+ $(BUILD_IMAGE) \
+ $(TARGET_OUT_OEM) $(oemimage_intermediates)/oem_image_info.txt $@ $(TARGET_OUT)
+ $(call assert-max-image-size,$@,$(BOARD_OEMIMAGE_PARTITION_SIZE))
.PHONY: oem_image
oem_image : $(INSTALLED_OEMIMAGE_TARGET)
diff --git a/core/tasks/tools/build_custom_image.mk b/core/tasks/tools/build_custom_image.mk
index b0d1a0c..4721591 100644
--- a/core/tasks/tools/build_custom_image.mk
+++ b/core/tasks/tools/build_custom_image.mk
@@ -152,8 +152,8 @@
$(if $(filter oem,$(PRIVATE_MOUNT_POINT)), \
$(hide) echo "oem.buildnumber=$(BUILD_NUMBER_FROM_FILE)" >> $(PRIVATE_STAGING_DIR)/oem.prop)
$(hide) PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
- build/make/tools/releasetools/build_image.py \
- $(PRIVATE_STAGING_DIR) $(PRIVATE_INTERMEDIATES)/image_info.txt $@ $(TARGET_OUT)
+ $(BUILD_IMAGE) \
+ $(PRIVATE_STAGING_DIR) $(PRIVATE_INTERMEDIATES)/image_info.txt $@ $(TARGET_OUT)
my_installed_custom_image := $(PRODUCT_OUT)/$(notdir $(my_built_custom_image))
$(my_installed_custom_image) : $(my_built_custom_image)
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 1bb1603..d4c4673 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -13,56 +13,124 @@
// limitations under the License.
python_defaults {
- name: "releasetools_defaults",
+ name: "releasetools_library_defaults",
version: {
py2: {
enabled: true,
- embedded_launcher: false,
},
py3: {
enabled: true,
- embedded_launcher: false,
},
},
}
python_library_host {
- name: "releasetools_lib",
- defaults: ["releasetools_defaults"],
+ name: "releasetools_common",
+ defaults: ["releasetools_library_defaults"],
srcs: [
- "add_img_to_target_files.py",
- "apex_utils.py",
"blockimgdiff.py",
- "build_image.py",
- "build_super_image.py",
- "check_ota_package_signature.py",
- "check_target_files_signatures.py",
"common.py",
- "edify_generator.py",
- "img_from_target_files.py",
"images.py",
- "make_recovery_patch.py",
- "merge_target_files.py",
- "ota_from_target_files.py",
- "ota_package_parser.py",
"rangelib.py",
- "sign_apex.py",
- "sign_target_files_apks.py",
"sparse_img.py",
- "target_files_diff.py",
- "validate_target_files.py",
+ ],
+ // Only the tools that are referenced directly are listed as required modules. For example,
+ // `avbtool` is not here, as the script always uses the one from info_dict['avb_avbtool'].
+ required: [
+ "aapt",
+ "boot_signer",
+ "brotli",
+ "bsdiff",
+ "imgdiff",
+ "minigzip",
+ "mkbootfs",
+ ],
+}
+
+python_library_host {
+ name: "releasetools_verity_utils",
+ defaults: ["releasetools_library_defaults"],
+ srcs: [
"verity_utils.py",
],
+ required: [
+ "append2simg",
+ "build_verity_metadata",
+ "build_verity_tree",
+ "fec",
+ ],
+}
+
+python_defaults {
+ name: "releasetools_binary_defaults",
+ version: {
+ py2: {
+ enabled: true,
+ embedded_launcher: true,
+ },
+ py3: {
+ enabled: false,
+ embedded_launcher: false,
+ },
+ },
+}
+
+python_binary_host {
+ name: "build_image",
+ defaults: ["releasetools_binary_defaults"],
+ srcs: [
+ "build_image.py",
+ ],
+ main: "build_image.py",
+ libs: [
+ "releasetools_common",
+ "releasetools_verity_utils",
+ ],
+ required: [
+ "blk_alloc_to_base_fs",
+ "e2fsck",
+ "simg2img",
+ "tune2fs",
+ ],
+}
+
+python_binary_host {
+ name: "build_super_image",
+ defaults: ["releasetools_binary_defaults"],
+ srcs: [
+ "build_super_image.py",
+ ],
+ main: "build_super_image.py",
+ libs: [
+ "releasetools_common",
+ ],
}
python_defaults {
name: "releasetools_test_defaults",
- defaults: ["releasetools_defaults"],
srcs: [
+ "add_img_to_target_files.py",
+ "apex_utils.py",
+ "build_image.py",
+ "build_super_image.py",
+ "check_ota_package_signature.py",
+ "check_target_files_signatures.py",
+ "edify_generator.py",
+ "img_from_target_files.py",
+ "make_recovery_patch.py",
+ "merge_target_files.py",
+ "ota_from_target_files.py",
+ "ota_package_parser.py",
+ "sign_apex.py",
+ "sign_target_files_apks.py",
+ "target_files_diff.py",
+ "validate_target_files.py",
+
"test_*.py",
],
libs: [
- "releasetools_lib",
+ "releasetools_common",
+ "releasetools_verity_utils",
],
data: [
"testdata/*",
@@ -79,6 +147,9 @@
version: {
py2: {
enabled: true,
+ // When using embedded launcher, atest will try (but may fail) to load libc++.so from
+ // host, because the test executable won't be able to find the needed libs via its
+ // runpath.
embedded_launcher: false,
},
py3: {
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index ee05dd5..af508fe 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -18,7 +18,7 @@
Builds output_image from the given input_directory, properties_file,
and writes the image to target_output_directory.
-Usage: build_image.py input_directory properties_file output_image \\
+Usage: build_image input_directory properties_file output_image \\
target_output_directory
"""