From 162850b332acdce6d68d010f3aa0c8beb03ec5ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= <rene.kijewski@fu-berlin.de>
Date: Sun, 26 Oct 2014 23:18:58 +0100
Subject: [PATCH] make: Implement optional features

Fixes #1876

This PR introduces `FEATURES_OPTIONAL` which can be used to tell the
Make system, that the application would like to use some feature, but
the build should proceed even if the selected board cannot provide the
optional feature.

`make buildtest` and `make info-supported-boards` heed this variable
when examining the list of supported boards.

If a word is present in `FEATURES_REQUIRED` and `FEATURES_OPTIONAL`,
then `FEATURES_OPTIONAL` takes precedence.
---
 Makefile.buildtests       | 19 ++++++++++++++++---
 Makefile.include          |  4 ++--
 examples/default/Makefile |  2 ++
 3 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/Makefile.buildtests b/Makefile.buildtests
index 1c161ef8ef..fde12f6974 100644
--- a/Makefile.buildtests
+++ b/Makefile.buildtests
@@ -169,8 +169,16 @@ info-build:
 	@echo 'ELFFILE: $(ELFFILE)'
 	@echo 'HEXFILE: $(HEXFILE)'
 	@echo ''
-	@echo 'FEATURES_REQUIRED: $(sort $(FEATURES_REQUIRED))'
-	@echo 'FEATURES_PROVIDED: $(sort $(FEATURES_PROVIDED))'
+	@echo 'FEATURES_REQUIRED (excl. optional features):'
+	@echo '         $(or $(sort $(filter-out $(FEATURES_OPTIONAL), $(FEATURES_REQUIRED))), -none-)'
+	@echo 'FEATURES_OPTIONAL (strictly "nice to have"):'
+	@echo '         $(or $(sort $(FEATURES_OPTIONAL)), -none-)'
+	@echo 'FEATURES_PROVIDED (by the board):'
+	@echo '         $(or $(sort $(FEATURES_PROVIDED)), -none-)'
+	@echo 'FEATURES_MISSING (incl. optional features):'
+	@echo '         $(or $(sort $(filter-out $(FEATURES_PROVIDED), $(FEATURES_REQUIRED))), -none-)'
+	@echo 'FEATURES_MISSING (only non-optional features):'
+	@echo '         $(or $(sort $(filter-out $(FEATURES_OPTIONAL) $(FEATURES_PROVIDED), $(FEATURES_REQUIRED))), -none-)'
 	@echo ''
 	@echo 'CC:      $(CC)'
 	@echo -e 'CFLAGS:$(patsubst %, \n\t%, $(CFLAGS))'
@@ -215,6 +223,8 @@ info-features-missing:
 info-boards-features-missing:
 	@for f in $(BOARDS_FEATURES_MISSING); do echo $${f}; done | column -t
 
+FEATURES_REQUIRED += $(FEATURES_OPTIONAL)
+
 ifneq (, $(filter info-boards-supported info-boards-features-missing info-build, $(MAKECMDGOALS)))
   FEATURES_PROVIDED_BAK := $(FEATURES_PROVIDED)
 
@@ -224,8 +234,11 @@ ifneq (, $(filter info-boards-supported info-boards-features-missing info-build,
 
     FEATURES_MISSING := $$(filter-out $$(FEATURES_PROVIDED), $$(FEATURES_REQUIRED))
     ifneq (, $${FEATURES_MISSING})
-      BOARDS_WITH_MISSING_FEATURES += ${1}
       BOARDS_FEATURES_MISSING += "${1} $${FEATURES_MISSING}"
+
+      ifneq (, $$(filter-out $$(FEATURES_OPTIONAL), $$(FEATURES_MISSING)))
+        BOARDS_WITH_MISSING_FEATURES += ${1}
+      endif
     endif
   endef
 
diff --git a/Makefile.include b/Makefile.include
index 5daf23058c..16a34ee622 100644
--- a/Makefile.include
+++ b/Makefile.include
@@ -219,9 +219,9 @@ ifneq (, $(filter all, $(if $(MAKECMDGOALS), $(MAKECMDGOALS), all)))
   endif
 
   # Test if all feature requirements were met by the selected board.
-  ifneq (, $(filter-out $(FEATURES_PROVIDED), $(FEATURES_REQUIRED)))
+  ifneq (, $(filter-out $(FEATURES_PROVIDED) $(FEATURES_OPTIONAL), $(FEATURES_REQUIRED)))
     $(shell $(COLOR_ECHO) "$(COLOR_RED)There are unsatisfied feature requirements:$(COLOR_RESET)"\
-                          "$(filter-out $(FEATURES_PROVIDED), $(FEATURES_REQUIRED))" 1>&2)
+                          "$(sort $(filter-out $(FEATURES_PROVIDED) $(FEATURES_OPTIONAL), $(FEATURES_REQUIRED)))" 1>&2)
     EXPECT_ERRORS := 1
   endif
 
diff --git a/examples/default/Makefile b/examples/default/Makefile
index 33746afc9c..fa481bfd49 100644
--- a/examples/default/Makefile
+++ b/examples/default/Makefile
@@ -36,6 +36,8 @@ USEMODULE += ps
 USEMODULE += vtimer
 USEMODULE += defaulttransceiver
 
+FEATURES_OPTIONAL += transceiver
+
 ifneq (,$(filter msb-430,$(BOARD)))
 	USEMODULE += sht11
 endif
-- 
GitLab