If compilation was invoked as make -j, pass serialization didn't work.
In other words, it was possible that, for example, some library-pass
targets was made before all include-pass targets was finished. This
meant all include files were not available for compilation of libraries.
This behavior was caused the fact that recently introduced <pass>-XXX-subdir
targets was direct dependencies of <pass>. Since pass serialization is
done by putting one pass as dependency of another pass, this
serialization dependencies was on the "same level" as -subdir
dependencies and make -j executed them in parallel.
This was fixed by adding another target called <pass>-submakes which is
called recursively from <pass> target after all "serialization
dependencies" are processed. All -subdir targets are dependencies of
only -submakes target and hence are not intermixed with serialization
dependencies.
To avoid overhead caused by this additional recursive make invocation,
all recursive makes are invoked directly with the new -submakes target
as their goal. Hence, the original pass target is called only in the
top-level make.
This change can influence some "nonstandard" constructs used sometimes
in Makefile.omk that count upon invocation of the original pass in every
directory. This issue will be solved by upcoming patches.
darcs-hash:
20080418154711-f2ef6-
365337cb69c6aeb0eb659c6f2ad74605d80de1d8.gz
# Usage: $(call omk_pass_subdir_template,<pass name>,<build dir>,<subdir>)
define omk_pass_subdir_template
.PHONY: $(1)-$(3)-subdir
-$(1): $(1)-$(3)-subdir
+$(1)-submakes: $(1)-$(3)-subdir
$(1)-$(3)-subdir:
@$(call mkdir_def,$(2)/$(3))
+@$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(3) $(NO_PRINT_DIRECTORY) \
RELATIVE_DIR=$(RELATIVE_PREFIX)$(3) -C $(2)/$(3) \
- -f $(SUBDIR_MAKEFILE) $(1)
+ -f $(SUBDIR_MAKEFILE) $(1)-submakes
+# In subdirectories we can call submakes directly since passes are
+# already searialized on the toplevel make.
endef
ifdef OMK_TESTSROOT
# Usage: $(call omk_pass_template,<pass name>,<build dir>,[<local make flags>],[<local enable condition>])
define omk_pass_template
-.PHONY: $(1) $(addsuffix -local,$(1)) $(addsuffix -check,$(1))
+.PHONY: $(1) $(1)-local $(1)-check $(1)-submakes
$(foreach subdir,$(SUBDIRS),$(eval $(call omk_pass_subdir_template,$(1),$(2),$(subdir))))
$(1):
+# Submakes have to be called this way and not as dependecies for pass
+# serialization to work
+ +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR) --no-print-directory \
+ RELATIVE_DIR=$(RELATIVE_DIR) \
+ -f $(SOURCESDIR_MAKEFILE) $(1)-submakes
+$(1)-submakes:
@true # Do not emit "nothing to be done" messages
+
ifneq ($(4),)
-$(1): $(1)-this-dir
+$(1)-submakes: $(1)-this-dir
$(1)-this-dir: $(foreach subdir,$(SUBDIRS),$(1)-$(subdir)-subdir)
+@echo "make[omk]: $(strip $(1)) in $(RELATIVE_DIR)"
@$(call mkdir_def,$(2))
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" == `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+SUBDIRS=dir1 dir2 dir3
--- /dev/null
+# Start of OMK config file
+# This file should not be altered manually
+# Overrides should be stored in file config.omk
+
+# Config for dir1/
+# Config for dir2/
+# Config for dir3/
+# Config for
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" == `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+$(info $(MAKECMDGOALS))
+
+%-pass: %-pass-message
+
+%-pass-message:
+ @echo $@
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" == `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+$(info $(MAKECMDGOALS))
+
+%-pass-local: %-pass-message
+
+%-pass-message:
+ @echo $@
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" == `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+$(info $(MAKECMDGOALS))
+
+%-pass-local: %-pass-message
+
+%-pass-message:
+ @echo $@
--- /dev/null
+#!/bin/sh
+
+. ../functions.sh
+
+make -j | grep -vE '(^make\[.*\]|-local$)' > passes
+
+cat passes|uniq > passes.uniq
+LINES_UNIQ=`cat passes.uniq|wc -l`
+
+cat passes|sort|uniq > passes.sort.uniq
+LINES_SORT_UNIQ=`cat passes.sort.uniq|wc -l`
+
+if [ x"$LINES_UNIQ" != x"$LINES_SORT_UNIQ" ]; then
+ echo "=== passes.uniq ==="
+ cat passes.uniq
+ echo "=== passes.sort.uniq ==="
+ cat passes.sort.uniq
+ error "Passes are not correctly serialized under parallel make"
+fi