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
This commit is contained in:
Colin Cross 2017-02-03 15:10:05 -08:00
parent d12816b100
commit e14d9b7f7e
1 changed files with 34 additions and 26 deletions

View File

@ -1535,6 +1535,7 @@ $(call _concat-if-arg2-not-empty,$(1),$(wordlist 3001,99999,$(2)))
endef endef
# $(1): the full path of the source static library. # $(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 define _extract-and-include-single-target-whole-static-lib
$(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\ $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\
rm -rf $$ldir; \ rm -rf $$ldir; \
@ -1556,20 +1557,22 @@ $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;
filelist="$$filelist $$ldir/$$ext$$f"; \ filelist="$$filelist $$ldir/$$ext$$f"; \
done ; \ done ; \
$($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_ARFLAGS) \ $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_ARFLAGS) \
$@ $$filelist $(2) $$filelist
endef endef
# $(1): the full path of the source static library. # $(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 define extract-and-include-whole-static-libs-first
$(if $(strip $(1)), $(if $(strip $(1)),
$(hide) cp $(1) $@) $(hide) cp $(1) $(2))
endef endef
# $(1): the full path of the destination static library.
define extract-and-include-target-whole-static-libs 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)), \ $(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 endef
# Explicitly delete the archive first so that ar doesn't # Explicitly delete the archive first so that ar doesn't
@ -1577,15 +1580,17 @@ endef
define transform-o-to-static-lib define transform-o-to-static-lib
@echo "$($(PRIVATE_PREFIX)DISPLAY) StaticLib: $(PRIVATE_MODULE) ($@)" @echo "$($(PRIVATE_PREFIX)DISPLAY) StaticLib: $(PRIVATE_MODULE) ($@)"
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
@rm -f $@ @rm -f $@ $@.tmp
$(extract-and-include-target-whole-static-libs) $(call extract-and-include-target-whole-static-libs,$@.tmp)
$(call split-long-arguments,$($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) \ $(call split-long-arguments,$($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_AR) \
$($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_ARFLAGS) \ $($(PRIVATE_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_ARFLAGS) \
$(PRIVATE_ARFLAGS) \ $(PRIVATE_ARFLAGS) \
$@,$(PRIVATE_ALL_OBJECTS)) $@.tmp,$(PRIVATE_ALL_OBJECTS))
$(hide) mv -f $@.tmp $@
endef endef
# $(1): the full path of the source static library. # $(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 define _extract-and-include-single-aux-whole-static-lib
$(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\ $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\
rm -rf $$ldir; \ 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; \ $(PRIVATE_AR) p $$lib_to_include $$f > $$ldir/$$ext$$f; \
filelist="$$filelist $$ldir/$$ext$$f"; \ filelist="$$filelist $$ldir/$$ext$$f"; \
done ; \ done ; \
$(PRIVATE_AR) $(AUX_GLOBAL_ARFLAGS) $@ $$filelist $(PRIVATE_AR) $(AUX_GLOBAL_ARFLAGS) $(2) $$filelist
endef endef
define extract-and-include-aux-whole-static-libs 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)), \ $(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 endef
# Explicitly delete the archive first so that ar doesn't # Explicitly delete the archive first so that ar doesn't
@ -1621,10 +1626,11 @@ endef
define transform-o-to-aux-static-lib define transform-o-to-aux-static-lib
@echo "$($(PRIVATE_PREFIX)DISPLAY) StaticLib: $(PRIVATE_MODULE) ($@)" @echo "$($(PRIVATE_PREFIX)DISPLAY) StaticLib: $(PRIVATE_MODULE) ($@)"
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
@rm -f $@ @rm -f $@ $@.tmp
$(extract-and-include-aux-whole-static-libs) $(call extract-and-include-aux-whole-static-libs,$@.tmp)
$(call split-long-arguments,$(PRIVATE_AR) \ $(call split-long-arguments,$(PRIVATE_AR) \
$(AUX_GLOBAL_ARFLAGS) $@,$(PRIVATE_ALL_OBJECTS)) $(AUX_GLOBAL_ARFLAGS) $@.tmp,$(PRIVATE_ALL_OBJECTS))
$(hide) mv -f $@.tmp $@
endef endef
define transform-o-to-aux-executable-inner define transform-o-to-aux-executable-inner
@ -1671,6 +1677,7 @@ endef
########################################################### ###########################################################
# $(1): the full path of the source static library. # $(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 define _extract-and-include-single-host-whole-static-lib
$(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\ $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;\
rm -rf $$ldir; \ rm -rf $$ldir; \
@ -1692,30 +1699,30 @@ $(hide) ldir=$(PRIVATE_INTERMEDIATES_DIR)/WHOLE/$(basename $(notdir $(1)))_objs;
filelist="$$filelist $$ldir/$$ext$$f"; \ filelist="$$filelist $$ldir/$$ext$$f"; \
done ; \ done ; \
$($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)AR) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)GLOBAL_ARFLAGS) \ $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)AR) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)GLOBAL_ARFLAGS) \
$@ $$filelist $(2) $$filelist
endef endef
define extract-and-include-host-whole-static-libs 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)), \ $(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 endef
ifeq ($(HOST_OS),darwin) ifeq ($(HOST_OS),darwin)
# On Darwin the host ar fails if there is nothing to add to .a at all. # 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. # We work around by adding a dummy.o and then deleting it.
define create-dummy.o-if-no-objs 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 endef
define get-dummy.o-if-no-objs define get-dummy.o-if-no-objs
$(if $(PRIVATE_ALL_OBJECTS),,$(dir $@)dummy.o) $(if $(PRIVATE_ALL_OBJECTS),,$(dir $(1))dummy.o)
endef endef
define delete-dummy.o-if-no-objs define delete-dummy.o-if-no-objs
$(if $(PRIVATE_ALL_OBJECTS),,$(hide) $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)AR) d $@ $(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 $@)dummy.o) && rm -f $(dir $(1))dummy.o)
endef endef
endif # HOST_OS is darwin endif # HOST_OS is darwin
@ -1724,13 +1731,14 @@ endif # HOST_OS is darwin
define transform-host-o-to-static-lib define transform-host-o-to-static-lib
@echo "$($(PRIVATE_PREFIX)DISPLAY) StaticLib: $(PRIVATE_MODULE) ($@)" @echo "$($(PRIVATE_PREFIX)DISPLAY) StaticLib: $(PRIVATE_MODULE) ($@)"
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
@rm -f $@ @rm -f $@ $@.tmp
$(extract-and-include-host-whole-static-libs) $(call extract-and-include-host-whole-static-libs,$@.tmp)
$(create-dummy.o-if-no-objs) $(call create-dummy.o-if-no-objs,$@.tmp)
$(call split-long-arguments,$($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)AR) \ $(call split-long-arguments,$($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)AR) \
$($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)GLOBAL_ARFLAGS) $@,\ $($(PRIVATE_2ND_ARCH_VAR_PREFIX)$(PRIVATE_PREFIX)GLOBAL_ARFLAGS) $@.tmp,\
$(PRIVATE_ALL_OBJECTS) $(get-dummy.o-if-no-objs)) $(PRIVATE_ALL_OBJECTS) $(call get-dummy.o-if-no-objs,$@.tmp))
$(delete-dummy.o-if-no-objs) $(call delete-dummy.o-if-no-objs,$@.tmp)
$(hide) mv -f $@.tmp $@
endef endef