summaryrefslogtreecommitdiff
path: root/mk/checkconf.mk
diff options
context:
space:
mode:
Diffstat (limited to 'mk/checkconf.mk')
-rw-r--r--mk/checkconf.mk162
1 files changed, 162 insertions, 0 deletions
diff --git a/mk/checkconf.mk b/mk/checkconf.mk
new file mode 100644
index 0000000..b40af81
--- /dev/null
+++ b/mk/checkconf.mk
@@ -0,0 +1,162 @@
+# Generate/check/update a .h file to reflect the values of Makefile
+# variables
+#
+# Example usage (by default, check-conf-h will consider all CFG_*
+# and _CFG_* variables plus PLATFORM_*):
+#
+# path/to/conf.h: FORCE
+# $(call check-conf-h)
+#
+# Or, to include only the variables with the given prefix(es):
+#
+# path/to/crypto_config.h: FORCE
+# $(call check-conf-h,CFG_CRYPTO_ CRYPTO_)
+define check-conf-h
+ $(q)set -e; \
+ $(cmd-echo-silent) ' CHK $@'; \
+ cnf='$(strip $(foreach var, \
+ $(call cfg-vars-by-prefix,$1), \
+ $(call cfg-make-define,$(var))))'; \
+ guard="_`echo $@ | tr -- -/. ___`_"; \
+ mkdir -p $(dir $@); \
+ echo "#ifndef $${guard}" >$@.tmp; \
+ echo "#define $${guard}" >>$@.tmp; \
+ echo -n "$${cnf}" | sed 's/_nl_ */\n/g' >>$@.tmp; \
+ echo "#endif" >>$@.tmp; \
+ $(call mv-if-changed,$@.tmp,$@)
+endef
+
+define check-conf-mk
+ $(q)set -e; \
+ $(cmd-echo-silent) ' CHK $@'; \
+ cnf='$(strip $(foreach var, \
+ $(call cfg-vars-by-prefix,CFG_), \
+ $(strip $(var)=$($(var))_nl_)))'; \
+ mkdir -p $(dir $@); \
+ echo "# auto-generated TEE configuration file" >$@.tmp; \
+ echo "# TEE version ${TEE_IMPL_VERSION}" >>$@.tmp; \
+ echo "ARCH=${ARCH}" >>$@.tmp; \
+ echo "PLATFORM=${PLATFORM}" >>$@.tmp; \
+ echo "PLATFORM_FLAVOR=${PLATFORM_FLAVOR}" >>$@.tmp; \
+ echo -n "$${cnf}" | sed 's/_nl_ */\n/g' >>$@.tmp; \
+ $(call mv-if-changed,$@.tmp,$@)
+endef
+
+# Rename $1 to $2 only if file content differs. Otherwise just delete $1.
+define mv-if-changed
+ if [ -r $2 ] && cmp -s $2 $1; then \
+ rm -f $1; \
+ else \
+ $(cmd-echo-silent) ' UPD $2'; \
+ mv $1 $2; \
+ fi
+endef
+
+define cfg-vars-by-prefix
+ $(strip $(if $(1),$(call _cfg-vars-by-prefix,$(1)),
+ $(call _cfg-vars-by-prefix,CFG_ _CFG_ PLATFORM_)))
+endef
+
+define _cfg-vars-by-prefix
+ $(sort $(foreach prefix,$(1),$(filter $(prefix)%,$(.VARIABLES))))
+endef
+
+# Convert a makefile variable to a #define
+# <undefined>, n => <undefined>
+# y => 1
+# <other value> => <other value>
+define cfg-make-define
+ $(strip $(if $(filter y,$($1)),
+ #define $1 1_nl_,
+ $(if $(filter xn x,x$($1)),
+ /* $1 is not set */_nl_,
+ #define $1 $($1)_nl_)))
+endef
+
+# Returns 'y' if at least one variable is 'y', empty otherwise
+# Example:
+# FOO_OR_BAR := $(call cfg-one-enabled, FOO BAR)
+cfg-one-enabled = $(if $(filter y, $(foreach var,$(1),$($(var)))),y,)
+
+# Returns 'y' if all variables are 'y', empty otherwise
+# Example:
+# FOO_AND_BAR := $(call cfg-all-enabled, FOO BAR)
+cfg-all-enabled = \
+ $(strip \
+ $(if $(1), \
+ $(if $(filter y,$($(firstword $(1)))), \
+ $(call cfg-all-enabled,$(filter-out $(firstword $(1)),$(1))), \
+ ), \
+ y \
+ ) \
+ )
+
+# Disable a configuration variable if some dependency is disabled
+# Example:
+# $(eval $(call cfg-depends-all,FOO,BAR BAZ))
+# Will clear FOO if it is initially 'y' and BAR or BAZ are not 'y'
+cfg-depends-all = \
+ $(strip \
+ $(if $(filter y, $($(1))), \
+ $(if $(call cfg-all-enabled,$(2)), \
+ , \
+ $(warning Warning: Disabling $(1) [requires $(strip $(2))]) \
+ override $(1) := \
+ ) \
+ ) \
+ )
+
+# Disable a configuration variable if all dependencies are disabled
+# Example:
+# $(eval $(call cfg-depends-one,FOO,BAR BAZ))
+# Will clear FOO if it is initially 'y' and both BAR and BAZ are not 'y'
+cfg-depends-one = \
+ $(strip \
+ $(if $(filter y, $($(1))), \
+ $(if $(call cfg-one-enabled,$(2)), \
+ , \
+ $(warning Warning: Disabling $(1) [requires (one of) $(strip $(2))]) \
+ override $(1) := \
+ ) \
+ ) \
+ )
+
+
+# Enable all depend variables
+# Example:
+# $(eval $(call cfg-enable-all-depends,FOO,BAR BAZ))
+# Will enable BAR and BAZ if FOO is initially 'y'
+cfg-enable-all-depends = \
+ $(strip \
+ $(if $(2), \
+ $(if $(filter y, $($(1))), \
+ $(if $(filter y,$($(firstword $(2)))), \
+ , \
+ $(warning Warning: Enabling $(firstword $(2)) [required by $(1)]) \
+ $(eval override $(firstword $(2)) := y) \
+ ) \
+ $(call cfg-enable-all-depends,$(1),$(filter-out $(firstword $(2)),$(2))), \
+ ) \
+ , \
+ ) \
+ )
+
+# Set a variable or error out if it was previously set to a different value
+# The reason message (3rd parameter) is optional
+# Example:
+# $(call force,CFG_FOO,foo,required by CFG_BAR)
+define force
+$(eval $(call _force,$(1),$(2),$(3)))
+endef
+
+define _force
+ifdef $(1)
+ifneq ($($(1)),$(2))
+ifneq (,$(3))
+_reason := $$(_empty) [$(3)]
+endif
+$$(error $(1) is set to '$($(1))' (from $(origin $(1))) but its value must be '$(2)'$$(_reason))
+endif
+endif
+$(1) := $(2)
+endef