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 58 # If the clean_steps.mk file is missing (usually after a clean build) 59 # then we won't do anything. 60 CURRENT_CLEAN_BUILD_VERSION := $(INTERNAL_CLEAN_BUILD_VERSION) 61 CURRENT_CLEAN_STEPS := $(INTERNAL_CLEAN_STEPS) 62 63 # Read the current state from the file, if present. 64 # Will set CURRENT_CLEAN_BUILD_VERSION and CURRENT_CLEAN_STEPS. 65 # 66 clean_steps_file := $(PRODUCT_OUT)/clean_steps.mk 67 -include $(clean_steps_file) 68 69 ifneq ($(CURRENT_CLEAN_BUILD_VERSION),$(INTERNAL_CLEAN_BUILD_VERSION)) 70 # The major clean version is out-of-date. Do a full clean, and 71 # don't even bother with the clean steps. 72 $(info *** A clean build is required because of a recent change.) 73 $(shell rm -rf $(OUT_DIR)) 74 $(info *** Done with the cleaning, now starting the real build.) 75 else 76 # The major clean version is correct. Find the list of clean steps 77 # that we need to execute to get up-to-date. 78 steps := \ 79 $(filter-out $(CURRENT_CLEAN_STEPS),$(INTERNAL_CLEAN_STEPS)) 80 $(foreach step,$(steps), \ 81 $(info Clean step: $(INTERNAL_CLEAN_STEP.$(step))) \ 82 $(shell $(INTERNAL_CLEAN_STEP.$(step))) \ 83 ) 84 85 # Rewrite the clean step for the second arch. 86 ifdef TARGET_2ND_ARCH 87 # $(1): the clean step cmd 88 # $(2): the prefix to search for 89 # $(3): the prefix to replace with 90 define -cs-rewrite-cleanstep 91 $(if $(filter $(2)/%,$(1)),\ 92 $(eval _crs_new_cmd := $(patsubst $(2)/%,$(3)/%,$(1)))\ 93 $(info Clean step: $(_crs_new_cmd))\ 94 $(shell $(_crs_new_cmd))) 95 endef 96 $(foreach step,$(steps), \ 97 $(call -cs-rewrite-cleanstep,$(INTERNAL_CLEAN_STEP.$(step)),$(TARGET_OUT_INTERMEDIATES),$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES))\ 98 $(call -cs-rewrite-cleanstep,$(INTERNAL_CLEAN_STEP.$(step)),$(TARGET_OUT_SHARED_LIBRARIES),$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES))\ 99 $(call -cs-rewrite-cleanstep,$(INTERNAL_CLEAN_STEP.$(step)),$(TARGET_OUT_VENDOR_SHARED_LIBRARIES),$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_SHARED_LIBRARIES))\ 100 $(call -cs-rewrite-cleanstep,$(INTERNAL_CLEAN_STEP.$(step)),$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES),$(TARGET_OUT_INTERMEDIATES))\ 101 $(call -cs-rewrite-cleanstep,$(INTERNAL_CLEAN_STEP.$(step)),$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SHARED_LIBRARIES),$(TARGET_OUT_SHARED_LIBRARIES))\ 102 $(call -cs-rewrite-cleanstep,$(INTERNAL_CLEAN_STEP.$(step)),$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_VENDOR_SHARED_LIBRARIES),$(TARGET_OUT_VENDOR_SHARED_LIBRARIES))\ 103 ) 104 endif 105 _crs_new_cmd := 106 steps := 107 endif 108 CURRENT_CLEAN_BUILD_VERSION := 109 CURRENT_CLEAN_STEPS := 110 111 # Write the new state to the file. 112 # 113 $(shell \ 114 mkdir -p $(dir $(clean_steps_file)) && \ 115 echo "CURRENT_CLEAN_BUILD_VERSION := $(INTERNAL_CLEAN_BUILD_VERSION)" > \ 116 $(clean_steps_file) ;\ 117 echo "CURRENT_CLEAN_STEPS := $(INTERNAL_CLEAN_STEPS)" >> \ 118 $(clean_steps_file) \ 119 ) 120 121 clean_steps_file := 122 INTERNAL_CLEAN_STEPS := 123 INTERNAL_CLEAN_BUILD_VERSION := 124 125 endif # if not ONE_SHOT_MAKEFILE dont_bother 126 127 # Since products and build variants (unfortunately) share the same 128 # PRODUCT_OUT staging directory, things can get out of sync if different 129 # build configurations are built in the same tree. The following logic 130 # will notice when the configuration has changed and remove the files 131 # necessary to keep things consistent. 132 133 previous_build_config_file := $(PRODUCT_OUT)/previous_build_config.mk 134 135 # TODO: this special case for the sdk is only necessary while "sdk" 136 # is a valid make target. Eventually, it will just be a product, at 137 # which point TARGET_PRODUCT will handle it and we can avoid this check 138 # of MAKECMDGOALS. The "addprefix" is just to keep things pretty. 139 ifneq ($(TARGET_PRODUCT),sdk) 140 building_sdk := $(addprefix -,$(filter sdk,$(MAKECMDGOALS))) 141 else 142 # Don't bother with this extra part when explicitly building the sdk product. 143 building_sdk := 144 endif 145 146 # A change in the list of aapt configs warrants an installclean, too. 147 aapt_config_list := $(strip $(PRODUCT_AAPT_CONFIG) $(PRODUCT_AAPT_PREF_CONFIG)) 148 149 current_build_config := \ 150 $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)$(building_sdk)-{$(aapt_config_list)} 151 building_sdk := 152 aapt_config_list := 153 force_installclean := false 154 155 # Read the current state from the file, if present. 156 # Will set PREVIOUS_BUILD_CONFIG. 157 # 158 PREVIOUS_BUILD_CONFIG := 159 -include $(previous_build_config_file) 160 PREVIOUS_BUILD_CONFIG := $(strip $(PREVIOUS_BUILD_CONFIG)) 161 ifdef PREVIOUS_BUILD_CONFIG 162 ifneq "$(current_build_config)" "$(PREVIOUS_BUILD_CONFIG)" 163 $(info *** Build configuration changed: "$(PREVIOUS_BUILD_CONFIG)" -> "$(current_build_config)") 164 ifneq ($(DISABLE_AUTO_INSTALLCLEAN),true) 165 force_installclean := true 166 else 167 $(info DISABLE_AUTO_INSTALLCLEAN is set; skipping auto-clean. Your tree may be in an inconsistent state.) 168 endif 169 endif 170 endif # else, this is the first build, so no need to clean. 171 PREVIOUS_BUILD_CONFIG := 172 173 # Write the new state to the file. 174 # 175 $(shell \ 176 mkdir -p $(dir $(previous_build_config_file)) && \ 177 echo "PREVIOUS_BUILD_CONFIG := $(current_build_config)" > \ 178 $(previous_build_config_file) \ 179 ) 180 previous_build_config_file := 181 current_build_config := 182 183 # 184 # installclean logic 185 # 186 187 # The files/dirs to delete during an installclean. This includes the 188 # non-common APPS directory, which may contain the wrong resources. 189 # 190 # Deletes all of the files that change between different build types, 191 # like "make user" vs. "make sdk". This lets you work with different 192 # build types without having to do a full clean each time. E.g.: 193 # 194 # $ make -j8 all 195 # $ make installclean 196 # $ make -j8 user 197 # $ make installclean 198 # $ make -j8 sdk 199 # 200 installclean_files := \ 201 $(HOST_OUT)/obj/NOTICE_FILES \ 202 $(HOST_OUT)/sdk \ 203 $(PRODUCT_OUT)/*.img \ 204 $(PRODUCT_OUT)/*.ini \ 205 $(PRODUCT_OUT)/*.txt \ 206 $(PRODUCT_OUT)/*.xlb \ 207 $(PRODUCT_OUT)/*.zip \ 208 $(PRODUCT_OUT)/kernel \ 209 $(PRODUCT_OUT)/data \ 210 $(PRODUCT_OUT)/skin \ 211 $(PRODUCT_OUT)/obj/APPS \ 212 $(PRODUCT_OUT)/obj/NOTICE_FILES \ 213 $(PRODUCT_OUT)/obj/PACKAGING \ 214 $(PRODUCT_OUT)/recovery \ 215 $(PRODUCT_OUT)/root \ 216 $(PRODUCT_OUT)/system \ 217 $(PRODUCT_OUT)/vendor \ 218 $(PRODUCT_OUT)/oem \ 219 $(PRODUCT_OUT)/dex_bootjars \ 220 $(PRODUCT_OUT)/obj/JAVA_LIBRARIES \ 221 $(PRODUCT_OUT)/obj/FAKE \ 222 $(PRODUCT_OUT)/obj/EXECUTABLES/adbd_intermediates \ 223 $(PRODUCT_OUT)/obj/EXECUTABLES/init_intermediates \ 224 $(PRODUCT_OUT)/obj/ETC/mac_permissions.xml_intermediates \ 225 $(PRODUCT_OUT)/obj/ETC/sepolicy_intermediates \ 226 $(PRODUCT_OUT)/obj/ETC/init.environ.rc_intermediates 227 228 # The files/dirs to delete during a dataclean, which removes any files 229 # in the staging and emulator data partitions. 230 dataclean_files := \ 231 $(PRODUCT_OUT)/data/* \ 232 $(PRODUCT_OUT)/data-qemu/* \ 233 $(PRODUCT_OUT)/userdata-qemu.img 234 235 # make sure *_OUT is set so that we won't result in deleting random parts 236 # of the filesystem. 237 ifneq (2,$(words $(HOST_OUT) $(PRODUCT_OUT))) 238 $(error both HOST_OUT and PRODUCT_OUT should be set at this point.) 239 endif 240 241 # Define the rules for commandline invocation. 242 .PHONY: dataclean 243 dataclean: FILES := $(dataclean_files) 244 dataclean: 245 $(hide) rm -rf $(FILES) 246 @echo "Deleted emulator userdata images." 247 248 .PHONY: installclean 249 installclean: FILES := $(installclean_files) 250 installclean: dataclean 251 $(hide) rm -rf $(FILES) 252 @echo "Deleted images and staging directories." 253 254 ifeq "$(force_installclean)" "true" 255 $(info *** Forcing "make installclean"...) 256 $(info *** rm -rf $(dataclean_files) $(installclean_files)) 257 $(shell rm -rf $(dataclean_files) $(installclean_files)) 258 $(info *** Done with the cleaning, now starting the real build.) 259 endif 260 force_installclean := 261