mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 00:49:45 +01:00
d29652350b
Failing to provide any of the required features can provide a message such as: There are unsatisfied feature requirements: periph_uart|periph_lpuart This can be confusing and may hide the actual. E.g. above message was generated when using SPI on the `msb-430` and `stdio_uart`. However, the MSB-430 board *does* provide `periph_uart`, so this looks like a bug in the feature resolution. This changes the failure mode of `FEATURES_REQUIRED_ANY` to just pick the first of the alternatives given if none of the alternative is usable, which gives in the example the following message instead: The following features may conflict: periph_spi periph_uart Rationale: Both SPI and UART are provided by the same USART peripheral The output is less surprising and can provide non-obvious reasons why `FEATURES_REQUIRED_ANY` failed to pick a feature. The downside is that the alternatives are no longer visible. However, that output likely was so confusing this might be for the best. Co-authored-by: mguetschow <mikolai.guetschow@tu-dresden.de>
88 lines
4.6 KiB
Makefile
88 lines
4.6 KiB
Makefile
# Check if all required FEATURES are provided
|
|
|
|
# Features that are used without taking "one out of" dependencies into account
|
|
FEATURES_USED_SO_FAR := $(sort $(FEATURES_REQUIRED) $(FEATURES_OPTIONAL_USED))
|
|
|
|
# Get features which inclusion would cause a conflict
|
|
# Parameter 1: Features currently used
|
|
# Parameter 2: A set of features that would conflict (separated by spaces)
|
|
# Algorithm: If interaction of the two lists is empty, return an empty set. Otherwise return
|
|
# the set of conflicting features without the feature in it that is already used
|
|
_features_would_conflict = $(if $(filter $1,$2),$(filter-out $1,$2))
|
|
# Adding any of the following features would result in a feature conflict with the already used
|
|
# features:
|
|
FEATURES_WOULD_CONFLICT := $(foreach conflict,$(FEATURES_CONFLICT),\
|
|
$(call _features_would_conflict,\
|
|
$(FEATURES_USED_SO_FAR),$(subst :, ,$(conflict))))
|
|
|
|
# Features that are provided, not blacklisted, and do not conflict with any used feature
|
|
FEATURES_USABLE := $(filter-out $(FEATURES_BLACKLIST) $(FEATURES_WOULD_CONFLICT),\
|
|
$(FEATURES_PROVIDED))
|
|
|
|
# Features that may be used, if provided.
|
|
FEATURES_OPTIONAL_ONLY := $(sort $(filter-out $(FEATURES_REQUIRED),$(FEATURES_OPTIONAL)))
|
|
|
|
# Optional features that end up being used
|
|
FEATURES_OPTIONAL_USED := $(sort $(filter $(FEATURES_USABLE),$(FEATURES_OPTIONAL_ONLY)))
|
|
|
|
# Optional features that will not be used because they are not provided or blacklisted
|
|
FEATURES_OPTIONAL_MISSING := $(sort $(filter-out $(FEATURES_USABLE),$(FEATURES_OPTIONAL_ONLY)))
|
|
|
|
# Update to account for change in FEATURES_OPTIONAL_USED
|
|
FEATURES_USED_SO_FAR := $(sort $(FEATURES_REQUIRED) $(FEATURES_OPTIONAL_USED))
|
|
|
|
# Additionally required features due to the "one out of" dependencies
|
|
# Algorithm:
|
|
# - For each list in FEATURES_REQUIRED_ANY as "item":
|
|
# - Store the intersection of FEATURES_USED_SO_FAR and the features in
|
|
# "item" in "tmp"
|
|
# - Append the intersection of FEATURES_USABLE and the features in "item"
|
|
# to "tmp"
|
|
# - Append "item" to "tmp" (with pipes between features, e.g.
|
|
# "periph_spi|periph_i2c")
|
|
# - Append the first element of "tmp" to FEATURES_REQUIRED_ONE_OUT_OF
|
|
# ==> If one (or more) already used features is listed in item, this (or
|
|
# one of these) will be in the front of "tmp" and be taken
|
|
# ==> If one (or more) usable features is listed in item, this will come
|
|
# afterwards. If no feature in item is used so far, one of the
|
|
# features supported and listed in item will be picked
|
|
# ==> At the end of the list, feature alternatives in item itself are added.
|
|
# If no feature in item is already used or usable, the first alternative is
|
|
# just added, triggering a warning about a feature being missing or
|
|
# conflicting later on.
|
|
FEATURES_REQUIRED_ONE_OUT_OF := $(foreach item,\
|
|
$(FEATURES_REQUIRED_ANY),\
|
|
$(word 1,\
|
|
$(filter $(FEATURES_USED_SO_FAR),$(subst |, ,$(item)))\
|
|
$(filter $(FEATURES_USABLE),$(subst |, ,$(item)))\
|
|
$(subst |, ,$(item))))
|
|
|
|
# Features that are required by the application but not provided by the BSP
|
|
# Having features missing may case the build to fail.
|
|
FEATURES_MISSING := $(sort \
|
|
$(filter-out $(FEATURES_PROVIDED),\
|
|
$(FEATURES_REQUIRED) $(FEATURES_REQUIRED_ONE_OUT_OF)))
|
|
|
|
# Features that are used for an application
|
|
FEATURES_USED := $(sort $(FEATURES_REQUIRED) \
|
|
$(FEATURES_REQUIRED_ONE_OUT_OF) \
|
|
$(FEATURES_OPTIONAL_USED))
|
|
|
|
# Return conflicting features from the conflict string feature1:feature2
|
|
# $1: feature1:feature2
|
|
# Return the list of conflicting features
|
|
_features_conflicting = $(if $(call _features_used_conflicting,$(subst :, ,$1)),$(subst :, ,$1))
|
|
# Check if all features from the list are used
|
|
# $1: list of features that conflict together
|
|
# Return non empty on error
|
|
_features_used_conflicting = $(filter $(words $1),$(words $(filter $(FEATURES_USED),$1)))
|
|
|
|
# Used features that conflict when used together
|
|
FEATURES_CONFLICTING := $(sort $(foreach conflict,\
|
|
$(FEATURES_CONFLICT),\
|
|
$(call _features_conflicting,$(conflict))))
|
|
|
|
# Features that are used by the application but blacklisted by the BSP.
|
|
# Having blacklisted features may cause the build to fail.
|
|
FEATURES_USED_BLACKLISTED := $(sort $(filter $(FEATURES_USED), $(FEATURES_BLACKLIST)))
|