cleanbuild.mk revision eadaa954ceadcf44fa7cc2b1327f786defa29c35
1# Copyright (C) 2007 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# 15 16# Don't bother with the cleanspecs if you are running mm/mmm 17ifeq ($(ONE_SHOT_MAKEFILE)$(dont_bother),) 18 19INTERNAL_CLEAN_STEPS := 20 21# Builds up a list of clean steps. Creates a unique 22# id for each step by taking makefile path, INTERNAL_CLEAN_BUILD_VERSION 23# and appending an increasing number of '@' characters. 24# 25# $(1): shell command to run 26# $(2): indicate to not use makefile path as part of step id if not empty. 27# $(2) should only be used in build/core/cleanspec.mk: just for compatibility. 28define _add-clean-step 29 $(if $(strip $(INTERNAL_CLEAN_BUILD_VERSION)),, \ 30 $(error INTERNAL_CLEAN_BUILD_VERSION not set)) 31 $(eval _acs_makefile_prefix := $(lastword $(MAKEFILE_LIST))) 32 $(eval _acs_makefile_prefix := $(subst /,_,$(_acs_makefile_prefix))) 33 $(eval _acs_makefile_prefix := $(subst .,-,$(_acs_makefile_prefix))) 34 $(eval _acs_makefile_prefix := $(_acs_makefile_prefix)_acs) 35 $(if $($(_acs_makefile_prefix)),,\ 36 $(eval $(_acs_makefile_prefix) := $(INTERNAL_CLEAN_BUILD_VERSION))) 37 $(eval $(_acs_makefile_prefix) := $($(_acs_makefile_prefix))@) 38 $(if $(strip $(2)),$(eval _acs_id := $($(_acs_makefile_prefix))),\ 39 $(eval _acs_id := $(_acs_makefile_prefix)$($(_acs_makefile_prefix)))) 40 $(eval INTERNAL_CLEAN_STEPS += $(_acs_id)) 41 $(eval INTERNAL_CLEAN_STEP.$(_acs_id) := $(1)) 42 $(eval _acs_id :=) 43 $(eval _acs_makefile_prefix :=) 44endef 45define add-clean-step 46$(eval # for build/core/cleanspec.mk, dont use makefile path as part of step id) \ 47$(if $(filter %/cleanspec.mk,$(lastword $(MAKEFILE_LIST))),\ 48 $(eval $(call _add-clean-step,$(1),true)),\ 49 $(eval $(call _add-clean-step,$(1)))) 50endef 51 52# Defines INTERNAL_CLEAN_BUILD_VERSION and the individual clean steps. 53# cleanspec.mk is outside of the core directory so that more people 54# can have permission to touch it. 55include $(BUILD_SYSTEM)/cleanspec.mk 56INTERNAL_CLEAN_BUILD_VERSION := $(strip $(INTERNAL_CLEAN_BUILD_VERSION)) 57INTERNAL_CLEAN_STEPS := $(strip $(INTERNAL_CLEAN_STEPS)) 58 59# If the clean_steps.mk file is missing (usually after a clean build) 60# then we won't do anything. 61CURRENT_CLEAN_BUILD_VERSION := $(INTERNAL_CLEAN_BUILD_VERSION) 62CURRENT_CLEAN_STEPS := $(INTERNAL_CLEAN_STEPS) 63 64# Read the current state from the file, if present. 65# Will set CURRENT_CLEAN_BUILD_VERSION and CURRENT_CLEAN_STEPS. 66# 67clean_steps_file := $(PRODUCT_OUT)/clean_steps.mk 68-include $(clean_steps_file) 69 70ifneq ($(CURRENT_CLEAN_BUILD_VERSION),$(INTERNAL_CLEAN_BUILD_VERSION)) 71 # The major clean version is out-of-date. Do a full clean, and 72 # don't even bother with the clean steps. 73 $(info *** A clean build is required because of a recent change.) 74 $(shell rm -rf $(OUT_DIR)) 75 $(info *** Done with the cleaning, now starting the real build.) 76else 77 # The major clean version is correct. Find the list of clean steps 78 # that we need to execute to get up-to-date. 79 steps := \ 80 $(filter-out $(CURRENT_CLEAN_STEPS),$(INTERNAL_CLEAN_STEPS)) 81 $(foreach step,$(steps), \ 82 $(info Clean step: $(INTERNAL_CLEAN_STEP.$(step))) \ 83 $(shell $(INTERNAL_CLEAN_STEP.$(step))) \ 84 ) 85 86 # Rewrite the clean step for the second arch. 87 ifdef TARGET_2ND_ARCH 88 # $(1): the clean step cmd 89 # $(2): the prefix to search for 90 # $(3): the prefix to replace with 91 define -cs-rewrite-cleanstep 92 $(if $(filter $(2)/%,$(1)),\ 93 $(eval _crs_new_cmd := $(patsubst $(2)/%,$(3)/%,$(1)))\ 94 $(info Clean step: $(_crs_new_cmd))\ 95 $(shell $(_crs_new_cmd))) 96 endef 97 $(foreach step,$(steps), \ 98 $(call -cs-rewrite-cleanstep,$(INTERNAL_CLEAN_STEP.$(step)),$(TARGET_OUT_INTERMEDIATES),$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES))\ 99 $(call -cs-rewrite-cleanstep,$(INTERNAL_CLEAN_STEP.$(step)),$(TARGET_OUT_SHARED_LIBRARIES),$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES))\ 100 $(call -cs-rewrite-cleanstep,$(INTERNAL_CLEAN_STEP.$(step)),$(TARGET_OUT_VENDOR_SHARED_LIBRARIES),$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_SHARED_LIBRARIES))\ 101 $(call -cs-rewrite-cleanstep,$(INTERNAL_CLEAN_STEP.$(step)),$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES),$(TARGET_OUT_INTERMEDIATES))\ 102 $(call -cs-rewrite-cleanstep,$(INTERNAL_CLEAN_STEP.$(step)),$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES),$(TARGET_OUT_SHARED_LIBRARIES))\ 103 $(call -cs-rewrite-cleanstep,$(INTERNAL_CLEAN_STEP.$(step)),$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_SHARED_LIBRARIES),$(TARGET_OUT_VENDOR_SHARED_LIBRARIES))\ 104 ) 105 endif 106 _crs_new_cmd := 107 steps := 108endif 109 110# Write the new state to the file. 111# 112rewrite_clean_steps_file := 113ifneq ($(CURRENT_CLEAN_BUILD_VERSION)-$(CURRENT_CLEAN_STEPS),$(INTERNAL_CLEAN_BUILD_VERSION)-$(INTERNAL_CLEAN_STEPS)) 114rewrite_clean_steps_file := true 115endif 116ifeq ($(wildcard $(clean_steps_file)),) 117# This is the first build. 118rewrite_clean_steps_file := true 119endif 120ifeq ($(rewrite_clean_steps_file),true) 121$(shell \ 122 mkdir -p $(dir $(clean_steps_file)) && \ 123 echo "CURRENT_CLEAN_BUILD_VERSION := $(INTERNAL_CLEAN_BUILD_VERSION)" > \ 124 $(clean_steps_file) ;\ 125 echo "CURRENT_CLEAN_STEPS := $(INTERNAL_CLEAN_STEPS)" >> \ 126 $(clean_steps_file) \ 127 ) 128endif 129 130CURRENT_CLEAN_BUILD_VERSION := 131CURRENT_CLEAN_STEPS := 132clean_steps_file := 133rewrite_clean_steps_file := 134INTERNAL_CLEAN_STEPS := 135INTERNAL_CLEAN_BUILD_VERSION := 136 137endif # if not ONE_SHOT_MAKEFILE dont_bother 138 139# Since products and build variants (unfortunately) share the same 140# PRODUCT_OUT staging directory, things can get out of sync if different 141# build configurations are built in the same tree. The following logic 142# will notice when the configuration has changed and remove the files 143# necessary to keep things consistent. 144 145previous_build_config_file := $(PRODUCT_OUT)/previous_build_config.mk 146 147# A change in the list of aapt configs warrants an installclean, too. 148aapt_config_list := $(strip $(PRODUCT_AAPT_CONFIG) $(PRODUCT_AAPT_PREF_CONFIG)) 149 150current_build_config := \ 151 $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)-{$(aapt_config_list)} 152current_sanitize_target := $(strip $(SANITIZE_TARGET)) 153ifeq (,$(current_sanitize_target)) 154 current_sanitize_target := false 155endif 156aapt_config_list := 157force_installclean := false 158force_objclean := false 159 160# Read the current state from the file, if present. 161# Will set PREVIOUS_BUILD_CONFIG. 162# 163PREVIOUS_BUILD_CONFIG := 164PREVIOUS_SANITIZE_TARGET := 165-include $(previous_build_config_file) 166PREVIOUS_BUILD_CONFIG := $(strip $(PREVIOUS_BUILD_CONFIG)) 167PREVIOUS_SANITIZE_TARGET := $(strip $(PREVIOUS_SANITIZE_TARGET)) 168 169ifdef PREVIOUS_BUILD_CONFIG 170 ifneq "$(current_build_config)" "$(PREVIOUS_BUILD_CONFIG)" 171 $(info *** Build configuration changed: "$(PREVIOUS_BUILD_CONFIG)" -> "$(current_build_config)") 172 ifneq ($(DISABLE_AUTO_INSTALLCLEAN),true) 173 force_installclean := true 174 else 175 $(info DISABLE_AUTO_INSTALLCLEAN is set; skipping auto-clean. Your tree may be in an inconsistent state.) 176 endif 177 endif 178endif # else, this is the first build, so no need to clean. 179 180ifdef PREVIOUS_SANITIZE_TARGET 181 ifneq "$(current_sanitize_target)" "$(PREVIOUS_SANITIZE_TARGET)" 182 $(info *** SANITIZE_TARGET changed: "$(PREVIOUS_SANITIZE_TARGET)" -> "$(current_sanitize_target)") 183 force_objclean := true 184 endif 185endif # else, this is the first build, so no need to clean. 186 187# Write the new state to the file. 188# 189ifneq ($(PREVIOUS_BUILD_CONFIG)-$(PREVIOUS_SANITIZE_TARGET),$(current_build_config)-$(current_sanitize_target)) 190$(shell \ 191 mkdir -p $(dir $(previous_build_config_file)) && \ 192 echo "PREVIOUS_BUILD_CONFIG := $(current_build_config)" > \ 193 $(previous_build_config_file) && \ 194 echo "PREVIOUS_SANITIZE_TARGET := $(current_sanitize_target)" >> \ 195 $(previous_build_config_file) \ 196 ) 197endif 198PREVIOUS_BUILD_CONFIG := 199PREVIOUS_SANITIZE_TARGET := 200previous_build_config_file := 201current_build_config := 202 203# 204# installclean logic 205# 206 207# The files/dirs to delete during an installclean. This includes the 208# non-common APPS directory, which may contain the wrong resources. 209# 210# Deletes all of the files that change between different build types, 211# like "make user" vs. "make sdk". This lets you work with different 212# build types without having to do a full clean each time. E.g.: 213# 214# $ make -j8 all 215# $ make installclean 216# $ make -j8 user 217# $ make installclean 218# $ make -j8 sdk 219# 220installclean_files := \ 221 $(HOST_OUT)/obj/NOTICE_FILES \ 222 $(HOST_OUT)/sdk \ 223 $(PRODUCT_OUT)/*.img \ 224 $(PRODUCT_OUT)/*.ini \ 225 $(PRODUCT_OUT)/*.txt \ 226 $(PRODUCT_OUT)/*.xlb \ 227 $(PRODUCT_OUT)/*.zip \ 228 $(PRODUCT_OUT)/kernel \ 229 $(PRODUCT_OUT)/data \ 230 $(PRODUCT_OUT)/skin \ 231 $(PRODUCT_OUT)/obj/APPS \ 232 $(PRODUCT_OUT)/obj/NOTICE_FILES \ 233 $(PRODUCT_OUT)/obj/PACKAGING \ 234 $(PRODUCT_OUT)/recovery \ 235 $(PRODUCT_OUT)/root \ 236 $(PRODUCT_OUT)/system \ 237 $(PRODUCT_OUT)/vendor \ 238 $(PRODUCT_OUT)/oem \ 239 $(PRODUCT_OUT)/dex_bootjars \ 240 $(PRODUCT_OUT)/obj/JAVA_LIBRARIES \ 241 $(PRODUCT_OUT)/obj/FAKE \ 242 $(PRODUCT_OUT)/obj/EXECUTABLES/adbd_intermediates \ 243 $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libfs_mgr_intermediates \ 244 $(PRODUCT_OUT)/obj/EXECUTABLES/init_intermediates \ 245 $(PRODUCT_OUT)/obj/ETC/mac_permissions.xml_intermediates \ 246 $(PRODUCT_OUT)/obj/ETC/sepolicy_intermediates \ 247 $(PRODUCT_OUT)/obj/ETC/init.environ.rc_intermediates 248 249# The files/dirs to delete during a dataclean, which removes any files 250# in the staging and emulator data partitions. 251dataclean_files := \ 252 $(PRODUCT_OUT)/data/* \ 253 $(PRODUCT_OUT)/data-qemu/* \ 254 $(PRODUCT_OUT)/userdata-qemu.img 255 256# The files/dirs to delete during an objclean, which removes any files 257# in the staging and emulator data partitions. 258objclean_files := \ 259 $(TARGET_OUT_INTERMEDIATES) \ 260 $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES) 261 262# make sure *_OUT is set so that we won't result in deleting random parts 263# of the filesystem. 264ifneq (2,$(words $(HOST_OUT) $(PRODUCT_OUT))) 265 $(error both HOST_OUT and PRODUCT_OUT should be set at this point.) 266endif 267 268# Define the rules for commandline invocation. 269.PHONY: dataclean 270dataclean: FILES := $(dataclean_files) 271dataclean: 272 $(hide) rm -rf $(FILES) 273 @echo "Deleted emulator userdata images." 274 275.PHONY: installclean 276installclean: FILES := $(installclean_files) 277installclean: dataclean 278 $(hide) rm -rf $(FILES) 279 @echo "Deleted images and staging directories." 280 281.PHONY: objclean 282objclean: FILES := $(objclean_files) 283objclean: 284 $(hide) rm -rf $(FILES) 285 @echo "Deleted images and staging directories." 286 287ifeq "$(force_installclean)" "true" 288 $(info *** Forcing "make installclean"...) 289 $(info *** rm -rf $(dataclean_files) $(installclean_files)) 290 $(shell rm -rf $(dataclean_files) $(installclean_files)) 291 $(info *** Done with the cleaning, now starting the real build.) 292endif 293force_installclean := 294 295ifeq "$(force_objclean)" "true" 296 $(info *** Forcing cleanup of intermediate files...) 297 $(info *** rm -rf $(objclean_files)) 298 $(shell rm -rf $(objclean_files)) 299 $(info *** Done with the cleaning, now starting the real build.) 300endif 301force_objclean := 302 303########################################################### 304# Clean build tools when swithcing between prebuilt host tools (such as in 305# apps_only build) and tools built from source (platform build). 306previous_prebuilt_tools_config_file := $(HOST_OUT)/previous_prebuilt_tools_config.mk 307ifneq (,$(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK))) 308current_prebuilt_tools := true 309else 310current_prebuilt_tools := false 311endif 312PREVIOUS_PREBUILT_TOOLS := 313-include $(previous_prebuilt_tools_config_file) 314force_tools_clean := 315ifdef PREVIOUS_PREBUILT_TOOLS 316ifneq ($(PREVIOUS_PREBUILT_TOOLS),$(current_prebuilt_tools)) 317force_tools_clean := true 318endif 319endif # else, this is the first build, so no need to clean. 320 321# Write the new state to the file. 322ifneq ($(PREVIOUS_PREBUILT_TOOLS),$(current_prebuilt_tools)) 323$(shell \ 324 mkdir -p $(dir $(previous_prebuilt_tools_config_file)) && \ 325 echo "PREVIOUS_PREBUILT_TOOLS:=$(current_prebuilt_tools)" > \ 326 $(previous_prebuilt_tools_config_file)) 327endif 328 329ifeq ($(force_tools_clean),true) 330# For this list of prebuilt tools, see prebuilts/sdk/tools/Android.mk. 331tools_clean_files := \ 332 $(HOST_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/signapk_intermediates \ 333 $(HOST_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/dx_intermediates \ 334 $(HOST_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/shrinkedAndroid_intermediates \ 335 $(HOST_OUT)/obj*/EXECUTABLES/aapt_intermediates \ 336 $(HOST_OUT)/obj*/EXECUTABLES/aidl_intermediates \ 337 $(HOST_OUT)/obj*/EXECUTABLES/zipalign_intermediates \ 338 $(HOST_OUT)/obj*/lib/libc++$(HOST_SHLIB_SUFFIX) \ 339 340$(info *** build type changed, clean host tools...) 341$(info *** rm -rf $(tools_clean_files)) 342$(shell rm -rf $(tools_clean_files)) 343endif 344 345########################################################### 346 347.PHONY: clean-jack-files 348clean-jack-files: clean-dex-files 349 $(hide) find $(OUT_DIR) -name "*.jack" | xargs rm -f 350 $(hide) find $(OUT_DIR) -type d -name "jack" | xargs rm -rf 351 @echo "All jack files have been removed." 352 353.PHONY: clean-dex-files 354clean-dex-files: 355 $(hide) find $(OUT_DIR) -name "*.dex" ! -path "*/jack-incremental/*" | xargs rm -f 356 $(hide) for i in `find $(OUT_DIR) -name "*.jar" -o -name "*.apk"` ; do ((unzip -l $$i 2> /dev/null | \ 357 grep -q "\.dex$$" && rm -f $$i) || continue ) ; done 358 @echo "All dex files and archives containing dex files have been removed." 359 360.PHONY: clean-jack-incremental 361clean-jack-incremental: 362 $(hide) find $(OUT_DIR) -name "jack-incremental" -type d | xargs rm -rf 363 @echo "All jack incremental dirs have been removed." 364