ifeq (, $(__RIOTBUILD_FLAG)) $(error You cannot build a module on its own. Use "make" in your application's directory instead.) endif # # enable second expansion of prerequisites. # # Doing that here enables it globally for all modules # # See https://www.gnu.org/software/make/manual/html_node/Secondary-Expansion.html # for what it can be used for. .SECONDEXPANSION: unexport DIRS DIRS := $(sort $(abspath $(DIRS))) _MOD := $(shell basename $(CURDIR)) MODULE ?= $(_MOD) .PHONY: all clean $(DIRS:%=ALL--%) $(DIRS:%=CLEAN--%) $(MODULE).module \ compile-commands $(DIRS:%=COMPILE-COMMANDS--%) $(MODULE).cleanup all: $(MODULE).module ..nothing ..nothing: @: clean:: $(DIRS:%=CLEAN--%) $(DIRS:%=ALL--%): $(QQ)"$(MAKE)" -C $(@:ALL--%=%) $(DIRS:%=CLEAN--%): $(QQ)"$(MAKE)" -C $(@:CLEAN--%=%) clean $(DIRS:%=COMPILE-COMMANDS--%): $(QQ)"$(MAKE)" -C $(@:COMPILE-COMMANDS--%=%) compile-commands ## submodules ifeq (1, $(SUBMODULES)) # don't use *.c as SRC if SRC is empty (e.g., no module selected) NO_AUTO_SRC := 1 # allow different submodule basename (e.g., MODULE=cpu_periph_common, but match just periph_%) BASE_MODULE ?= $(MODULE) # for each $(BASE_MODULE)_ in USEMODULE, add .c to SRC # unless in SUBMODULES_NO_SRC SRC += $(wildcard \ $(filter-out $(SUBMODULES_NO_SRC),\ $(patsubst $(BASE_MODULE)_%,%.c,\ $(filter $(BASE_MODULE)_%,$(USEMODULE))))) # remove duplicates SRC := $(sort $(SRC)) endif # By default consider C++ files has a .cpp extension SRCXXEXT ?= cpp ifeq ($(strip $(SRC))$(NO_AUTO_SRC),) SRC := $(filter-out $(SRC_NOLTO), $(wildcard *.c)) endif ifeq ($(strip $(SRCXX))$(NO_AUTO_SRC),) SRCXX := $(filter-out $(SRCXXEXCLUDE),$(wildcard *.$(SRCXXEXT))) endif ifeq ($(strip $(ASMSRC))$(NO_AUTO_SRC),) ASMSRC := $(wildcard *.s) endif ifeq ($(strip $(ASSMSRC))$(NO_AUTO_SRC),) ASSMSRC := $(wildcard *.S) endif ifneq (,$(SRCXX)) ifeq (,$(filter cpp,$(USEMODULE))) $(error Found C++ source, but feature "cpp" is not used. Add "FEATURES_REQUIRED += cpp") endif endif compile-commands: | $(DIRS:%=COMPILE-COMMANDS--%) $(file >$(BINDIR)/$(MODULE)/compile_cmds.txt,SRC: $(sort $(SRC) $(SRC_NO_LTO))) $(file >>$(BINDIR)/$(MODULE)/compile_cmds.txt,SRC_NO_LTO: $(sort $(SRC_NO_LTO))) $(file >>$(BINDIR)/$(MODULE)/compile_cmds.txt,SRCXX: $(sort $(SRCXX))) $(file >>$(BINDIR)/$(MODULE)/compile_cmds.txt,CURDIR: $(CURDIR)) $(file >>$(BINDIR)/$(MODULE)/compile_cmds.txt,CFLAGS: $(CFLAGS)) $(file >>$(BINDIR)/$(MODULE)/compile_cmds.txt,LTOFLAGS: $(LTOFLAGS)) $(file >>$(BINDIR)/$(MODULE)/compile_cmds.txt,INCLUDES: $(INCLUDES)) $(file >>$(BINDIR)/$(MODULE)/compile_cmds.txt,CXXFLAGS: $(CXXFLAGS)) $(file >>$(BINDIR)/$(MODULE)/compile_cmds.txt,CXXINCLUDES: $(CXXINCLUDES)) $(file >>$(BINDIR)/$(MODULE)/compile_cmds.txt,CC: $(CC)) $(file >>$(BINDIR)/$(MODULE)/compile_cmds.txt,CXX: $(CXX)) $(file >>$(BINDIR)/$(MODULE)/compile_cmds.txt,TARGET_ARCH: $(TARGET_ARCH)) $(file >>$(BINDIR)/$(MODULE)/compile_cmds.txt,TARGET_ARCH_LLVM: $(TARGET_ARCH_LLVM)) GENOBJC := $(GENSRC:%.c=%.o) OBJC_LTO := $(SRC:%.c=$(BINDIR)/$(MODULE)/%.o) OBJC_NOLTO := $(SRC_NOLTO:%.c=$(BINDIR)/$(MODULE)/%.o) OBJC := $(OBJC_NOLTO) $(OBJC_LTO) OBJCXX := $(SRCXX:%.$(SRCXXEXT)=$(BINDIR)/$(MODULE)/%.o) ASMOBJ := $(ASMSRC:%.s=$(BINDIR)/$(MODULE)/%.o) ASSMOBJ := $(ASSMSRC:%.S=$(BINDIR)/$(MODULE)/%.o) OBJ := $(OBJC) $(OBJCXX) $(ASMOBJ) $(ASSMOBJ) $(GENOBJC) DEP := $(OBJC:.o=.d) $(OBJCXX:.o=.d) $(ASSMOBJ:.o=.d) SRC_ALL := $(SRC) $(SRCXX) $(ASMSRC) $(ASSMSRC) SUBDIRS_IN_DIRS := $(filter $(DIRS), $(abspath $(sort $(dir $(SRC_ALL))))) ifneq (,$(SUBDIRS_IN_DIRS)) $(warning Files of the following subdirectories are selected \ both as RIOT modules (using DIRS) and directly as sourcefiles (using SRC): \ $(patsubst $(CURDIR)/%,./%, $(SUBDIRS_IN_DIRS)). \ Please select a single approach for each subfolder to prevent linking errors.) endif SUBDIRS := $(filter-out $(BINDIR)/$(MODULE)/, $(dir $(OBJ))) include $(RIOTMAKE)/blob.inc.mk include $(RIOTMAKE)/tools/fixdep.inc.mk $(BINDIR)/$(MODULE)/ $(SUBDIRS): $(Q)mkdir -p $@ OLD_OBJECTS = $(wildcard $(BINDIR)/$(MODULE)/*.o $(BINDIR)/$(MODULE)/**/*.o) # do not clean objects from bindist modules ifeq (,$(filter $(MODULE),$(BIN_USEMODULE))) OBJECTS_TO_REMOVE = $(filter-out $(OBJ),$(OLD_OBJECTS)) endif $(MODULE).module compile-commands $(OBJ): | $(BINDIR)/$(MODULE)/ $(SUBDIRS) $(MODULE).module: $(OBJ) $(if $(OBJECTS_TO_REMOVE),$(MODULE).cleanup) | $(DIRS:%=ALL--%) $(MODULE).cleanup: $(Q)# cleanup non selected source files objects $(Q)$(RM) $(OBJECTS_TO_REMOVE) CXXFLAGS = $(filter-out $(CXXUWFLAGS), $(CFLAGS)) $(CXXEXFLAGS) CCASFLAGS = $(filter-out $(CCASUWFLAGS), $(CFLAGS)) $(CCASEXFLAGS) # compile and generate dependency info $(OBJC_LTO): CFLAGS+=$(LTOFLAGS) # Define dependencies for object files OBJ_DEPS += $(RIOTBUILD_CONFIG_HEADER_C) $(OBJC): $(BINDIR)/$(MODULE)/%.o: %.c $(OBJ_DEPS) | $(if $(SHOULD_RUN_KCONFIG),$(KCONFIG_GENERATED_AUTOCONF_HEADER_C)) $(Q)$(CCACHE) $(CC) \ -DRIOT_FILE_RELATIVE=\"$(patsubst $(RIOTBASE)/%,%,$(abspath $<))\" \ -DRIOT_FILE_NOPATH=\"$(notdir $<)\" \ $(CFLAGS) $(INCLUDES) -MQ '$@' -MD -MP -c -o $@ $(abspath $<) ifneq (,$(SHOULD_RUN_KCONFIG)) $(Q)$(FIXDEP) $(@:.o=.d) $@ $(KCONFIG_SYNC_DIR) > $(@:.o=.tmp) $(Q)mv $(@:.o=.tmp) $(@:.o=.d) endif $(GENOBJC): %.o: %.c $(OBJ_DEPS) | $(if $(SHOULD_RUN_KCONFIG),$(KCONFIG_GENERATED_AUTOCONF_HEADER_C)) $(Q) $(CCACHE) $(CC) \ -DRIOT_FILE_RELATIVE=\"$(patsubst $(RIOTBASE)/%,%,$<)\" \ -DRIOT_FILE_NOPATH=\"$(notdir $<)\" \ $(CFLAGS) $(INCLUDES) -MQ '$@' -MD -MP -c -o $@ $< ifneq (,$(SHOULD_RUN_KCONFIG)) $(Q)$(FIXDEP) $(@:.o=.d) $@ $(KCONFIG_SYNC_DIR) > $(@:.o=.tmp) $(Q)mv $(@:.o=.tmp) $(@:.o=.d) endif $(OBJCXX): $(BINDIR)/$(MODULE)/%.o: %.$(SRCXXEXT) $(OBJ_DEPS) | $(if $(SHOULD_RUN_KCONFIG),$(KCONFIG_GENERATED_AUTOCONF_HEADER_C)) $(Q)$(CCACHE) $(CXX) \ -DRIOT_FILE_RELATIVE=\"$(patsubst $(RIOTBASE)/%,%,$(abspath $<))\" \ -DRIOT_FILE_NOPATH=\"$(notdir $<)\" \ $(CXXFLAGS) $(CXXINCLUDES) $(INCLUDES) -MQ '$@' -MD -MP -c -o $@ $(abspath $<) ifneq (,$(SHOULD_RUN_KCONFIG)) $(Q)$(FIXDEP) $(@:.o=.d) $@ $(KCONFIG_SYNC_DIR) > $(@:.o=.tmp) $(Q)mv $(@:.o=.tmp) $(@:.o=.d) endif $(ASMOBJ): $(BINDIR)/$(MODULE)/%.o: %.s $(Q)$(AS) $(ASFLAGS) -o $@ $(abspath $<) $(ASSMOBJ): $(BINDIR)/$(MODULE)/%.o: %.S $(OBJ_DEPS) | $(if $(SHOULD_RUN_KCONFIG),$(KCONFIG_GENERATED_AUTOCONF_HEADER_C)) $(Q)$(CCAS) $(CCASFLAGS) $(INCLUDES) -MQ '$@' -MD -MP -c -o $@ $(abspath $<) ifneq (,$(SHOULD_RUN_KCONFIG)) $(Q)$(FIXDEP) $(@:.o=.d) $@ $(KCONFIG_SYNC_DIR) > $(@:.o=.tmp) $(Q)mv $(@:.o=.tmp) $(@:.o=.d) endif # pull in dependency info for *existing* .o files # deleted header files will be silently ignored -include $(DEP)