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