cleanbuild.mk revision 6ea58cb3dc564ce112b28f1a7c6936317168d931
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
16INTERNAL_CLEAN_STEPS :=
17
18# Builds up a list of clean steps.  Creates a unique
19# id for each step by taking makefile path, INTERNAL_CLEAN_BUILD_VERSION
20# and appending an increasing number of '@' characters.
21#
22# $(1): shell command to run
23# $(2): indicate to not use makefile path as part of step id if not empty.
24#       $(2) should only be used in build/core/cleanspec.mk: just for compatibility.
25define _add-clean-step
26  $(if $(strip $(INTERNAL_CLEAN_BUILD_VERSION)),, \
27      $(error INTERNAL_CLEAN_BUILD_VERSION not set))
28  $(eval _acs_makefile_prefix := $(lastword $(MAKEFILE_LIST)))
29  $(eval _acs_makefile_prefix := $(subst /,_,$(_acs_makefile_prefix)))
30  $(eval _acs_makefile_prefix := $(subst .,-,$(_acs_makefile_prefix)))
31  $(eval _acs_makefile_prefix := $(_acs_makefile_prefix)_acs)
32  $(if $($(_acs_makefile_prefix)),,\
33      $(eval $(_acs_makefile_prefix) := $(INTERNAL_CLEAN_BUILD_VERSION)))
34  $(eval $(_acs_makefile_prefix) := $($(_acs_makefile_prefix))@)
35  $(if $(strip $(2)),$(eval _acs_id := $($(_acs_makefile_prefix))),\
36      $(eval _acs_id := $(_acs_makefile_prefix)$($(_acs_makefile_prefix))))
37  $(eval INTERNAL_CLEAN_STEPS += $(_acs_id))
38  $(eval INTERNAL_CLEAN_STEP.$(_acs_id) := $(1))
39  $(eval _acs_id :=)
40  $(eval _acs_makefile_prefix :=)
41endef
42define add-clean-step
43$(eval # for build/core/cleanspec.mk, dont use makefile path as part of step id) \
44$(if $(filter %/cleanspec.mk,$(lastword $(MAKEFILE_LIST))),\
45    $(eval $(call _add-clean-step,$(1),true)),\
46    $(eval $(call _add-clean-step,$(1))))
47endef
48
49# Defines INTERNAL_CLEAN_BUILD_VERSION and the individual clean steps.
50# cleanspec.mk is outside of the core directory so that more people
51# can have permission to touch it.
52include $(BUILD_SYSTEM)/cleanspec.mk
53INTERNAL_CLEAN_BUILD_VERSION := $(strip $(INTERNAL_CLEAN_BUILD_VERSION))
54
55# If the clean_steps.mk file is missing (usually after a clean build)
56# then we won't do anything.
57CURRENT_CLEAN_BUILD_VERSION := $(INTERNAL_CLEAN_BUILD_VERSION)
58CURRENT_CLEAN_STEPS := $(INTERNAL_CLEAN_STEPS)
59
60# Read the current state from the file, if present.
61# Will set CURRENT_CLEAN_BUILD_VERSION and CURRENT_CLEAN_STEPS.
62#
63clean_steps_file := $(PRODUCT_OUT)/clean_steps.mk
64-include $(clean_steps_file)
65
66ifneq ($(CURRENT_CLEAN_BUILD_VERSION),$(INTERNAL_CLEAN_BUILD_VERSION))
67  # The major clean version is out-of-date.  Do a full clean, and
68  # don't even bother with the clean steps.
69  $(info *** A clean build is required because of a recent change.)
70  $(shell rm -rf $(OUT_DIR))
71  $(info *** Done with the cleaning, now starting the real build.)
72else
73  # The major clean version is correct.  Find the list of clean steps
74  # that we need to execute to get up-to-date.
75  steps := \
76      $(filter-out $(CURRENT_CLEAN_STEPS),$(INTERNAL_CLEAN_STEPS))
77  $(foreach step,$(steps), \
78    $(info Clean step: $(INTERNAL_CLEAN_STEP.$(step))) \
79    $(shell $(INTERNAL_CLEAN_STEP.$(step))) \
80   )
81  # If we are running mm/mmm, we should copy over the other clean steps too.
82  ifneq ($(ONE_SHOT_MAKEFILE),)
83    INTERNAL_CLEAN_STEPS := $(strip $(CURRENT_CLEAN_STEPS) $(steps))
84  endif
85  steps :=
86endif
87CURRENT_CLEAN_BUILD_VERSION :=
88CURRENT_CLEAN_STEPS :=
89
90# Write the new state to the file.
91#
92$(shell \
93  mkdir -p $(dir $(clean_steps_file)) && \
94  echo "CURRENT_CLEAN_BUILD_VERSION := $(INTERNAL_CLEAN_BUILD_VERSION)" > \
95      $(clean_steps_file) ;\
96  echo "CURRENT_CLEAN_STEPS := $(INTERNAL_CLEAN_STEPS)" >> \
97      $(clean_steps_file) \
98 )
99
100clean_steps_file :=
101INTERNAL_CLEAN_STEPS :=
102INTERNAL_CLEAN_BUILD_VERSION :=
103
104
105# Since products and build variants (unfortunately) share the same
106# PRODUCT_OUT staging directory, things can get out of sync if different
107# build configurations are built in the same tree.  The following logic
108# will notice when the configuration has changed and remove the files
109# necessary to keep things consistent.
110
111previous_build_config_file := $(PRODUCT_OUT)/previous_build_config.mk
112
113# TODO: this special case for the sdk is only necessary while "sdk"
114# is a valid make target.  Eventually, it will just be a product, at
115# which point TARGET_PRODUCT will handle it and we can avoid this check
116# of MAKECMDGOALS.  The "addprefix" is just to keep things pretty.
117ifneq ($(TARGET_PRODUCT),sdk)
118  building_sdk := $(addprefix -,$(filter sdk,$(MAKECMDGOALS)))
119else
120  # Don't bother with this extra part when explicitly building the sdk product.
121  building_sdk :=
122endif
123
124# A change in the list of aapt configs warrants an installclean, too.
125aapt_config_list := $(strip $(PRODUCT_AAPT_CONFIG) $(PRODUCT_AAPT_PREF_CONFIG))
126
127current_build_config := \
128    $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)$(building_sdk)-{$(aapt_config_list)}
129building_sdk :=
130aapt_config_list :=
131force_installclean := false
132
133# Read the current state from the file, if present.
134# Will set PREVIOUS_BUILD_CONFIG.
135#
136PREVIOUS_BUILD_CONFIG :=
137-include $(previous_build_config_file)
138PREVIOUS_BUILD_CONFIG := $(strip $(PREVIOUS_BUILD_CONFIG))
139ifdef PREVIOUS_BUILD_CONFIG
140  ifneq "$(current_build_config)" "$(PREVIOUS_BUILD_CONFIG)"
141    $(info *** Build configuration changed: "$(PREVIOUS_BUILD_CONFIG)" -> "$(current_build_config)")
142    ifneq ($(DISABLE_AUTO_INSTALLCLEAN),true)
143      force_installclean := true
144    else
145      $(info DISABLE_AUTO_INSTALLCLEAN is set; skipping auto-clean. Your tree may be in an inconsistent state.)
146    endif
147  endif
148endif  # else, this is the first build, so no need to clean.
149PREVIOUS_BUILD_CONFIG :=
150
151# Write the new state to the file.
152#
153$(shell \
154  mkdir -p $(dir $(previous_build_config_file)) && \
155  echo "PREVIOUS_BUILD_CONFIG := $(current_build_config)" > \
156      $(previous_build_config_file) \
157 )
158previous_build_config_file :=
159current_build_config :=
160
161#
162# installclean logic
163#
164
165# The files/dirs to delete during an installclean.  This includes the
166# non-common APPS directory, which may contain the wrong resources.
167#
168# Deletes all of the files that change between different build types,
169# like "make user" vs. "make sdk".  This lets you work with different
170# build types without having to do a full clean each time.  E.g.:
171#
172#     $ make -j8 all
173#     $ make installclean
174#     $ make -j8 user
175#     $ make installclean
176#     $ make -j8 sdk
177#
178installclean_files := \
179	$(HOST_OUT)/obj/NOTICE_FILES \
180	$(HOST_OUT)/sdk \
181	$(PRODUCT_OUT)/*.img \
182	$(PRODUCT_OUT)/*.txt \
183	$(PRODUCT_OUT)/*.xlb \
184	$(PRODUCT_OUT)/*.zip \
185	$(PRODUCT_OUT)/data \
186	$(PRODUCT_OUT)/obj/APPS \
187	$(PRODUCT_OUT)/obj/NOTICE_FILES \
188	$(PRODUCT_OUT)/obj/PACKAGING \
189	$(PRODUCT_OUT)/recovery \
190	$(PRODUCT_OUT)/root \
191	$(PRODUCT_OUT)/system \
192	$(PRODUCT_OUT)/dex_bootjars \
193	$(PRODUCT_OUT)/obj/JAVA_LIBRARIES \
194	$(PRODUCT_OUT)/obj/FAKE \
195	$(PRODUCT_OUT)/obj/EXECUTABLES/adbd_intermediates \
196	$(PRODUCT_OUT)/obj/EXECUTABLES/init_intermediates
197
198
199# The files/dirs to delete during a dataclean, which removes any files
200# in the staging and emulator data partitions.
201dataclean_files := \
202	$(PRODUCT_OUT)/data/* \
203	$(PRODUCT_OUT)/data-qemu/* \
204	$(PRODUCT_OUT)/userdata-qemu.img
205
206# make sure *_OUT is set so that we won't result in deleting random parts
207# of the filesystem.
208ifneq (2,$(words $(HOST_OUT) $(PRODUCT_OUT)))
209  $(error both HOST_OUT and PRODUCT_OUT should be set at this point.)
210endif
211
212# Define the rules for commandline invocation.
213.PHONY: dataclean
214dataclean: FILES := $(dataclean_files)
215dataclean:
216	$(hide) rm -rf $(FILES)
217	@echo "Deleted emulator userdata images."
218
219.PHONY: installclean
220installclean: FILES := $(installclean_files)
221installclean: dataclean
222	$(hide) rm -rf $(FILES)
223	@echo "Deleted images and staging directories."
224
225ifeq "$(force_installclean)" "true"
226  $(info *** Forcing "make installclean"...)
227  $(info *** rm -rf $(dataclean_files) $(installclean_files))
228  $(shell rm -rf $(dataclean_files) $(installclean_files))
229  $(info *** Done with the cleaning, now starting the real build.)
230endif
231force_installclean :=
232