1# Generate/check/update a .h file to reflect the values of Makefile
2# variables
3#
4# Example usage (by default, check-conf-h will consider all CFG_*
5# and _CFG_* variables plus PLATFORM_*):
6#
7# path/to/conf.h: FORCE
8#	$(call check-conf-h)
9#
10# Or, to include only the variables with the given prefix(es):
11#
12# path/to/crypto_config.h: FORCE
13#	$(call check-conf-h,CFG_CRYPTO_ CRYPTO_)
14define check-conf-h
15	$(q)set -e;						\
16	$(cmd-echo-silent) '  CHK     $@';			\
17	cnf='$(strip $(foreach var,				\
18		$(call cfg-vars-by-prefix,$1),			\
19		$(call cfg-make-define,$(var))))';		\
20	guard="_`echo $@ | tr -- -/.+ _`_";			\
21	mkdir -p $(dir $@);					\
22	echo "#ifndef $${guard}" >$@.tmp;			\
23	echo "#define $${guard}" >>$@.tmp;			\
24	echo -n "$${cnf}" | sed 's/_nl_ */\n/g' >>$@.tmp;	\
25	echo "#endif" >>$@.tmp;					\
26	$(call mv-if-changed,$@.tmp,$@)
27endef
28
29define check-conf-cmake
30	$(q)set -e;						\
31	$(cmd-echo-silent) '  CHK     $@';			\
32	cnf='$(strip $(foreach var,				\
33		$(call cfg-vars-by-prefix,$1),			\
34		$(call cfg-cmake-set,$(var))))';		\
35	mkdir -p $(dir $@);					\
36	echo "# auto-generated TEE configuration file" >$@.tmp; \
37	echo "# TEE version ${TEE_IMPL_VERSION}" >>$@.tmp; \
38	echo -n "$${cnf}" | sed 's/_nl_ */\n/g' >>$@.tmp;	\
39	$(call mv-if-changed,$@.tmp,$@)
40endef
41
42define check-conf-mk
43	$(q)set -e;						\
44	$(cmd-echo-silent) '  CHK     $@';			\
45	cnf='$(strip $(foreach var,				\
46		$(call cfg-vars-by-prefix,CFG_),		\
47		$(strip $(var)=$($(var))_nl_)))';		\
48	mkdir -p $(dir $@);					\
49	echo "# auto-generated TEE configuration file" >$@.tmp; \
50	echo "# TEE version ${TEE_IMPL_VERSION}" >>$@.tmp; \
51	echo "ARCH=${ARCH}" >>$@.tmp;				\
52	echo "PLATFORM=${PLATFORM}" >>$@.tmp;			\
53	echo "PLATFORM_FLAVOR=${PLATFORM_FLAVOR}" >>$@.tmp; 	\
54	echo -n "$${cnf}" | sed 's/_nl_ */\n/g' >>$@.tmp;	\
55	$(call mv-if-changed,$@.tmp,$@)
56endef
57
58# Rename $1 to $2 only if file content differs. Otherwise just delete $1.
59define mv-if-changed
60	if cmp -s $2 $1; then					\
61		rm -f $1;					\
62	else							\
63		$(cmd-echo-silent) '  UPD     $2';		\
64		mv $1 $2;					\
65	fi
66endef
67
68define cfg-vars-by-prefix
69	$(strip $(if $(1),$(call _cfg-vars-by-prefix,$(1)),
70			  $(call _cfg-vars-by-prefix,CFG_ _CFG_ PLATFORM_)))
71endef
72
73define _cfg-vars-by-prefix
74	$(sort $(foreach prefix,$(1),$(filter $(prefix)%,$(.VARIABLES))))
75endef
76
77# Convert a makefile variable to a #define
78# <undefined>, n => <undefined>
79# y              => 1
80# <other value>  => <other value>
81define cfg-make-define
82	$(strip $(if $(filter y,$($1)),
83		     #define $1 1_nl_,
84		     $(if $(filter xn x,x$($1)),
85			  /* $1 is not set */_nl_,
86			  #define $1 $($1)_nl_)))
87endef
88
89# Convert a makefile variable to a cmake set statement
90# <undefined>, n => <undefined>
91# <other value>  => <other value>
92define cfg-cmake-set
93	$(strip $(if $(filter xn x,x$($1)),
94		  # $1 is not set _nl_,
95		  set($1 $($1))_nl_))
96endef
97
98# Returns 'y' if at least one variable is 'y', 'n' otherwise
99# Example:
100# FOO_OR_BAR := $(call cfg-one-enabled, FOO BAR)
101cfg-one-enabled = $(if $(filter y, $(foreach var,$(1),$($(var)))),y,n)
102
103# Returns 'y' if all variables are 'y', 'n' otherwise
104# Example:
105# FOO_AND_BAR := $(call cfg-all-enabled, FOO BAR)
106cfg-all-enabled = $(if $(strip $(1)),$(if $(call _cfg-all-enabled,$(1)),y,n),n)
107_cfg-all-enabled =                                                             \
108    $(strip                                                                    \
109        $(if $(1),                                                             \
110            $(if $(filter y,$($(firstword $(1)))),                             \
111                $(call _cfg-all-enabled,$(filter-out $(firstword $(1)),$(1))), \
112             ),                                                                \
113            y                                                                  \
114         )                                                                     \
115     )
116
117# Disable a configuration variable if some dependency is disabled
118# Example:
119# $(eval $(call cfg-depends-all,FOO,BAR BAZ))
120# Will set FOO to 'n' if it is initially 'y' and BAR or BAZ are not 'y'
121cfg-depends-all =                                                           \
122    $(strip                                                                 \
123        $(if $(filter y, $($(1))),                                          \
124            $(if $(filter y,$(call cfg-all-enabled,$(2))),                  \
125                ,                                                           \
126                $(warning Warning: Disabling $(1) [requires $(strip $(2))]) \
127                    override $(1) := n                                      \
128             )                                                              \
129         )                                                                  \
130     )
131
132# Disable a configuration variable if all dependencies are disabled
133# Example:
134# $(eval $(call cfg-depends-one,FOO,BAR BAZ))
135# Will set FOO to 'n' if it is initially 'y' and both BAR and BAZ are not 'y'
136cfg-depends-one =                                                                    \
137    $(strip                                                                          \
138        $(if $(filter y, $($(1))),                                                   \
139            $(if $(filter y,$(call cfg-one-enabled,$(2))),                           \
140                ,                                                                    \
141                $(warning Warning: Disabling $(1) [requires (one of) $(strip $(2))]) \
142                    override $(1) := n                                               \
143             )                                                                       \
144         )                                                                           \
145     )
146
147
148# Enable all depend variables
149# Example:
150# $(eval $(call cfg-enable-all-depends,FOO,BAR BAZ))
151# Will enable BAR and BAZ if FOO is initially 'y'
152cfg-enable-all-depends =                                                                   \
153    $(strip                                                                                \
154        $(if $(2),                                                                         \
155            $(if $(filter y, $($(1))),                                                     \
156                $(if $(filter y,$($(firstword $(2)))),                                     \
157                    ,                                                                      \
158                    $(warning Warning: Enabling $(firstword $(2)) [required by $(1)])      \
159                        $(eval override $(firstword $(2)) := y)                            \
160                 )                                                                         \
161                 $(call cfg-enable-all-depends,$(1),$(filter-out $(firstword $(2)),$(2))), \
162             )                                                                             \
163             ,                                                                             \
164        )                                                                                  \
165     )
166
167# Check if a configuration variable has an acceptable value
168# Example:
169# $(call cfg-check-value,FOO,foo bar)
170# Will do nothing if $(CFG_FOO) is either foo or bar, and error out otherwise.
171cfg-check-value =                                                          \
172    $(if $(filter-out $(2),$(CFG_$(1))),                                   \
173        $(error CFG_$(1) is set to '$(CFG_$(1))', valid values are: $(2)))
174
175# Set a variable or error out if it was previously set to a different value
176# The reason message (3rd parameter) is optional
177# Example:
178# $(call force,CFG_FOO,foo,required by CFG_BAR)
179define force
180$(eval $(call _force,$(strip $(1)),$(2),$(3)))
181endef
182
183define _force
184ifdef $(1)
185ifneq ($($(1)),$(2))
186ifneq (,$(3))
187_reason := $$(_empty) [$(3)]
188endif
189$$(error $(1) is set to '$($(1))' (from $(origin $(1))) but its value must be '$(2)'$$(_reason))
190endif
191endif
192$(1) := $(2)
193endef
194