From 7f29c468d7bfce620f49ba1c0898bc68e95597f3 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Tue, 10 Jul 2012 18:30:41 +0000
Subject: [PATCH] Slightly better method of recursive make - use proper make
 dependencies to allow for parallel builds.

---
 Bootloaders/makefile                | 21 +++++++++++++++++----
 Demos/Device/ClassDriver/makefile   | 21 +++++++++++++++++----
 Demos/Device/LowLevel/makefile      | 21 +++++++++++++++++----
 Demos/DualRole/ClassDriver/makefile | 20 ++++++++++++++++----
 Demos/Host/ClassDriver/makefile     | 21 +++++++++++++++++----
 Demos/Host/LowLevel/makefile        | 21 +++++++++++++++++----
 Projects/makefile                   | 22 ++++++++++++++++++----
 7 files changed, 119 insertions(+), 28 deletions(-)

diff --git a/Bootloaders/makefile b/Bootloaders/makefile
index 01aa506fd..ba4f51259 100644
--- a/Bootloaders/makefile
+++ b/Bootloaders/makefile
@@ -22,10 +22,23 @@ ifeq ($(MAKELEVEL), 10)
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-all:
+# If building without a per-project object directory, we can't build in parallel
 ifeq ($(OBJDIR),)
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) clean all;)
+   .NOTPARALLEL:
+
+   # Ensure projects are pre-cleaned if the target is the default or "all"
+   ifeq ($(MAKECMDGOALS),)
+      MAKECMDGOALS := clean all
+   endif
+   ifneq ($(findstring all, $(MAKECMDGOALS)),)
+      MAKECMDGOALS := clean $(MAKECMDGOALS)
+   endif
 endif
 
-%:
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) $@;)
+%: $(PROJECT_DIRECTORIES)
+	@echo . > /dev/null
+
+$(PROJECT_DIRECTORIES):
+	@$(MAKE) -C $@ $(MAKECMDGOALS)
+    
+.PHONY: $(PROJECT_DIRECTORIES)
diff --git a/Demos/Device/ClassDriver/makefile b/Demos/Device/ClassDriver/makefile
index ad8800091..3a5615e05 100644
--- a/Demos/Device/ClassDriver/makefile
+++ b/Demos/Device/ClassDriver/makefile
@@ -22,10 +22,23 @@ ifeq ($(MAKELEVEL), 10)
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-all:
+# If building without a per-project object directory, we can't build in parallel
 ifeq ($(OBJDIR),)
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) clean all;)
+   .NOTPARALLEL:
+
+   # Ensure projects are pre-cleaned if the target is the default or "all"
+   ifeq ($(MAKECMDGOALS),)
+      MAKECMDGOALS := clean all
+   endif
+   ifneq ($(findstring all, $(MAKECMDGOALS)),)
+      MAKECMDGOALS := clean $(MAKECMDGOALS)
+   endif
 endif
 
-%:
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) $@;)
+%: $(PROJECT_DIRECTORIES)
+	@echo . > /dev/null
+
+$(PROJECT_DIRECTORIES):
+	@$(MAKE) -C $@ $(MAKECMDGOALS)
+    
+.PHONY: $(PROJECT_DIRECTORIES)
diff --git a/Demos/Device/LowLevel/makefile b/Demos/Device/LowLevel/makefile
index ad8800091..3a5615e05 100644
--- a/Demos/Device/LowLevel/makefile
+++ b/Demos/Device/LowLevel/makefile
@@ -22,10 +22,23 @@ ifeq ($(MAKELEVEL), 10)
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-all:
+# If building without a per-project object directory, we can't build in parallel
 ifeq ($(OBJDIR),)
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) clean all;)
+   .NOTPARALLEL:
+
+   # Ensure projects are pre-cleaned if the target is the default or "all"
+   ifeq ($(MAKECMDGOALS),)
+      MAKECMDGOALS := clean all
+   endif
+   ifneq ($(findstring all, $(MAKECMDGOALS)),)
+      MAKECMDGOALS := clean $(MAKECMDGOALS)
+   endif
 endif
 
