Use .KATI_RESTAT to reduce unnecessary rebuilds of binaries

When a shared object is rebuilt, all dependent libraries and
executables are rebuilt. Such rebuild is unnecessary when there
is no interface change. With this patch, .toc files will be
generated for all .so files. The rule which generates .toc files
has ninja's restat=1 and .toc files are not changed ninja won't
rebuild dependent targets.

Performance:

$ m && touch bionic/libc/stdio/stdio.c && time m
Before: 1m03s (2563 targets)
After: 21s (90 targets)

Bug: 24597504
Change-Id: Ia5dd950273d143f4e99eee8bef7478f1a94cd138
diff --git a/core/base_rules.mk b/core/base_rules.mk
index a0a3582..42dfc1b 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -221,6 +221,33 @@
 LOCAL_INTERMEDIATE_TARGETS += $(LOCAL_BUILT_MODULE)
 
 ###########################################################
+## Create .toc files from shared objects to reduce unnecessary rebuild
+# .toc files have the list of external dynamic symbols without their addresses.
+# For ninja build, .toc files will be updated only when the content of .toc
+# files are changed. As .KATI_RESTAT is specified to .toc files, dependent
+# binaries of a .toc file will be rebuilt only when the content of
+# the .toc file is changed.
+###########################################################
+ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
+LOCAL_INTERMEDIATE_TARGETS += $(LOCAL_BUILT_MODULE).toc
+$(LOCAL_BUILT_MODULE).toc: $(LOCAL_BUILT_MODULE)
+ifeq ($(BUILDING_WITH_NINJA),true)
+	$(call $(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)transform-shared-lib-to-toc,$<,$@.tmp)
+	$(hide) if cmp -s $@.tmp $@ ; then \
+		  rm $@.tmp ; \
+		else \
+		  mv $@.tmp $@ ; \
+		fi
+else
+	@# make doesn't support restat. We always update .toc files so the dependents will always be updated too.
+	$(call $(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)transform-shared-lib-to-toc,$<,$@)
+endif
+
+# Kati adds restat=1 to ninja. GNU make does nothing for this.
+.KATI_RESTAT: $(LOCAL_BUILT_MODULE).toc
+endif
+
+###########################################################
 ## logtags: Add .logtags files to global list
 ###########################################################