Home | History | Annotate | Download | only in core
      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   steps :=
     85 endif
     86 CURRENT_CLEAN_BUILD_VERSION :=
     87 CURRENT_CLEAN_STEPS :=
     88 
     89 # Write the new state to the file.
     90 #
     91 $(shell \
     92   mkdir -p $(dir $(clean_steps_file)) && \
     93   echo "CURRENT_CLEAN_BUILD_VERSION := $(INTERNAL_CLEAN_BUILD_VERSION)" > \
     94       $(clean_steps_file) ;\
     95   echo "CURRENT_CLEAN_STEPS := $(INTERNAL_CLEAN_STEPS)" >> \
     96       $(clean_steps_file) \
     97  )
     98 
     99 clean_steps_file :=
    100 INTERNAL_CLEAN_STEPS :=
    101 INTERNAL_CLEAN_BUILD_VERSION :=
    102 
    103 endif  # if not ONE_SHOT_MAKEFILE dont_bother
    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 
    111 previous_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.
    117 ifneq ($(TARGET_PRODUCT),sdk)
    118   building_sdk := $(addprefix -,$(filter sdk,$(MAKECMDGOALS)))
    119 else
    120   # Don't bother with this extra part when explicitly building the sdk product.
    121   building_sdk :=
    122 endif
    123 
    124 # A change in the list of aapt configs warrants an installclean, too.
    125 aapt_config_list := $(strip $(PRODUCT_AAPT_CONFIG) $(PRODUCT_AAPT_PREF_CONFIG))
    126 
    127 current_build_config := \
    128     $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)$(building_sdk)-{$(aapt_config_list)}
    129 building_sdk :=
    130 aapt_config_list :=
    131 force_installclean := false
    132 
    133 # Read the current state from the file, if present.
    134 # Will set PREVIOUS_BUILD_CONFIG.
    135 #
    136 PREVIOUS_BUILD_CONFIG :=
    137 -include $(previous_build_config_file)
    138 PREVIOUS_BUILD_CONFIG := $(strip $(PREVIOUS_BUILD_CONFIG))
    139 ifdef 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
    148 endif  # else, this is the first build, so no need to clean.
    149 PREVIOUS_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  )
    158 previous_build_config_file :=
    159 current_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 #
    178 installclean_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)/kernel \
    186 	$(PRODUCT_OUT)/data \
    187 	$(PRODUCT_OUT)/obj/APPS \
    188 	$(PRODUCT_OUT)/obj/NOTICE_FILES \
    189 	$(PRODUCT_OUT)/obj/PACKAGING \
    190 	$(PRODUCT_OUT)/recovery \
    191 	$(PRODUCT_OUT)/root \
    192 	$(PRODUCT_OUT)/system \
    193 	$(PRODUCT_OUT)/dex_bootjars \
    194 	$(PRODUCT_OUT)/obj/JAVA_LIBRARIES \
    195 	$(PRODUCT_OUT)/obj/FAKE \
    196 	$(PRODUCT_OUT)/obj/EXECUTABLES/adbd_intermediates \
    197 	$(PRODUCT_OUT)/obj/EXECUTABLES/init_intermediates \
    198 	$(PRODUCT_OUT)/obj/ETC/mac_permissions.xml_intermediates \
    199 	$(PRODUCT_OUT)/obj/ETC/sepolicy_intermediates
    200 
    201 # The files/dirs to delete during a dataclean, which removes any files
    202 # in the staging and emulator data partitions.
    203 dataclean_files := \
    204 	$(PRODUCT_OUT)/data/* \
    205 	$(PRODUCT_OUT)/data-qemu/* \
    206 	$(PRODUCT_OUT)/userdata-qemu.img
    207 
    208 # make sure *_OUT is set so that we won't result in deleting random parts
    209 # of the filesystem.
    210 ifneq (2,$(words $(HOST_OUT) $(PRODUCT_OUT)))
    211   $(error both HOST_OUT and PRODUCT_OUT should be set at this point.)
    212 endif
    213 
    214 # Define the rules for commandline invocation.
    215 .PHONY: dataclean
    216 dataclean: FILES := $(dataclean_files)
    217 dataclean:
    218 	$(hide) rm -rf $(FILES)
    219 	@echo "Deleted emulator userdata images."
    220 
    221 .PHONY: installclean
    222 installclean: FILES := $(installclean_files)
    223 installclean: dataclean
    224 	$(hide) rm -rf $(FILES)
    225 	@echo "Deleted images and staging directories."
    226 
    227 ifeq "$(force_installclean)" "true"
    228   $(info *** Forcing "make installclean"...)
    229   $(info *** rm -rf $(dataclean_files) $(installclean_files))
    230   $(shell rm -rf $(dataclean_files) $(installclean_files))
    231   $(info *** Done with the cleaning, now starting the real build.)
    232 endif
    233 force_installclean :=
    234