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))
57
58# If the clean_steps.mk file is missing (usually after a clean build)
59# then we won't do anything.
60CURRENT_CLEAN_BUILD_VERSION := $(INTERNAL_CLEAN_BUILD_VERSION)
61CURRENT_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#
66clean_steps_file := $(PRODUCT_OUT)/clean_steps.mk
67-include $(clean_steps_file)
68
69ifneq ($(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.)
75else
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 :=
107endif
108CURRENT_CLEAN_BUILD_VERSION :=
109CURRENT_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
121clean_steps_file :=
122INTERNAL_CLEAN_STEPS :=
123INTERNAL_CLEAN_BUILD_VERSION :=
124
125endif  # 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
133previous_build_config_file := $(PRODUCT_OUT)/previous_build_config.mk
134
135# A change in the list of aapt configs warrants an installclean, too.
136aapt_config_list := $(strip $(PRODUCT_AAPT_CONFIG) $(PRODUCT_AAPT_PREF_CONFIG))
137
138current_build_config := \
139    $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)-{$(aapt_config_list)}
140aapt_config_list :=
141force_installclean := false
142
143# Read the current state from the file, if present.
144# Will set PREVIOUS_BUILD_CONFIG.
145#
146PREVIOUS_BUILD_CONFIG :=
147-include $(previous_build_config_file)
148PREVIOUS_BUILD_CONFIG := $(strip $(PREVIOUS_BUILD_CONFIG))
149ifdef PREVIOUS_BUILD_CONFIG
150  ifneq "$(current_build_config)" "$(PREVIOUS_BUILD_CONFIG)"
151    $(info *** Build configuration changed: "$(PREVIOUS_BUILD_CONFIG)" -> "$(current_build_config)")
152    ifneq ($(DISABLE_AUTO_INSTALLCLEAN),true)
153      force_installclean := true
154    else
155      $(info DISABLE_AUTO_INSTALLCLEAN is set; skipping auto-clean. Your tree may be in an inconsistent state.)
156    endif
157  endif
158endif  # else, this is the first build, so no need to clean.
159PREVIOUS_BUILD_CONFIG :=
160
161# Write the new state to the file.
162#
163$(shell \
164  mkdir -p $(dir $(previous_build_config_file)) && \
165  echo "PREVIOUS_BUILD_CONFIG := $(current_build_config)" > \
166      $(previous_build_config_file) \
167 )
168previous_build_config_file :=
169current_build_config :=
170
171#
172# installclean logic
173#
174
175# The files/dirs to delete during an installclean.  This includes the
176# non-common APPS directory, which may contain the wrong resources.
177#
178# Deletes all of the files that change between different build types,
179# like "make user" vs. "make sdk".  This lets you work with different
180# build types without having to do a full clean each time.  E.g.:
181#
182#     $ make -j8 all
183#     $ make installclean
184#     $ make -j8 user
185#     $ make installclean
186#     $ make -j8 sdk
187#
188installclean_files := \
189	$(HOST_OUT)/obj/NOTICE_FILES \
190	$(HOST_OUT)/sdk \
191	$(PRODUCT_OUT)/*.img \
192	$(PRODUCT_OUT)/*.ini \
193	$(PRODUCT_OUT)/*.txt \
194	$(PRODUCT_OUT)/*.xlb \
195	$(PRODUCT_OUT)/*.zip \
196	$(PRODUCT_OUT)/kernel \
197	$(PRODUCT_OUT)/data \
198	$(PRODUCT_OUT)/skin \
199	$(PRODUCT_OUT)/obj/APPS \
200	$(PRODUCT_OUT)/obj/NOTICE_FILES \
201	$(PRODUCT_OUT)/obj/PACKAGING \
202	$(PRODUCT_OUT)/recovery \
203	$(PRODUCT_OUT)/root \
204	$(PRODUCT_OUT)/system \
205	$(PRODUCT_OUT)/vendor \
206	$(PRODUCT_OUT)/oem \
207	$(PRODUCT_OUT)/dex_bootjars \
208	$(PRODUCT_OUT)/obj/JAVA_LIBRARIES \
209	$(PRODUCT_OUT)/obj/FAKE \
210	$(PRODUCT_OUT)/obj/EXECUTABLES/adbd_intermediates \
211	$(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libfs_mgr_intermediates \
212	$(PRODUCT_OUT)/obj/EXECUTABLES/init_intermediates \
213	$(PRODUCT_OUT)/obj/ETC/mac_permissions.xml_intermediates \
214	$(PRODUCT_OUT)/obj/ETC/sepolicy_intermediates \
215	$(PRODUCT_OUT)/obj/ETC/init.environ.rc_intermediates
216
217# The files/dirs to delete during a dataclean, which removes any files
218# in the staging and emulator data partitions.
219dataclean_files := \
220	$(PRODUCT_OUT)/data/* \
221	$(PRODUCT_OUT)/data-qemu/* \
222	$(PRODUCT_OUT)/userdata-qemu.img
223
224# make sure *_OUT is set so that we won't result in deleting random parts
225# of the filesystem.
226ifneq (2,$(words $(HOST_OUT) $(PRODUCT_OUT)))
227  $(error both HOST_OUT and PRODUCT_OUT should be set at this point.)
228endif
229
230# Define the rules for commandline invocation.
231.PHONY: dataclean
232dataclean: FILES := $(dataclean_files)
233dataclean:
234	$(hide) rm -rf $(FILES)
235	@echo "Deleted emulator userdata images."
236
237.PHONY: installclean
238installclean: FILES := $(installclean_files)
239installclean: dataclean
240	$(hide) rm -rf $(FILES)
241	@echo "Deleted images and staging directories."
242
243ifeq "$(force_installclean)" "true"
244  $(info *** Forcing "make installclean"...)
245  $(info *** rm -rf $(dataclean_files) $(installclean_files))
246  $(shell rm -rf $(dataclean_files) $(installclean_files))
247  $(info *** Done with the cleaning, now starting the real build.)
248endif
249force_installclean :=
250