From ff506fa72fa1df6d457c64f14a12204b54cf69ab Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Fri, 18 Apr 2008 15:47:00 +0000 Subject: [PATCH] Fixed problem with parallel make (-j) caused by the previous change 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 -XXX-subdir targets was direct dependencies of . 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 -submakes which is called recursively from 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 --- snippets/base | 17 +++++++++++++---- tests/parallel_make/Makefile | 14 ++++++++++++++ tests/parallel_make/Makefile.omk | 1 + tests/parallel_make/config.omk-default | 8 ++++++++ tests/parallel_make/dir1/Makefile | 14 ++++++++++++++ tests/parallel_make/dir1/Makefile.omk | 6 ++++++ tests/parallel_make/dir2/Makefile | 14 ++++++++++++++ tests/parallel_make/dir2/Makefile.omk | 6 ++++++ tests/parallel_make/dir3/Makefile | 14 ++++++++++++++ tests/parallel_make/dir3/Makefile.omk | 6 ++++++ tests/parallel_make/runtest | 19 +++++++++++++++++++ 11 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 tests/parallel_make/Makefile create mode 100644 tests/parallel_make/Makefile.omk create mode 100644 tests/parallel_make/config.omk-default create mode 100644 tests/parallel_make/dir1/Makefile create mode 100644 tests/parallel_make/dir1/Makefile.omk create mode 100644 tests/parallel_make/dir2/Makefile create mode 100644 tests/parallel_make/dir2/Makefile.omk create mode 100644 tests/parallel_make/dir3/Makefile create mode 100644 tests/parallel_make/dir3/Makefile.omk create mode 100755 tests/parallel_make/runtest diff --git a/snippets/base b/snippets/base index bc9622b..6e352d0 100644 --- a/snippets/base +++ b/snippets/base @@ -179,12 +179,14 @@ endif # Usage: $(call omk_pass_subdir_template,,,) 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 @@ -193,12 +195,19 @@ endif # Usage: $(call omk_pass_template,,,[],[]) 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)) diff --git a/tests/parallel_make/Makefile b/tests/parallel_make/Makefile new file mode 100644 index 0000000..f595272 --- /dev/null +++ b/tests/parallel_make/Makefile @@ -0,0 +1,14 @@ +# 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 + diff --git a/tests/parallel_make/Makefile.omk b/tests/parallel_make/Makefile.omk new file mode 100644 index 0000000..c96b4b1 --- /dev/null +++ b/tests/parallel_make/Makefile.omk @@ -0,0 +1 @@ +SUBDIRS=dir1 dir2 dir3 diff --git a/tests/parallel_make/config.omk-default b/tests/parallel_make/config.omk-default new file mode 100644 index 0000000..8c3d55e --- /dev/null +++ b/tests/parallel_make/config.omk-default @@ -0,0 +1,8 @@ +# 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 diff --git a/tests/parallel_make/dir1/Makefile b/tests/parallel_make/dir1/Makefile new file mode 100644 index 0000000..f595272 --- /dev/null +++ b/tests/parallel_make/dir1/Makefile @@ -0,0 +1,14 @@ +# 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 + diff --git a/tests/parallel_make/dir1/Makefile.omk b/tests/parallel_make/dir1/Makefile.omk new file mode 100644 index 0000000..5076c89 --- /dev/null +++ b/tests/parallel_make/dir1/Makefile.omk @@ -0,0 +1,6 @@ +$(info $(MAKECMDGOALS)) + +%-pass: %-pass-message + +%-pass-message: + @echo $@ diff --git a/tests/parallel_make/dir2/Makefile b/tests/parallel_make/dir2/Makefile new file mode 100644 index 0000000..f595272 --- /dev/null +++ b/tests/parallel_make/dir2/Makefile @@ -0,0 +1,14 @@ +# 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 + diff --git a/tests/parallel_make/dir2/Makefile.omk b/tests/parallel_make/dir2/Makefile.omk new file mode 100644 index 0000000..364cce6 --- /dev/null +++ b/tests/parallel_make/dir2/Makefile.omk @@ -0,0 +1,6 @@ +$(info $(MAKECMDGOALS)) + +%-pass-local: %-pass-message + +%-pass-message: + @echo $@ diff --git a/tests/parallel_make/dir3/Makefile b/tests/parallel_make/dir3/Makefile new file mode 100644 index 0000000..f595272 --- /dev/null +++ b/tests/parallel_make/dir3/Makefile @@ -0,0 +1,14 @@ +# 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 + diff --git a/tests/parallel_make/dir3/Makefile.omk b/tests/parallel_make/dir3/Makefile.omk new file mode 100644 index 0000000..364cce6 --- /dev/null +++ b/tests/parallel_make/dir3/Makefile.omk @@ -0,0 +1,6 @@ +$(info $(MAKECMDGOALS)) + +%-pass-local: %-pass-message + +%-pass-message: + @echo $@ diff --git a/tests/parallel_make/runtest b/tests/parallel_make/runtest new file mode 100755 index 0000000..2c8edf4 --- /dev/null +++ b/tests/parallel_make/runtest @@ -0,0 +1,19 @@ +#!/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 -- 2.39.2