Linux debugging

Check our new training course

Linux debugging, tracing, profiling & perf. analysis

Check our new training course
with Creative Commons CC-BY-SA
lecture and lab materials

Bootlin logo

Elixir Cross Referencer

# 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):
#
# 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_)))
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 /* '$($1)' */_nl_,
		     $(if $(filter xn x,x$($1)),
			  /* $1 is not set ('$($1)') */_nl_,
			  #define $1 $($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