author | Mike Hommey <mh+mozilla@glandium.org> |
Wed, 02 Oct 2013 08:53:23 +0900 | |
changeset 149568 | 6be8c784235c92a7c72c1cf9cc797cf564cc8335 |
parent 149567 | 99e29833c316db196c00b250e654256e8b9dd19b |
child 149569 | c5906eed61fcc7a83f8ed23cdbbc868d6c45aaaf |
push id | 34598 |
push user | mh@glandium.org |
push date | Tue, 01 Oct 2013 23:54:44 +0000 |
treeherder | mozilla-inbound@6be8c784235c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | gps |
bugs | 905973 |
milestone | 27.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/Makefile.in +++ b/Makefile.in @@ -28,19 +28,19 @@ DIST_GARBAGE = config.cache config.log c config/autoconf.mk \ mozilla-config.h \ netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \ .mozconfig.mk ifndef MOZ_PROFILE_USE # We need to explicitly put backend.RecursiveMakeBackend.built here # otherwise the rule in rules.mk doesn't run early enough. -libs export tools:: CLOBBER $(topsrcdir)/configure config.status backend.RecursiveMakeBackend.built +libs binaries export tools:: CLOBBER $(topsrcdir)/configure config.status backend.RecursiveMakeBackend.built ifndef LIBXUL_SDK -libs export tools:: js-config-status +libs binaries export tools:: js-config-status endif endif CLOBBER: $(topsrcdir)/CLOBBER @echo "STOP! The CLOBBER file has changed." @echo "Please run the build through a sanctioned build wrapper, such as" @echo "'mach build' or client.mk." @exit 1 @@ -98,20 +98,24 @@ endif # Windows PGO builds don't perform a clean before the 2nd pass. So, we want # to preserve content for the 2nd pass on Windows. Everywhere else, we always # process the install manifests as part of export. ifdef MOZ_PROFILE_USE ifndef NO_PROFILE_GUIDED_OPTIMIZE ifneq ($(OS_ARCH)_$(GNU_CC), WINNT_) export:: install-manifests +binaries:: + @$(MAKE) install-manifests NO_REMOVE=1 endif endif else # !MOZ_PROFILE_USE (normal build) export:: install-manifests +binaries:: + @$(MAKE) install-manifests NO_REMOVE=1 endif # For historical reasons that are unknown, $(DIST)/sdk is always blown away # with no regard for PGO passes. This decision could probably be revisited. export:: install-dist-sdk ifdef ENABLE_TESTS # Additional makefile targets to call automated test suites @@ -234,10 +238,15 @@ check:: $(call SUBMAKE,$@,js/src) endif ifdef MOZ_PSEUDO_DERECURSE # Interdependencies for parallel export. js/xpconnect/src/export: dom/bindings/export accessible/src/xpcom/export: xpcom/xpidl/export js/src/export: mfbt/export +# Temporary interdependencies for binaries, until bug 921307 is fixed. +# Avoid traversal of those directories when creating the aggregate dependency file +ifneq (binaries-deps,$(MAKECMDGOALS)) +toolkit/library/binaries: js/src/binaries media/webrtc/trunk/binaries media/webrtc/signaling/binaries media/webrtc/trunk/testing/binaries media/webrtc/signalingtest/binaries media/mtransport/third_party/nrappkit/binaries media/mtransport/third_party/nICEr/binaries endif endif +endif
--- a/build/docs/build-targets.rst +++ b/build/docs/build-targets.rst @@ -15,26 +15,34 @@ partial tree builds can be unreliable. U export Build the *export* tier. The *export* tier builds everything that is required for C/C++ compilation. It stages all header files, processes IDLs, etc. compile Build the *compile* tier. The *compile* tier compiles all C/C++ files. + Only applies to builds with ``MOZ_PSEUDO_DERECURSE``. libs Build the *libs* tier. The *libs* tier performs linking and performs most build steps which aren't related to compilation. tools Build the *tools* tier. The *tools* tier mostly deals with supplementary tools and compiled tests. It will link tools against libXUL, including compiled test binaries. +binaries: + Recompiles and relinks C/C++ files. Only works after a complete normal + build, but allows for much faster rebuilds of C/C++ code. For performance + reasons, however, it skips nss, nspr, icu and ffi. This is targeted to + improve local developer workflow when touching C/C++ code. + Only applies to builds with ``MOZ_PSEUDO_DERECURSE``. + install-manifests Process install manifests. Install manifests handle the installation of files into the object directory. Unless ``NO_REMOVE=1`` is defined in the environment, files not accounted in the install manifests will be deleted from the object directory. install-tests
--- a/config/makefiles/target_libs.mk +++ b/config/makefiles/target_libs.mk @@ -13,17 +13,17 @@ else EXPORT_LIBRARY = $(DEPTH)/staticlib endif else # If EXPORT_LIBRARY has a value, we'll be installing there. We also need to cleanup there GARBAGE += $(foreach lib,$(LIBRARY),$(EXPORT_LIBRARY)/$(lib)) endif endif # EXPORT_LIBRARY -libs:: $(SUBMAKEFILES) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) +binaries libs:: $(SUBMAKEFILES) $(TARGETS) ifndef NO_DIST_INSTALL ifdef SHARED_LIBRARY ifdef IS_COMPONENT $(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components $(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY) ifndef NO_COMPONENTS_MANIFEST @$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest "manifest components/components.manifest" @$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.manifest "binary-component $(SHARED_LIBRARY)" @@ -32,66 +32,105 @@ endif # IS_COMPONENT endif # SHARED_LIBRARY endif # !NO_DIST_INSTALL ifndef NO_DIST_INSTALL ifneq (,$(strip $(PROGRAM)$(SIMPLE_PROGRAMS))) PROGRAMS_EXECUTABLES = $(SIMPLE_PROGRAMS) $(PROGRAM) PROGRAMS_DEST ?= $(FINAL_TARGET) +PROGRAMS_TARGET := binaries libs INSTALL_TARGETS += PROGRAMS endif ifdef LIBRARY ifdef EXPORT_LIBRARY LIBRARY_FILES = $(LIBRARY) LIBRARY_DEST ?= $(EXPORT_LIBRARY) +LIBRARY_TARGET = binaries libs INSTALL_TARGETS += LIBRARY endif ifdef DIST_INSTALL ifdef IS_COMPONENT $(error Shipping static component libs makes no sense.) else DIST_LIBRARY_FILES = $(LIBRARY) DIST_LIBRARY_DEST ?= $(DIST)/lib +DIST_LIBRARY_TARGET = binaries libs INSTALL_TARGETS += DIST_LIBRARY endif endif # DIST_INSTALL endif # LIBRARY ifdef SHARED_LIBRARY ifndef IS_COMPONENT SHARED_LIBRARY_FILES = $(SHARED_LIBRARY) SHARED_LIBRARY_DEST ?= $(FINAL_TARGET) +SHARED_LIBRARY_TARGET = binaries libs INSTALL_TARGETS += SHARED_LIBRARY ifneq (,$(filter OS2 WINNT,$(OS_ARCH))) ifndef NO_INSTALL_IMPORT_LIBRARY IMPORT_LIB_FILES = $(IMPORT_LIBRARY) endif # NO_INSTALL_IMPORT_LIBRARY else IMPORT_LIB_FILES = $(SHARED_LIBRARY) endif IMPORT_LIB_DEST ?= $(DIST)/lib +IMPORT_LIB_TARGET = binaries libs ifdef IMPORT_LIB_FILES INSTALL_TARGETS += IMPORT_LIB endif endif # ! IS_COMPONENT endif # SHARED_LIBRARY ifneq (,$(strip $(HOST_SIMPLE_PROGRAMS)$(HOST_PROGRAM))) HOST_PROGRAMS_EXECUTABLES = $(HOST_SIMPLE_PROGRAMS) $(HOST_PROGRAM) HOST_PROGRAMS_DEST ?= $(DIST)/host/bin +HOST_PROGRAMS_TARGET = binaries libs INSTALL_TARGETS += HOST_PROGRAMS endif ifdef HOST_LIBRARY HOST_LIBRARY_FILES = $(HOST_LIBRARY) HOST_LIBRARY_DEST ?= $(DIST)/host/lib +HOST_LIBRARY_TARGET = binaries libs INSTALL_TARGETS += HOST_LIBRARY endif endif # !NO_DIST_INSTALL +ifdef MOZ_PSEUDO_DERECURSE +BINARIES_INSTALL_TARGETS := $(foreach category,$(INSTALL_TARGETS),$(if $(filter binaries,$($(category)_TARGET)),$(category))) + +ifneq (,$(strip $(BINARIES_INSTALL_TARGETS))) +# Fill a dependency file with all the binaries installed somewhere in $(DIST) +BINARIES_PP := $(MDDEPDIR)/binaries.pp + +$(BINARIES_PP): Makefile backend.mk $(call mkdir_deps,$(MDDEPDIR)) + @echo "$(strip $(foreach category,$(BINARIES_INSTALL_TARGETS),\ + $(foreach file,$($(category)_FILES) $($(category)_EXECUTABLES),\ + $($(category)_DEST)/$(notdir $(file)): $(file)%\ + )\ + ))" | tr % '\n' > $@ +endif + +binaries libs:: $(TARGETS) $(BINARIES_PP) +# Aggregate all dependency files relevant to a binaries build. If there is nothing +# done in the current directory, just create an empty stamp. +# Externally managed make files (gyp managed) and root make files (js/src/Makefile) +# need to be recursed to do their duty, and creating a stamp would prevent that. +# In the future, we'll aggregate those. +ifneq (.,$(DEPTH)) +ifndef EXTERNALLY_MANAGED_MAKE_FILE + @$(if $^,$(call py_action,link_deps,-o binaries --group-all --topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) $(BINARIES_PP) $(wildcard $(addsuffix .pp,$(addprefix $(MDDEPDIR)/,$(notdir $(sort $(filter-out $(BINARIES_PP),$^) $(OBJ_TARGETS))))))),$(TOUCH) binaries) +endif +endif + +else +binaries:: + $(error The binaries target is not supported without MOZ_PSEUDO_DERECURSE) +endif + # EOF
--- a/config/recurse.mk +++ b/config/recurse.mk @@ -28,31 +28,31 @@ ifeq (1_.,$(if $(MOZ_PSEUDO_DERECURSE),1 include root.mk # Disable build status for mach in top directories without TIERS. # In practice this disables it when recursing under js/src, which confuses mach. ifndef TIERS BUILDSTATUS = endif -# Main rules (export, compile, libs and tools) call recurse_* rules. +# Main rules (export, compile, binaries, libs and tools) call recurse_* rules. # This wrapping is only really useful for build status. -compile libs export tools:: +compile binaries libs export tools:: $(call BUILDSTATUS,TIER_START $@ $($@_subtiers)) +$(MAKE) recurse_$@ $(call BUILDSTATUS,TIER_FINISH $@) # Carefully avoid $(eval) type of rule generation, which makes pymake slower # than necessary. # Get current tier and corresponding subtiers from the data in root.mk. -CURRENT_TIER := $(filter $(foreach tier,compile libs export tools,recurse_$(tier)),$(MAKECMDGOALS)) +CURRENT_TIER := $(filter $(foreach tier,compile binaries libs export tools,recurse_$(tier) $(tier)-deps),$(MAKECMDGOALS)) ifneq (,$(filter-out 0 1,$(words $(CURRENT_TIER)))) $(error $(CURRENT_TIER) not supported on the same make command line) endif -CURRENT_TIER := $(subst recurse_,,$(CURRENT_TIER)) +CURRENT_TIER := $(subst recurse_,,$(CURRENT_TIER:-deps=)) CURRENT_SUBTIERS := $($(CURRENT_TIER)_subtiers) # The rules here are doing directory traversal, so we don't want further # recursion to happen when running make -C subdir $tier. But some make files # further call make -C something else, and sometimes expect recursion to # happen in that case (see browser/metro/locales/Makefile.in for example). # Conveniently, every invocation of make increases MAKELEVEL, so only stop # recursion from happening at current MAKELEVEL + 1. @@ -64,49 +64,93 @@ export NO_RECURSE_MAKELEVEL=$(word $(MAK endif endif # Get all directories traversed for all subtiers in the current tier, or use # directly the $(*_dirs) variables available in root.mk when there is no # TIERS (like for js/src). CURRENT_DIRS := $(or $($(CURRENT_TIER)_dirs),$(foreach subtier,$(CURRENT_SUBTIERS),$($(CURRENT_TIER)_subtier_$(subtier)))) +ifneq (,$(filter binaries libs,$(CURRENT_TIER))) +WANT_STAMPS = 1 +STAMP_TOUCH = $(TOUCH) $(@D)/binaries +endif + # Subtier delimiter rules -$(addprefix subtiers/,$(addsuffix _start/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_start/$(CURRENT_TIER): +$(addprefix subtiers/,$(addsuffix _start/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_start/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_start)) $(call BUILDSTATUS,SUBTIER_START $(CURRENT_TIER) $* $(if $(BUG_915535_FIXED),$($(CURRENT_TIER)_subtier_$*))) + @$(STAMP_TOUCH) -$(addprefix subtiers/,$(addsuffix _finish/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_finish/$(CURRENT_TIER): +$(addprefix subtiers/,$(addsuffix _finish/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_finish/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_finish)) $(call BUILDSTATUS,SUBTIER_FINISH $(CURRENT_TIER) $*) + @$(STAMP_TOUCH) + +$(addprefix subtiers/,$(addsuffix /$(CURRENT_TIER),$(CURRENT_SUBTIERS))): %/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,%)) + @$(STAMP_TOUCH) + +GARBAGE_DIRS += subtiers # Recursion rule for all directories traversed for all subtiers in the # current tier. # root.mk defines subtier_of_* variables, that map a normalized subdir path to # a subtier name (e.g. subtier_of_memory_jemalloc = base) -$(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): %/$(CURRENT_TIER): +$(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): %/$(CURRENT_TIER): $(if $(WANT_STAMPS),%/Makefile %/backend.mk) ifdef BUG_915535_FIXED $(call BUILDSTATUS,TIERDIR_START $(CURRENT_TIER) $(subtier_of_$(subst /,_,$*)) $*) endif +@$(MAKE) -C $* $(if $(filter $*,$(tier_$(subtier_of_$(subst /,_,$*))_staticdirs)),,$(CURRENT_TIER)) +# Ensure existing stamps are up-to-date, but don't create one if submake didn't create one. + $(if $(wildcard $@),@$(STAMP_TOUCH)) ifdef BUG_915535_FIXED $(call BUILDSTATUS,TIERDIR_FINISH $(CURRENT_TIER) $(subtier_of_$(subst /,_,$*)) $*) endif +# Dummy rules for possibly inexisting dependencies for the above tier targets +$(addsuffix /Makefile,$(CURRENT_DIRS)) $(addsuffix /backend.mk,$(CURRENT_DIRS)): + # The export tier requires nsinstall, which is built from config. So every # subdirectory traversal needs to happen after traversing config. ifeq ($(CURRENT_TIER),export) $(addsuffix /$(CURRENT_TIER),$(filter-out config,$(CURRENT_DIRS))): config/$(CURRENT_TIER) endif +ifneq (,$(filter libs binaries,$(CURRENT_TIER))) +# When doing a "libs" build, target_libs.mk ensures the interesting dependency data +# is available in the "binaries" stamp. Once recursion is done, aggregate all that +# dependency info so that stamps depend on relevant files and relevant other stamps. +# When doing a "binaries" build, the aggregate dependency file and those stamps are +# used and allow to skip recursing directories where changes are not going to require +# rebuild. A few directories, however, are still traversed all the time, mostly, the +# gyp managed ones and js/src. +# A few things that are not traversed by a "binaries" build, but should, in an ideal +# world, are nspr, nss, icu and ffi. +recurse_$(CURRENT_TIER): + @$(MAKE) binaries-deps + +# Creating binaries-deps.mk directly would make us build it twice: once when beginning +# the build because of the include, and once at the end because of the stamps. +binaries-deps: $(wildcard $(addsuffix /binaries,$(CURRENT_DIRS))) + @$(call py_action,link_deps,-o $@.mk --group-by-depfile --topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) --guard $(addprefix ",$(addsuffix ",$^))) + @$(TOUCH) $@ + +ifeq (recurse_binaries,$(MAKECMDGOALS)) +$(call include_deps,binaries-deps.mk) +endif + +endif + +DIST_GARBAGE += binaries-deps.mk binaries-deps + else # Don't recurse if MAKELEVEL is NO_RECURSE_MAKELEVEL as defined above, but # still recurse for externally managed make files (gyp-generated ones). ifeq ($(EXTERNALLY_MANAGED_MAKE_FILE)_$(NO_RECURSE_MAKELEVEL),_$(MAKELEVEL)) -compile libs export tools:: +compile binaries libs export tools:: else ######################### # Tier traversal handling ######################### ifdef TIERS @@ -134,17 +178,17 @@ endif $(1):: $$(SUBMAKEFILES) ifdef PARALLEL_DIRS +@$(MAKE) $$(PARALLEL_DIRS_$(1)) endif $$(LOOP_OVER_DIRS) endef -$(foreach subtier,export libs tools,$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier)))) +$(foreach subtier,export compile binaries libs tools,$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier)))) tools export:: $(SUBMAKEFILES) $(LOOP_OVER_TOOL_DIRS) endif # ifdef TIERS endif # ifeq ($(EXTERNALLY_MANAGED_MAKE_FILE)_$(NO_RECURSE_MAKELEVEL),_$(MAKELEVEL))
--- a/config/rules.mk +++ b/config/rules.mk @@ -724,17 +724,19 @@ HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX # Dependencies which, if modified, should cause everything to rebuild GLOBAL_DEPS += Makefile $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk ifndef NO_MAKEFILE_RULE GLOBAL_DEPS += Makefile.in endif ############################################## -compile:: $(OBJS) $(HOST_OBJS) +OBJ_TARGETS = $(OBJS) $(PROGOBJS) $(HOST_OBJS) $(HOST_PROGOBJS) + +compile:: $(OBJ_TARGETS) include $(topsrcdir)/config/makefiles/target_libs.mk ifdef IS_TOOL_DIR # One would think "tools:: libs" would work, but it turns out that combined with # bug 907365, this makes make forget to run some rules sometimes. tools:: @$(MAKE) libs
--- a/js/src/config/makefiles/target_libs.mk +++ b/js/src/config/makefiles/target_libs.mk @@ -13,17 +13,17 @@ else EXPORT_LIBRARY = $(DEPTH)/staticlib endif else # If EXPORT_LIBRARY has a value, we'll be installing there. We also need to cleanup there GARBAGE += $(foreach lib,$(LIBRARY),$(EXPORT_LIBRARY)/$(lib)) endif endif # EXPORT_LIBRARY -libs:: $(SUBMAKEFILES) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) +binaries libs:: $(SUBMAKEFILES) $(TARGETS) ifndef NO_DIST_INSTALL ifdef SHARED_LIBRARY ifdef IS_COMPONENT $(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components $(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY) ifndef NO_COMPONENTS_MANIFEST @$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest "manifest components/components.manifest" @$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.manifest "binary-component $(SHARED_LIBRARY)" @@ -32,66 +32,105 @@ endif # IS_COMPONENT endif # SHARED_LIBRARY endif # !NO_DIST_INSTALL ifndef NO_DIST_INSTALL ifneq (,$(strip $(PROGRAM)$(SIMPLE_PROGRAMS))) PROGRAMS_EXECUTABLES = $(SIMPLE_PROGRAMS) $(PROGRAM) PROGRAMS_DEST ?= $(FINAL_TARGET) +PROGRAMS_TARGET := binaries libs INSTALL_TARGETS += PROGRAMS endif ifdef LIBRARY ifdef EXPORT_LIBRARY LIBRARY_FILES = $(LIBRARY) LIBRARY_DEST ?= $(EXPORT_LIBRARY) +LIBRARY_TARGET = binaries libs INSTALL_TARGETS += LIBRARY endif ifdef DIST_INSTALL ifdef IS_COMPONENT $(error Shipping static component libs makes no sense.) else DIST_LIBRARY_FILES = $(LIBRARY) DIST_LIBRARY_DEST ?= $(DIST)/lib +DIST_LIBRARY_TARGET = binaries libs INSTALL_TARGETS += DIST_LIBRARY endif endif # DIST_INSTALL endif # LIBRARY ifdef SHARED_LIBRARY ifndef IS_COMPONENT SHARED_LIBRARY_FILES = $(SHARED_LIBRARY) SHARED_LIBRARY_DEST ?= $(FINAL_TARGET) +SHARED_LIBRARY_TARGET = binaries libs INSTALL_TARGETS += SHARED_LIBRARY ifneq (,$(filter OS2 WINNT,$(OS_ARCH))) ifndef NO_INSTALL_IMPORT_LIBRARY IMPORT_LIB_FILES = $(IMPORT_LIBRARY) endif # NO_INSTALL_IMPORT_LIBRARY else IMPORT_LIB_FILES = $(SHARED_LIBRARY) endif IMPORT_LIB_DEST ?= $(DIST)/lib +IMPORT_LIB_TARGET = binaries libs ifdef IMPORT_LIB_FILES INSTALL_TARGETS += IMPORT_LIB endif endif # ! IS_COMPONENT endif # SHARED_LIBRARY ifneq (,$(strip $(HOST_SIMPLE_PROGRAMS)$(HOST_PROGRAM))) HOST_PROGRAMS_EXECUTABLES = $(HOST_SIMPLE_PROGRAMS) $(HOST_PROGRAM) HOST_PROGRAMS_DEST ?= $(DIST)/host/bin +HOST_PROGRAMS_TARGET = binaries libs INSTALL_TARGETS += HOST_PROGRAMS endif ifdef HOST_LIBRARY HOST_LIBRARY_FILES = $(HOST_LIBRARY) HOST_LIBRARY_DEST ?= $(DIST)/host/lib +HOST_LIBRARY_TARGET = binaries libs INSTALL_TARGETS += HOST_LIBRARY endif endif # !NO_DIST_INSTALL +ifdef MOZ_PSEUDO_DERECURSE +BINARIES_INSTALL_TARGETS := $(foreach category,$(INSTALL_TARGETS),$(if $(filter binaries,$($(category)_TARGET)),$(category))) + +ifneq (,$(strip $(BINARIES_INSTALL_TARGETS))) +# Fill a dependency file with all the binaries installed somewhere in $(DIST) +BINARIES_PP := $(MDDEPDIR)/binaries.pp + +$(BINARIES_PP): Makefile backend.mk $(call mkdir_deps,$(MDDEPDIR)) + @echo "$(strip $(foreach category,$(BINARIES_INSTALL_TARGETS),\ + $(foreach file,$($(category)_FILES) $($(category)_EXECUTABLES),\ + $($(category)_DEST)/$(notdir $(file)): $(file)%\ + )\ + ))" | tr % '\n' > $@ +endif + +binaries libs:: $(TARGETS) $(BINARIES_PP) +# Aggregate all dependency files relevant to a binaries build. If there is nothing +# done in the current directory, just create an empty stamp. +# Externally managed make files (gyp managed) and root make files (js/src/Makefile) +# need to be recursed to do their duty, and creating a stamp would prevent that. +# In the future, we'll aggregate those. +ifneq (.,$(DEPTH)) +ifndef EXTERNALLY_MANAGED_MAKE_FILE + @$(if $^,$(call py_action,link_deps,-o binaries --group-all --topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) $(BINARIES_PP) $(wildcard $(addsuffix .pp,$(addprefix $(MDDEPDIR)/,$(notdir $(sort $(filter-out $(BINARIES_PP),$^) $(OBJ_TARGETS))))))),$(TOUCH) binaries) +endif +endif + +else +binaries:: + $(error The binaries target is not supported without MOZ_PSEUDO_DERECURSE) +endif + # EOF
--- a/js/src/config/recurse.mk +++ b/js/src/config/recurse.mk @@ -28,31 +28,31 @@ ifeq (1_.,$(if $(MOZ_PSEUDO_DERECURSE),1 include root.mk # Disable build status for mach in top directories without TIERS. # In practice this disables it when recursing under js/src, which confuses mach. ifndef TIERS BUILDSTATUS = endif -# Main rules (export, compile, libs and tools) call recurse_* rules. +# Main rules (export, compile, binaries, libs and tools) call recurse_* rules. # This wrapping is only really useful for build status. -compile libs export tools:: +compile binaries libs export tools:: $(call BUILDSTATUS,TIER_START $@ $($@_subtiers)) +$(MAKE) recurse_$@ $(call BUILDSTATUS,TIER_FINISH $@) # Carefully avoid $(eval) type of rule generation, which makes pymake slower # than necessary. # Get current tier and corresponding subtiers from the data in root.mk. -CURRENT_TIER := $(filter $(foreach tier,compile libs export tools,recurse_$(tier)),$(MAKECMDGOALS)) +CURRENT_TIER := $(filter $(foreach tier,compile binaries libs export tools,recurse_$(tier) $(tier)-deps),$(MAKECMDGOALS)) ifneq (,$(filter-out 0 1,$(words $(CURRENT_TIER)))) $(error $(CURRENT_TIER) not supported on the same make command line) endif -CURRENT_TIER := $(subst recurse_,,$(CURRENT_TIER)) +CURRENT_TIER := $(subst recurse_,,$(CURRENT_TIER:-deps=)) CURRENT_SUBTIERS := $($(CURRENT_TIER)_subtiers) # The rules here are doing directory traversal, so we don't want further # recursion to happen when running make -C subdir $tier. But some make files # further call make -C something else, and sometimes expect recursion to # happen in that case (see browser/metro/locales/Makefile.in for example). # Conveniently, every invocation of make increases MAKELEVEL, so only stop # recursion from happening at current MAKELEVEL + 1. @@ -64,49 +64,93 @@ export NO_RECURSE_MAKELEVEL=$(word $(MAK endif endif # Get all directories traversed for all subtiers in the current tier, or use # directly the $(*_dirs) variables available in root.mk when there is no # TIERS (like for js/src). CURRENT_DIRS := $(or $($(CURRENT_TIER)_dirs),$(foreach subtier,$(CURRENT_SUBTIERS),$($(CURRENT_TIER)_subtier_$(subtier)))) +ifneq (,$(filter binaries libs,$(CURRENT_TIER))) +WANT_STAMPS = 1 +STAMP_TOUCH = $(TOUCH) $(@D)/binaries +endif + # Subtier delimiter rules -$(addprefix subtiers/,$(addsuffix _start/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_start/$(CURRENT_TIER): +$(addprefix subtiers/,$(addsuffix _start/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_start/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_start)) $(call BUILDSTATUS,SUBTIER_START $(CURRENT_TIER) $* $(if $(BUG_915535_FIXED),$($(CURRENT_TIER)_subtier_$*))) + @$(STAMP_TOUCH) -$(addprefix subtiers/,$(addsuffix _finish/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_finish/$(CURRENT_TIER): +$(addprefix subtiers/,$(addsuffix _finish/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_finish/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_finish)) $(call BUILDSTATUS,SUBTIER_FINISH $(CURRENT_TIER) $*) + @$(STAMP_TOUCH) + +$(addprefix subtiers/,$(addsuffix /$(CURRENT_TIER),$(CURRENT_SUBTIERS))): %/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,%)) + @$(STAMP_TOUCH) + +GARBAGE_DIRS += subtiers # Recursion rule for all directories traversed for all subtiers in the # current tier. # root.mk defines subtier_of_* variables, that map a normalized subdir path to # a subtier name (e.g. subtier_of_memory_jemalloc = base) -$(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): %/$(CURRENT_TIER): +$(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): %/$(CURRENT_TIER): $(if $(WANT_STAMPS),%/Makefile %/backend.mk) ifdef BUG_915535_FIXED $(call BUILDSTATUS,TIERDIR_START $(CURRENT_TIER) $(subtier_of_$(subst /,_,$*)) $*) endif +@$(MAKE) -C $* $(if $(filter $*,$(tier_$(subtier_of_$(subst /,_,$*))_staticdirs)),,$(CURRENT_TIER)) +# Ensure existing stamps are up-to-date, but don't create one if submake didn't create one. + $(if $(wildcard $@),@$(STAMP_TOUCH)) ifdef BUG_915535_FIXED $(call BUILDSTATUS,TIERDIR_FINISH $(CURRENT_TIER) $(subtier_of_$(subst /,_,$*)) $*) endif +# Dummy rules for possibly inexisting dependencies for the above tier targets +$(addsuffix /Makefile,$(CURRENT_DIRS)) $(addsuffix /backend.mk,$(CURRENT_DIRS)): + # The export tier requires nsinstall, which is built from config. So every # subdirectory traversal needs to happen after traversing config. ifeq ($(CURRENT_TIER),export) $(addsuffix /$(CURRENT_TIER),$(filter-out config,$(CURRENT_DIRS))): config/$(CURRENT_TIER) endif +ifneq (,$(filter libs binaries,$(CURRENT_TIER))) +# When doing a "libs" build, target_libs.mk ensures the interesting dependency data +# is available in the "binaries" stamp. Once recursion is done, aggregate all that +# dependency info so that stamps depend on relevant files and relevant other stamps. +# When doing a "binaries" build, the aggregate dependency file and those stamps are +# used and allow to skip recursing directories where changes are not going to require +# rebuild. A few directories, however, are still traversed all the time, mostly, the +# gyp managed ones and js/src. +# A few things that are not traversed by a "binaries" build, but should, in an ideal +# world, are nspr, nss, icu and ffi. +recurse_$(CURRENT_TIER): + @$(MAKE) binaries-deps + +# Creating binaries-deps.mk directly would make us build it twice: once when beginning +# the build because of the include, and once at the end because of the stamps. +binaries-deps: $(wildcard $(addsuffix /binaries,$(CURRENT_DIRS))) + @$(call py_action,link_deps,-o $@.mk --group-by-depfile --topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) --guard $(addprefix ",$(addsuffix ",$^))) + @$(TOUCH) $@ + +ifeq (recurse_binaries,$(MAKECMDGOALS)) +$(call include_deps,binaries-deps.mk) +endif + +endif + +DIST_GARBAGE += binaries-deps.mk binaries-deps + else # Don't recurse if MAKELEVEL is NO_RECURSE_MAKELEVEL as defined above, but # still recurse for externally managed make files (gyp-generated ones). ifeq ($(EXTERNALLY_MANAGED_MAKE_FILE)_$(NO_RECURSE_MAKELEVEL),_$(MAKELEVEL)) -compile libs export tools:: +compile binaries libs export tools:: else ######################### # Tier traversal handling ######################### ifdef TIERS @@ -134,17 +178,17 @@ endif $(1):: $$(SUBMAKEFILES) ifdef PARALLEL_DIRS +@$(MAKE) $$(PARALLEL_DIRS_$(1)) endif $$(LOOP_OVER_DIRS) endef -$(foreach subtier,export libs tools,$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier)))) +$(foreach subtier,export compile binaries libs tools,$(eval $(call CREATE_SUBTIER_TRAVERSAL_RULE,$(subtier)))) tools export:: $(SUBMAKEFILES) $(LOOP_OVER_TOOL_DIRS) endif # ifdef TIERS endif # ifeq ($(EXTERNALLY_MANAGED_MAKE_FILE)_$(NO_RECURSE_MAKELEVEL),_$(MAKELEVEL))
--- a/js/src/config/rules.mk +++ b/js/src/config/rules.mk @@ -724,17 +724,19 @@ HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX # Dependencies which, if modified, should cause everything to rebuild GLOBAL_DEPS += Makefile $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk ifndef NO_MAKEFILE_RULE GLOBAL_DEPS += Makefile.in endif ############################################## -compile:: $(OBJS) $(HOST_OBJS) +OBJ_TARGETS = $(OBJS) $(PROGOBJS) $(HOST_OBJS) $(HOST_PROGOBJS) + +compile:: $(OBJ_TARGETS) include $(topsrcdir)/config/makefiles/target_libs.mk ifdef IS_TOOL_DIR # One would think "tools:: libs" would work, but it turns out that combined with # bug 907365, this makes make forget to run some rules sometimes. tools:: @$(MAKE) libs
--- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -427,20 +427,21 @@ class RecursiveMakeBackend(CommonBackend return current, subdirs.parallel, \ subdirs.dirs + subdirs.tests + subdirs.tools # Skip tools dirs during libs traversal def libs_filter(current, subdirs): return current, subdirs.parallel, \ subdirs.static + subdirs.dirs + subdirs.tests - # compile and tools tiers use the same traversal as export + # compile, binaries and tools tiers use the same traversal as export filters = { 'export': export_filter, 'compile': parallel_filter, + 'binaries': parallel_filter, 'libs': libs_filter, 'tools': parallel_filter, } root_deps_mk = Makefile() # Fill the dependencies for traversal of each tier. for tier, filter in filters.items():