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 17 ifeq ($(ONE_SHOT_MAKEFILE)$(dont_bother),) 18 19 INTERNAL_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. 28 define _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 :=) 44 endef 45 define 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)))) 50 endef 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. 55 include $(BUILD_SYSTEM)/cleanspec.mk 56 INTERNAL_CLEAN_BUILD_VERSION := $(strip $(INTERNAL_CLEAN_BUILD_VERSION)) 57 INTERNAL_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. 61 CURRENT_CLEAN_BUILD_VERSION := $(INTERNAL_CLEAN_BUILD_VERSION) 62 CURRENT_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 # 67 clean_steps_file := $(PRODUCT_OUT)/clean_steps.mk 68 -include $(clean_steps_file) 69 70 ifneq ($(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.) 76 else 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 := 108 endif 109 110 # Write the new state to the file. 111 # 112 rewrite_clean_steps_file := 113 ifneq ($(CURRENT_CLEAN_BUILD_VERSION)-$(CURRENT_CLEAN_STEPS),$(INTERNAL_CLEAN_BUILD_VERSION)-$(INTERNAL_CLEAN_STEPS)) 114 rewrite_clean_steps_file := true 115 endif 116 ifeq ($(wildcard $(clean_steps_file)),) 117 # This is the first build. 118 rewrite_clean_steps_file := true 119 endif 120 ifeq ($(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 := $(wordlist 1,500,$(INTERNAL_CLEAN_STEPS))" >> $(clean_steps_file) \ 126 ) 127 define -cs-write-clean-steps-if-arg1-not-empty 128 $(if $(1),$(shell echo "CURRENT_CLEAN_STEPS += $(1)" >> $(clean_steps_file))) 129 endef 130 $(call -cs-write-clean-steps-if-arg1-not-empty,$(wordlist 501,1000,$(INTERNAL_CLEAN_STEPS))) 131 $(call -cs-write-clean-steps-if-arg1-not-empty,$(wordlist 1001,1500,$(INTERNAL_CLEAN_STEPS))) 132 $(call -cs-write-clean-steps-if-arg1-not-empty,$(wordlist 1501,2000,$(INTERNAL_CLEAN_STEPS))) 133 $(call -cs-write-clean-steps-if-arg1-not-empty,$(wordlist 2001,2500,$(INTERNAL_CLEAN_STEPS))) 134 $(call -cs-write-clean-steps-if-arg1-not-empty,$(wordlist 2501,3000,$(INTERNAL_CLEAN_STEPS))) 135 $(call -cs-write-clean-steps-if-arg1-not-empty,$(wordlist 3001,99999,$(INTERNAL_CLEAN_STEPS))) 136 endif 137 138 CURRENT_CLEAN_BUILD_VERSION := 139 CURRENT_CLEAN_STEPS := 140 clean_steps_file := 141 rewrite_clean_steps_file := 142 INTERNAL_CLEAN_STEPS := 143 INTERNAL_CLEAN_BUILD_VERSION := 144 145 endif # if not ONE_SHOT_MAKEFILE dont_bother 146 147 # Since products and build variants (unfortunately) share the same 148 # PRODUCT_OUT staging directory, things can get out of sync if different 149 # build configurations are built in the same tree. The following logic 150 # will notice when the configuration has changed and remove the files 151 # necessary to keep things consistent. 152 153 previous_build_config_file := $(PRODUCT_OUT)/previous_build_config.mk 154 current_build_config_file := $(PRODUCT_OUT)/current_build_config.mk 155 156 current_build_config := \ 157 $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT) 158 force_installclean := false 159 160 # Read the current state from the file, if present. 161 # Will set PREVIOUS_BUILD_CONFIG. 162 # 163 PREVIOUS_BUILD_CONFIG := 164 -include $(previous_build_config_file) 165 PREVIOUS_BUILD_CONFIG := $(strip $(PREVIOUS_BUILD_CONFIG)) 166 167 ifdef PREVIOUS_BUILD_CONFIG 168 ifneq ($(current_build_config),$(PREVIOUS_BUILD_CONFIG)) 169 $(info *** Build configuration changed: "$(PREVIOUS_BUILD_CONFIG)" -> "$(current_build_config)") 170 ifneq ($(DISABLE_AUTO_INSTALLCLEAN),true) 171 force_installclean := true 172 else 173 $(info DISABLE_AUTO_INSTALLCLEAN is set; skipping auto-clean. Your tree may be in an inconsistent state.) 174 endif 175 endif 176 endif # else, this is the first build, so no need to clean. 177 178 # Write the new state to the file. 179 # 180 $(shell \ 181 mkdir -p $(dir $(current_build_config_file)) && \ 182 echo "PREVIOUS_BUILD_CONFIG := $(current_build_config)" > \ 183 $(current_build_config_file) \ 184 ) 185 $(shell cmp $(current_build_config_file) $(previous_build_config_file) > /dev/null 2>&1 || \ 186 mv -f $(current_build_config_file) $(previous_build_config_file)) 187 188 PREVIOUS_BUILD_CONFIG := 189 previous_build_config_file := 190 current_build_config_file := 191 current_build_config := 192 193 # 194 # installclean logic 195 # 196 197 # The files/dirs to delete during an installclean. 198 # 199 # Deletes all of the installed files -- the intent is to remove files 200 # that may no longer be installed, either because the user previously 201 # installed them, or they were previously installed by default but no 202 # longer are. 203 # 204 # This is faster than a full clean, since we're not deleting the 205 # intermediates. Instead of recompiling, we can just copy the results. 206 # 207 # Host bin, frameworks, and lib* are intentionally omitted, since 208 # otherwise we'd have to rebuild any generated files created with those 209 # tools. 210 installclean_files := \ 211 $(HOST_OUT)/obj/NOTICE_FILES \ 212 $(HOST_OUT)/obj/PACKAGING \ 213 $(HOST_OUT)/coverage \ 214 $(HOST_OUT)/cts \ 215 $(HOST_OUT)/nativetest* \ 216 $(HOST_OUT)/sdk \ 217 $(HOST_OUT)/sdk_addon \ 218 $(HOST_OUT)/testcases \ 219 $(HOST_OUT)/vts \ 220 $(HOST_CROSS_OUT)/bin \ 221 $(HOST_CROSS_OUT)/coverage \ 222 $(HOST_CROSS_OUT)/lib* \ 223 $(HOST_CROSS_OUT)/nativetest* \ 224 $(PRODUCT_OUT)/*.img \ 225 $(PRODUCT_OUT)/*.ini \ 226 $(PRODUCT_OUT)/*.txt \ 227 $(PRODUCT_OUT)/*.xlb \ 228 $(PRODUCT_OUT)/*.zip \ 229 $(PRODUCT_OUT)/kernel \ 230 $(PRODUCT_OUT)/data \ 231 $(PRODUCT_OUT)/skin \ 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)/system_other \ 238 $(PRODUCT_OUT)/vendor \ 239 $(PRODUCT_OUT)/oem \ 240 $(PRODUCT_OUT)/obj/FAKE \ 241 $(PRODUCT_OUT)/breakpad \ 242 $(PRODUCT_OUT)/cache \ 243 $(PRODUCT_OUT)/coverage \ 244 $(PRODUCT_OUT)/installer \ 245 $(PRODUCT_OUT)/odm \ 246 $(PRODUCT_OUT)/sysloader \ 247 $(PRODUCT_OUT)/testcases \ 248 249 # The files/dirs to delete during a dataclean, which removes any files 250 # in the staging and emulator data partitions. 251 dataclean_files := \ 252 $(PRODUCT_OUT)/data/* \ 253 $(PRODUCT_OUT)/data-qemu/* \ 254 $(PRODUCT_OUT)/userdata-qemu.img 255 256 # make sure *_OUT is set so that we won't result in deleting random parts 257 # of the filesystem. 258 ifneq (2,$(words $(HOST_OUT) $(PRODUCT_OUT))) 259 $(error both HOST_OUT and PRODUCT_OUT should be set at this point.) 260 endif 261 262 # Define the rules for commandline invocation. 263 .PHONY: dataclean 264 dataclean: FILES := $(dataclean_files) 265 dataclean: 266 $(hide) rm -rf $(FILES) 267 @echo "Deleted emulator userdata images." 268 269 .PHONY: installclean 270 installclean: FILES := $(installclean_files) 271 installclean: dataclean 272 $(hide) rm -rf $(FILES) 273 @echo "Deleted images and staging directories." 274 275 ifeq ($(force_installclean),true) 276 $(info *** Forcing "make installclean"...) 277 $(info *** rm -rf $(dataclean_files) $(installclean_files)) 278 $(shell rm -rf $(dataclean_files) $(installclean_files)) 279 $(info *** Done with the cleaning, now starting the real build.) 280 endif 281 force_installclean := 282 283 ########################################################### 284 285 .PHONY: clean-jack-files 286 clean-jack-files: clean-dex-files 287 $(hide) find $(OUT_DIR) -name "*.jack" | xargs rm -f 288 $(hide) find $(OUT_DIR) -type d -name "jack" | xargs rm -rf 289 @echo "All jack files have been removed." 290 291 .PHONY: clean-dex-files 292 clean-dex-files: 293 $(hide) find $(OUT_DIR) -name "*.dex" ! -path "*/jack-incremental/*" | xargs rm -f 294 $(hide) for i in `find $(OUT_DIR) -name "*.jar" -o -name "*.apk"` ; do ((unzip -l $$i 2> /dev/null | \ 295 grep -q "\.dex$$" && rm -f $$i) || continue ) ; done 296 @echo "All dex files and archives containing dex files have been removed." 297 298 .PHONY: clean-jack-incremental 299 clean-jack-incremental: 300 $(hide) find $(OUT_DIR) -name "jack-incremental" -type d | xargs rm -rf 301 @echo "All jack incremental dirs have been removed." 302