]> rtime.felk.cvut.cz Git - omk.git/commitdiff
Fixed problem with parallel make (-j) caused by the previous change
authorMichal Sojka <sojkam1@fel.cvut.cz>
Fri, 18 Apr 2008 15:47:00 +0000 (15:47 +0000)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Fri, 18 Apr 2008 15:47:00 +0000 (15:47 +0000)
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

snippets/base
tests/parallel_make/Makefile [new file with mode: 0644]
tests/parallel_make/Makefile.omk [new file with mode: 0644]
tests/parallel_make/config.omk-default [new file with mode: 0644]
tests/parallel_make/dir1/Makefile [new file with mode: 0644]
tests/parallel_make/dir1/Makefile.omk [new file with mode: 0644]
tests/parallel_make/dir2/Makefile [new file with mode: 0644]
tests/parallel_make/dir2/Makefile.omk [new file with mode: 0644]
tests/parallel_make/dir3/Makefile [new file with mode: 0644]
tests/parallel_make/dir3/Makefile.omk [new file with mode: 0644]
tests/parallel_make/runtest [new file with mode: 0755]

index bc9622be6bd2419b8618c57da4095b8954428196..6e352d0be9b38d1b3dbfe5a59a1d567df54df816 100644 (file)
@@ -179,12 +179,14 @@ endif
 # 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
@@ -193,12 +195,19 @@ endif
 
 # 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))
diff --git a/tests/parallel_make/Makefile b/tests/parallel_make/Makefile
new file mode 100644 (file)
index 0000000..f595272
--- /dev/null
@@ -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 (file)
index 0000000..c96b4b1
--- /dev/null
@@ -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 (file)
index 0000000..8c3d55e
--- /dev/null
@@ -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 (file)
index 0000000..f595272
--- /dev/null
@@ -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 (file)
index 0000000..5076c89
--- /dev/null
@@ -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 (file)
index 0000000..f595272
--- /dev/null
@@ -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 (file)
index 0000000..364cce6
--- /dev/null
@@ -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 (file)
index 0000000..f595272
--- /dev/null
@@ -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 (file)
index 0000000..364cce6
--- /dev/null
@@ -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 (executable)
index 0000000..2c8edf4
--- /dev/null
@@ -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