Add cleaner way to conditionally compile files
This commit is contained in:
parent
2aadbee43c
commit
79ca00af49
3 changed files with 84 additions and 7 deletions
|
@ -396,7 +396,8 @@ Adding conditional configuration
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
The configuration system can be used to conditionally compile some files
|
The configuration system can be used to conditionally compile some files
|
||||||
depending on the options selected in ``make menuconfig``:
|
depending on the options selected in ``make menuconfig``. For this, ESP-IDF
|
||||||
|
has the compile_only_if and compile_only_if_not macros:
|
||||||
|
|
||||||
``Kconfig``::
|
``Kconfig``::
|
||||||
|
|
||||||
|
@ -407,14 +408,56 @@ depending on the options selected in ``make menuconfig``:
|
||||||
|
|
||||||
``component.mk``::
|
``component.mk``::
|
||||||
|
|
||||||
COMPONENT_OBJS := foo_a.o foo_b.o
|
$(call compile_only_if,$(CONFIG_FOO_ENABLE_BAR),bar.o)
|
||||||
|
|
||||||
ifdef CONFIG_FOO_BAR
|
|
||||||
COMPONENT_OBJS += foo_bar.o foo_bar_interface.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
See the `GNU Make Manual` for conditional syntax that can be used use in makefiles.
|
As can be seen in the example, the ``compile_only_if`` macro takes a condition and a
|
||||||
|
list of object files as parameters. If the condition is true (in this case: if the
|
||||||
|
BAR feature is enabled in menuconfig) the object files (in this case: bar.o) will
|
||||||
|
always be compiled. The opposite goes as well: if the condition is not true, bar.o
|
||||||
|
will never be compiled. ``compile_only_if_not`` does the opposite: compile if the
|
||||||
|
condition is false, not compile if the condition is true.
|
||||||
|
|
||||||
|
This can also be used to select or stub out an implementation, as such:
|
||||||
|
|
||||||
|
``Kconfig``::
|
||||||
|
|
||||||
|
config ENABLE_LCD_OUTPUT
|
||||||
|
bool "Enable LCD output."
|
||||||
|
help
|
||||||
|
Select this if your board has a LCD.
|
||||||
|
|
||||||
|
config ENABLE_LCD_CONSOLE
|
||||||
|
bool "Output console text to LCD"
|
||||||
|
depends on ENABLE_LCD_OUTPUT
|
||||||
|
help
|
||||||
|
Select this to output debugging output to the lcd
|
||||||
|
|
||||||
|
config ENABLE_LCD_PLOT
|
||||||
|
bool "Output temperature plots to LCD"
|
||||||
|
depends on ENABLE_LCD_OUTPUT
|
||||||
|
help
|
||||||
|
Select this to output temperature plots
|
||||||
|
|
||||||
|
|
||||||
|
``component.mk``::
|
||||||
|
|
||||||
|
# If LCD is enabled, compile interface to it, otherwise compile dummy interface
|
||||||
|
$(call compile_only_if,$(CONFIG_ENABLE_LCD_OUTPUT),lcd-real.o lcd-spi.o)
|
||||||
|
$(call compile_only_if_not,$(CONFIG_ENABLE_LCD_OUTPUT),lcd-dummy.o)
|
||||||
|
|
||||||
|
#We need font if either console or plot is enabled
|
||||||
|
$(call compile_only_if,$(or $(CONFIG_ENABLE_LCD_CONSOLE),$(CONFIG_ENABLE_LCD_PLOT)), font.o)
|
||||||
|
|
||||||
|
Note the use of the Make 'or' function to include the font file. Other substitution functions,
|
||||||
|
like 'and' and 'if' will also work here. Variables that do not come from menuconfig can also
|
||||||
|
be used: ESP-IDF uses the default Make policy of judging a variable which is empty or contains
|
||||||
|
only whitespace to be false while a variable with any non-whitespace in it is true.
|
||||||
|
|
||||||
|
(Note: Older versions of this document advised conditionally adding object file names to
|
||||||
|
``COMPONENT_OBJS``. While this still is possible, this will only work when all object
|
||||||
|
files for a component are named explicitely, and will not clean up deselected object files
|
||||||
|
in a ``make clean`` pass.)
|
||||||
|
|
||||||
Source Code Generation
|
Source Code Generation
|
||||||
^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -73,3 +73,11 @@ endef
|
||||||
define prereq_if_explicit
|
define prereq_if_explicit
|
||||||
$(filter $(1),$(MAKECMDGOALS))
|
$(filter $(1),$(MAKECMDGOALS))
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
# macro to kill duplicate items in a list without messing up the sort order of the list.
|
||||||
|
# Will only keep the unique items; if there are non-unique items in the list, it will remove
|
||||||
|
# the later recurring ones so only the first one remains.
|
||||||
|
# Copied from http://stackoverflow.com/questions/16144115/makefile-remove-duplicate-words-without-sorting
|
||||||
|
define uniq
|
||||||
|
$(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
|
||||||
|
endef
|
||||||
|
|
|
@ -46,6 +46,23 @@ COMPONENT_EMBED_TXTFILES ?=
|
||||||
COMPONENT_ADD_INCLUDEDIRS = include
|
COMPONENT_ADD_INCLUDEDIRS = include
|
||||||
COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME)
|
COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME)
|
||||||
|
|
||||||
|
# Define optional compiling macros
|
||||||
|
define compile_exclude
|
||||||
|
COMPONENT_OBJEXCLUDE += $(1)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define compile_include
|
||||||
|
COMPONENT_OBJINCLUDE += $(1)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define compile_only_if
|
||||||
|
$(eval $(if $(1), $(call compile_include, $(2)), $(call compile_exclude, $(2))))
|
||||||
|
endef
|
||||||
|
|
||||||
|
define compile_only_if_not
|
||||||
|
$(eval $(if $(1), $(call compile_exclude, $(2)), $(call compile_include, $(2))))
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# 2) Include the component.mk for the specific component (COMPONENT_MAKEFILE) to
|
# 2) Include the component.mk for the specific component (COMPONENT_MAKEFILE) to
|
||||||
|
@ -68,7 +85,16 @@ COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.cpp,%.o
|
||||||
COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.S,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.S)))
|
COMPONENT_OBJS += $(foreach compsrcdir,$(COMPONENT_SRCDIRS),$(patsubst %.S,%.o,$(wildcard $(COMPONENT_PATH)/$(compsrcdir)/*.S)))
|
||||||
# Make relative by removing COMPONENT_PATH from all found object paths
|
# Make relative by removing COMPONENT_PATH from all found object paths
|
||||||
COMPONENT_OBJS := $(patsubst $(COMPONENT_PATH)/%,%,$(COMPONENT_OBJS))
|
COMPONENT_OBJS := $(patsubst $(COMPONENT_PATH)/%,%,$(COMPONENT_OBJS))
|
||||||
|
else
|
||||||
|
# Add in components defined by conditional compiling macros
|
||||||
|
COMPONENT_OBJS += $(COMPONENT_OBJINCLUDE)
|
||||||
endif
|
endif
|
||||||
|
# Remove items disabled by optional compilation
|
||||||
|
COMPONENT_OBJS := $(foreach obj,$(COMPONENT_OBJS),$(if $(filter $(realpath $(obj)),$(realpath $(COMPONENT_OBJEXCLUDE))), ,$(obj)))
|
||||||
|
|
||||||
|
# Remove duplicates
|
||||||
|
COMPONENT_OBJS := $(call uniq,$(COMPONENT_OBJS))
|
||||||
|
|
||||||
|
|
||||||
# Object files with embedded binaries to add to the component library
|
# Object files with embedded binaries to add to the component library
|
||||||
# Correspond to the files named in COMPONENT_EMBED_FILES & COMPONENT_EMBED_TXTFILES
|
# Correspond to the files named in COMPONENT_EMBED_FILES & COMPONENT_EMBED_TXTFILES
|
||||||
|
@ -142,7 +168,7 @@ endif
|
||||||
|
|
||||||
# If COMPONENT_OWNCLEANTARGET is not set, define a phony clean target
|
# If COMPONENT_OWNCLEANTARGET is not set, define a phony clean target
|
||||||
ifndef COMPONENT_OWNCLEANTARGET
|
ifndef COMPONENT_OWNCLEANTARGET
|
||||||
CLEAN_FILES = $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_EMBED_OBJS) $(COMPONENT_EXTRA_CLEAN) component_project_vars.mk
|
CLEAN_FILES := $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_OBJEXCLUDE) $(COMPONENT_OBJEXCLUDE:.o=.d) $(COMPONENT_EMBED_OBJS) $(COMPONENT_EXTRA_CLEAN) component_project_vars.mk
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
$(summary) RM $(CLEAN_FILES)
|
$(summary) RM $(CLEAN_FILES)
|
||||||
|
|
Loading…
Reference in a new issue