From e14d9b7f7e699fce137c6914cb61533c38812852 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 3 Feb 2017 15:10:05 -0800 Subject: [PATCH] Create static archives in temporary file Creating static archives is often a multi-command process due to adding whole static libraires or hitting command line length limits. If one of the intermediate commands fails, the output file may already exist. Unlike make, ninja has no option to delete output files on failed builds, instead assuming all build commands will produce their output file atomically (https://github.com/ninja-build/ninja/issues/1135). Change the static library rules to generate to a temporary file that is then atomically moved into place as the output file. Test: m -j checkbuild tests cts Change-Id: I4faf269f0c8e313c738154870a5aa0b4774a72bc --- core/definitions.mk | 60 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/core/definitions.mk b/core/definitions.mk index d77cea998..da5aff10f 100644 --- a/core/definitions.mk +++ b/core/definitions.mk @@ -1535,6 +1535,7 @@ $(call _concat-if-arg2-not-empty,$(1),$(wordlist 3001,99999,$(2))) endef # $(1): the full path of the source static library. +# $(2): the full path of the destination static library. define _extract-and-include-single-target-whole-static-lib $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\ rm -rf $$ldir; \ @@ -1556,20 +1557,22 @@ $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs; filelist="$$filelist $$ldir/$$ext$$f"; \ done ; \ $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_ARFLAGS) \ - $@ $$filelist + $(2) $$filelist endef # $(1): the full path of the source static library. +# $(2): the full path of the destination static library. define extract-and-include-whole-static-libs-first $(if $(strip $(1)), -$(hide) cp $(1) $@) +$(hide) cp $(1) $(2)) endef +# $(1): the full path of the destination static library. define extract-and-include-target-whole-static-libs -$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES))) +$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)),$(1)) $(foreach lib,$(wordlist 2,999,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)), \ - $(call _extract-and-include-single-target-whole-static-lib, $(lib))) + $(call _extract-and-include-single-target-whole-static-lib, $(lib), $(1))) endef # Explicitly delete the archive first so that ar doesn't @@ -1577,15 +1580,17 @@ endef define transform-o-to-static-lib @echo "$($(PRIVATE_PREFIX)DISPLAY) StaticLib: $(PRIVATE_MODULE) ($@)" @mkdir -p $(dir $@) -@rm -f $@ -$(extract-and-include-target-whole-static-libs) +@rm -f $@ $@.tmp +$(call extract-and-include-target-whole-static-libs,$@.tmp) $(call split-long-arguments,$($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) \ $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_ARFLAGS) \ $(PRIVATE_ARFLAGS) \ - $@,$(PRIVATE_ALL_OBJECTS)) + $@.tmp,$(PRIVATE_ALL_OBJECTS)) +$(hide) mv -f $@.tmp $@ endef # $(1): the full path of the source static library. +# $(2): the full path of the destination static library. define _extract-and-include-single-aux-whole-static-lib $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\ rm -rf $$ldir; \ @@ -1606,14 +1611,14 @@ $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs; $(PRIVATE_AR) p $$lib_to_include $$f > $$ldir/$$ext$$f; \ filelist="$$filelist $$ldir/$$ext$$f"; \ done ; \ - $(PRIVATE_AR) $(AUX_GLOBAL_ARFLAGS) $@ $$filelist + $(PRIVATE_AR) $(AUX_GLOBAL_ARFLAGS) $(2) $$filelist endef define extract-and-include-aux-whole-static-libs -$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES))) +$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)),$(1)) $(foreach lib,$(wordlist 2,999,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)), \ - $(call _extract-and-include-single-aux-whole-static-lib, $(lib))) + $(call _extract-and-include-single-aux-whole-static-lib, $(lib), $(1))) endef # Explicitly delete the archive first so that ar doesn't @@ -1621,10 +1626,11 @@ endef define transform-o-to-aux-static-lib @echo "$($(PRIVATE_PREFIX)DISPLAY) StaticLib: $(PRIVATE_MODULE) ($@)" @mkdir -p $(dir $@) -@rm -f $@ -$(extract-and-include-aux-whole-static-libs) +@rm -f $@ $@.tmp +$(call extract-and-include-aux-whole-static-libs,$@.tmp) $(call split-long-arguments,$(PRIVATE_AR) \ - $(AUX_GLOBAL_ARFLAGS) $@,$(PRIVATE_ALL_OBJECTS)) + $(AUX_GLOBAL_ARFLAGS) $@.tmp,$(PRIVATE_ALL_OBJECTS)) +$(hide) mv -f $@.tmp $@ endef define transform-o-to-aux-executable-inner @@ -1671,6 +1677,7 @@ endef ########################################################### # $(1): the full path of the source static library. +# $(2): the full path of the destination static library. define _extract-and-include-single-host-whole-static-lib $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\ rm -rf $$ldir; \ @@ -1692,30 +1699,30 @@ $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs; filelist="$$filelist $$ldir/$$ext$$f"; \ done ; \ $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)AR) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)GLOBAL_ARFLAGS) \ - $@ $$filelist + $(2) $$filelist endef define extract-and-include-host-whole-static-libs -$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES))) +$(call extract-and-include-whole-static-libs-first, $(firstword $(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)),$(1)) $(foreach lib,$(wordlist 2,999,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)), \ - $(call _extract-and-include-single-host-whole-static-lib, $(lib))) + $(call _extract-and-include-single-host-whole-static-lib, $(lib),$(1))) endef ifeq ($(HOST_OS),darwin) # On Darwin the host ar fails if there is nothing to add to .a at all. # We work around by adding a dummy.o and then deleting it. define create-dummy.o-if-no-objs -$(if $(PRIVATE_ALL_OBJECTS),,$(hide) touch $(dir $@)dummy.o) +$(if $(PRIVATE_ALL_OBJECTS),,$(hide) touch $(dir $(1))dummy.o) endef define get-dummy.o-if-no-objs -$(if $(PRIVATE_ALL_OBJECTS),,$(dir $@)dummy.o) +$(if $(PRIVATE_ALL_OBJECTS),,$(dir $(1))dummy.o) endef define delete-dummy.o-if-no-objs -$(if $(PRIVATE_ALL_OBJECTS),,$(hide) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)AR) d $@ $(dir $@)dummy.o \ - && rm -f $(dir $@)dummy.o) +$(if $(PRIVATE_ALL_OBJECTS),,$(hide) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)AR) d $(1) $(dir $(1))dummy.o \ + && rm -f $(dir $(1))dummy.o) endef endif # HOST_OS is darwin @@ -1724,13 +1731,14 @@ endif # HOST_OS is darwin define transform-host-o-to-static-lib @echo "$($(PRIVATE_PREFIX)DISPLAY) StaticLib: $(PRIVATE_MODULE) ($@)" @mkdir -p $(dir $@) -@rm -f $@ -$(extract-and-include-host-whole-static-libs) -$(create-dummy.o-if-no-objs) +@rm -f $@ $@.tmp +$(call extract-and-include-host-whole-static-libs,$@.tmp) +$(call create-dummy.o-if-no-objs,$@.tmp) $(call split-long-arguments,$($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)AR) \ - $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)GLOBAL_ARFLAGS) $@,\ - $(PRIVATE_ALL_OBJECTS) $(get-dummy.o-if-no-objs)) -$(delete-dummy.o-if-no-objs) + $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)GLOBAL_ARFLAGS) $@.tmp,\ + $(PRIVATE_ALL_OBJECTS) $(call get-dummy.o-if-no-objs,$@.tmp)) +$(call delete-dummy.o-if-no-objs,$@.tmp) +$(hide) mv -f $@.tmp $@ endef -- 2.11.0