-%:
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) $@;)
+%: $(PROJECT_DIRECTORIES)
+	@echo . > /dev/null
+
+$(PROJECT_DIRECTORIES):
+	@$(MAKE) -C $@ $(MAKECMDGOALS)
+    
+.PHONY: $(PROJECT_DIRECTORIES)
diff --git a/Demos/DualRole/ClassDriver/makefile b/Demos/DualRole/ClassDriver/makefile
index 741383f18..71fb805ef 100644
--- a/Demos/DualRole/ClassDriver/makefile
+++ b/Demos/DualRole/ClassDriver/makefile
@@ -22,11 +22,23 @@ ifeq ($(MAKELEVEL), 10)
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-all:
+# If building without a per-project object directory, we can't build in parallel
 ifeq ($(OBJDIR),)
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) clean all;)
+   .NOTPARALLEL:
+
+   # Ensure projects are pre-cleaned if the target is the default or "all"
+   ifeq ($(MAKECMDGOALS),)
+      MAKECMDGOALS := clean all
+   endif
+   ifneq ($(findstring all, $(MAKECMDGOALS)),)
+      MAKECMDGOALS := clean $(MAKECMDGOALS)
+   endif
 endif
 
-%:
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) $@;)
+%: $(PROJECT_DIRECTORIES)
+	@echo . > /dev/null
 
+$(PROJECT_DIRECTORIES):
+	@$(MAKE) -C $@ $(MAKECMDGOALS)
+    
+.PHONY: $(PROJECT_DIRECTORIES)
diff --git a/Demos/Host/ClassDriver/makefile b/Demos/Host/ClassDriver/makefile
index d9a3dc359..a2b14c8a6 100644
--- a/Demos/Host/ClassDriver/makefile
+++ b/Demos/Host/ClassDriver/makefile
@@ -22,10 +22,23 @@ ifeq ($(MAKELEVEL), 10)
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-all:
+# If building without a per-project object directory, we can't build in parallel
 ifeq ($(OBJDIR),)
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) clean all;)
+   .NOTPARALLEL:
+
+   # Ensure projects are pre-cleaned if the target is the default or "all"
+   ifeq ($(MAKECMDGOALS),)
+      MAKECMDGOALS := clean all
+   endif
+   ifneq ($(findstring all, $(MAKECMDGOALS)),)
+      MAKECMDGOALS := clean $(MAKECMDGOALS)
+   endif
 endif
 
-%:
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) $@;)
+%: $(PROJECT_DIRECTORIES)
+	@echo . > /dev/null
+
+$(PROJECT_DIRECTORIES):
+	@$(MAKE) -C $@ $(MAKECMDGOALS)
+    
+.PHONY: $(PROJECT_DIRECTORIES)
diff --git a/Demos/Host/LowLevel/makefile b/Demos/Host/LowLevel/makefile
index d9a3dc359..a2b14c8a6 100644
--- a/Demos/Host/LowLevel/makefile
+++ b/Demos/Host/LowLevel/makefile
@@ -22,10 +22,23 @@ ifeq ($(MAKELEVEL), 10)
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-all:
+# If building without a per-project object directory, we can't build in parallel
 ifeq ($(OBJDIR),)
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) clean all;)
+   .NOTPARALLEL:
+
+   # Ensure projects are pre-cleaned if the target is the default or "all"
+   ifeq ($(MAKECMDGOALS),)
+      MAKECMDGOALS := clean all
+   endif
+   ifneq ($(findstring all, $(MAKECMDGOALS)),)
+      MAKECMDGOALS := clean $(MAKECMDGOALS)
+   endif
 endif
 
-%:
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) $@;)
+%: $(PROJECT_DIRECTORIES)
+	@echo . > /dev/null
+
+$(PROJECT_DIRECTORIES):
+	@$(MAKE) -C $@ $(MAKECMDGOALS)
+    
+.PHONY: $(PROJECT_DIRECTORIES)
diff --git a/Projects/makefile b/Projects/makefile
index 2bc9f98b1..ec8e65b8b 100644
--- a/Projects/makefile
+++ b/Projects/makefile
@@ -22,10 +22,24 @@ ifeq ($(MAKELEVEL), 10)
    $(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
 endif
 
-all:
+# If building without a per-project object directory, we can't build in parallel
 ifeq ($(OBJDIR),)
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) clean all;)
+   .NOTPARALLEL:
+
+   # Ensure projects are pre-cleaned if the target is the default or "all"
+   ifeq ($(MAKECMDGOALS),)
+      MAKECMDGOALS := clean all
+   endif
+   ifneq ($(findstring all, $(MAKECMDGOALS)),)
+      MAKECMDGOALS := clean $(MAKECMDGOALS)
+   endif
 endif
 
-%:
-	@$(foreach PROJECT, $(PROJECT_DIRECTORIES), $(MAKE) -C $(PROJECT) $@;)
+%: $(PROJECT_DIRECTORIES)
+	@echo . > /dev/null
+
+$(PROJECT_DIRECTORIES):
+	@$(MAKE) -C $@ $(MAKECMDGOALS)
+    
+.PHONY: $(PROJECT_DIRECTORIES)
+
-- 
GitLab