From 058a2fbceb8758f6851b37fa726e288657e1c1df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikolai=20G=C3=BCtschow?= Date: Thu, 26 Oct 2023 16:32:17 +0200 Subject: [PATCH 1/7] Makefiles: (application) support for SRC in subfolders --- Makefile.base | 16 +++++++++++++--- Makefile.include | 2 ++ makefiles/application.inc.mk | 17 ++++++++++------- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Makefile.base b/Makefile.base index cfc060c973481..18e4ad6c6f1bf 100644 --- a/Makefile.base +++ b/Makefile.base @@ -111,20 +111,30 @@ 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)/: +$(BINDIR)/$(MODULE)/ $(SUBDIRS): $(Q)mkdir -p $@ -OLD_OBJECTS = $(wildcard $(BINDIR)/$(MODULE)/*.o) +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)/ +$(MODULE).module compile-commands $(OBJ): | $(BINDIR)/$(MODULE)/ $(SUBDIRS) $(MODULE).module: $(OBJ) $(if $(OBJECTS_TO_REMOVE),$(MODULE).cleanup) | $(DIRS:%=ALL--%) diff --git a/Makefile.include b/Makefile.include index 609a1f8fecd85..79927a4647e9a 100644 --- a/Makefile.include +++ b/Makefile.include @@ -735,6 +735,7 @@ COMPILE_COMMANDS_FLAGS ?= --clangd .PHONY: compile-commands compile-commands: $(BUILDDEPS) $(Q)DIRS="$(DIRS)" APPLICATION_BLOBS="$(BLOBS)" \ + APPLICATION_SRC="$(SRC)" APPLICATION_SRCXX="$(SRCXX)" APPLICATION_ASMSRC="$(ASMSRC)" APPLICATION_ASSMSRC="$(ASSMSRC)" \ "$(MAKE)" -C $(APPDIR) -f $(RIOTMAKE)/application.inc.mk compile-commands $(Q)$(RIOTTOOLS)/compile_commands/compile_commands.py $(COMPILE_COMMANDS_FLAGS) $(BINDIR) \ > $(COMPILE_COMMANDS_PATH) @@ -759,6 +760,7 @@ $(ELFFILE): $(BASELIBS) $(ARCHIVES) $(LD_SCRIPTS) $(APPLICATION_MODULE).module: pkg-build $(BUILDDEPS) $(Q)DIRS="$(DIRS)" APPLICATION_BLOBS="$(BLOBS)" \ + APPLICATION_SRC="$(SRC)" APPLICATION_SRCXX="$(SRCXX)" APPLICATION_ASMSRC="$(ASMSRC)" APPLICATION_ASSMSRC="$(ASSMSRC)" \ "$(MAKE)" -C $(APPDIR) -f $(RIOTMAKE)/application.inc.mk $(APPLICATION_MODULE).module: FORCE diff --git a/makefiles/application.inc.mk b/makefiles/application.inc.mk index 0460b057c163c..274ec11445f56 100644 --- a/makefiles/application.inc.mk +++ b/makefiles/application.inc.mk @@ -3,17 +3,20 @@ MODULE = $(APPLICATION_MODULE) DIRS += $(RIOTCPU)/$(CPU) $(BOARDDIR) DIRS += $(RIOTBASE)/core $(RIOTBASE)/core/lib $(RIOTBASE)/drivers $(RIOTBASE)/sys -# For regular modules, adding files to BLOBS to their Makefile is sufficient to -# create the corresponding headers. +# For regular modules, adding files to BLOBS, SRC, SRCXX, ASMSRC or ASSMSRC +# in their Makefile is sufficient to explicitely set the variables. # # Application modules are different, as they use this makefile to build, thus # application level variables are not available unless exported. # -# But exporting e.g., BLOBS, would pre-set the variable for all -# submakefiles. +# But exporting would pre-set the variables for all submakefiles. # -# As workaround, $(RIOTBASE)/Makefile.include passes BLOBS to this -# Makefile as APPLICATION_BLOBS. -BLOBS = $(APPLICATION_BLOBS) +# As workaround, $(RIOTBASE)/Makefile.include passes the above-listed variables +# to this Makefile as APPLICATION_*. +BLOBS = $(APPLICATION_BLOBS) +SRC = $(APPLICATION_SRC) +SRCXX = $(APPLICATION_SRCXX) +ASMSRC = $(APPLICATION_ASMSRC) +ASSMSRC = $(APPLICATION_ASSMSRC) include $(RIOTBASE)/Makefile.base From 60661f52684a634d7d2337dc786a94c613e92038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikolai=20G=C3=BCtschow?= Date: Thu, 26 Oct 2023 17:25:27 +0200 Subject: [PATCH 2/7] add example showcasing application subfolders --- examples/subfolders/Makefile | 33 +++++++++ examples/subfolders/README.md | 85 ++++++++++++++++++++++++ examples/subfolders/folder/a.c | 14 ++++ examples/subfolders/folder/subfolder/b.c | 14 ++++ examples/subfolders/main.c | 39 +++++++++++ examples/subfolders/module/Makefile | 3 + examples/subfolders/module/a.c | 14 ++++ examples/subfolders/module/b.c | 14 ++++ 8 files changed, 216 insertions(+) create mode 100644 examples/subfolders/Makefile create mode 100644 examples/subfolders/README.md create mode 100644 examples/subfolders/folder/a.c create mode 100644 examples/subfolders/folder/subfolder/b.c create mode 100644 examples/subfolders/main.c create mode 100644 examples/subfolders/module/Makefile create mode 100644 examples/subfolders/module/a.c create mode 100644 examples/subfolders/module/b.c diff --git a/examples/subfolders/Makefile b/examples/subfolders/Makefile new file mode 100644 index 0000000000000..b5a8e88706877 --- /dev/null +++ b/examples/subfolders/Makefile @@ -0,0 +1,33 @@ +# name of your application +APPLICATION = subfolders + +# If no BOARD is found in the environment, use this default: +BOARD ?= native + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../.. + +# Add subfolders as modules +DIRS += module +USEMODULE += my_module # name as defined in module/Makefile + +# Add source files in subfolders manually +SRC += main.c +SRC += folder/a.c folder/subfolder/b.c + +# Alternative method to add files in subfolders using wildcards +# SRC += $(wildcard *.c folder/*.c folder/**/*.c) + +# Adding subfolders both via SRC and DIRS will generate a warning +# and likely fail during linking +# DIRS += folder + +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +DEVELHELP ?= 1 + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +include $(RIOTBASE)/Makefile.include diff --git a/examples/subfolders/README.md b/examples/subfolders/README.md new file mode 100644 index 0000000000000..14986afe579b3 --- /dev/null +++ b/examples/subfolders/README.md @@ -0,0 +1,85 @@ +# Application Example with Subfolders + +This example demonstrates the usage of subfolders in a RIOT application +show-casing two possible approaches: RIOT modules and simple subfolders. + +## Details + +Consider the following folder structure of this example. +The source files in `module` are incorporated as a RIOT module, +while the source files in `folder` are considered part of the application itself. + +``` +. +├── folder +│ ├── a.c +│ └── subfolder +│ └── b.c +├── main.c +├── Makefile +├── module +│ ├── a.c +│ ├── b.c +│ └── Makefile +└── README.md +``` + +### RIOT modules + +At a minimum, each module in RIOT requires a `Makefile` with the following content: + +```Makefile +MODULE := my_module + +include $(RIOTBASE)/Makefile.base +``` + +If `MODULE` is not specified, the name of the module's directory is automatically used, +leaving only the last line as minimal content. +It is important to note that module names have to be unique both among _all_ RIOT modules, +i.e., including the modules that are part of RIOT itself. + +If not manually specified via `SRC`, all source files which reside +directly in the module's directory are considered part of the module. +RIOT modules are also described in greater detail [in the documentation](https://doc.riot-os.org/creating-modules.html). + +Two lines need to be added to the application's Makefile in order to compile and use the module: + +```Makefile +DIRS += module +USEMODULE += my_module +``` + +The string added to `DIRS` has to match the directory name, +while the string added to `USEMODULE` has to match the module's name as defined above. + + +### Subfolders + +Compared to the module approach, no additional Makefile is needed in the subfolder. +The application's Makefile needs to add _all_ source files explicitly, +including the ones residing directly in the application directory: + +```Makefile +SRC += main.c +SRC += folder/a.c folder/subfolder/b.c +``` + +To avoid listing all source files individually, it is of course possible +to use normal GNU make functions such as `wildcard`: + +```Makefile +SRC += $(wildcard *.c folder/*.c folder/**/*.c) +``` + + +## Which approach should I use? + +In general, modules in RIOT are well-defined units of code that provide a set of features to your application. +If this matches your use-case, i.e., you have all your application tests separated into a subfolder, +RIOT modules are probably the best approach. +It is good practice to prefix all your application modules to avoid name clashes. + +If however you barely want to organize your files in a sensible folder structure, +but always require all source files to be part of your application, +the more straight-forward subfolder approach is probably the better pick. diff --git a/examples/subfolders/folder/a.c b/examples/subfolders/folder/a.c new file mode 100644 index 0000000000000..7d5f66244f0c9 --- /dev/null +++ b/examples/subfolders/folder/a.c @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +void folder_a(void) +{ + puts("./folder/a.c"); +} diff --git a/examples/subfolders/folder/subfolder/b.c b/examples/subfolders/folder/subfolder/b.c new file mode 100644 index 0000000000000..5aace94347ba5 --- /dev/null +++ b/examples/subfolders/folder/subfolder/b.c @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +void folder_b(void) +{ + puts("./folder/subfolder/b.c"); +} diff --git a/examples/subfolders/main.c b/examples/subfolders/main.c new file mode 100644 index 0000000000000..f7a8cf54b3b8d --- /dev/null +++ b/examples/subfolders/main.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief Application showcasing the use of subfolders in RIOT applications + * + * @author Mikolai Gütschow + * + * @} + */ + +#include + +void module_a(void); +void module_b(void); +void folder_a(void); +void folder_b(void); + +int main(void) +{ + puts("./main.c"); + // call functions from RIOT module + module_a(); + module_b(); + // call functions from subfolder + folder_a(); + folder_b(); + + return 0; +} diff --git a/examples/subfolders/module/Makefile b/examples/subfolders/module/Makefile new file mode 100644 index 0000000000000..831cf70a7d625 --- /dev/null +++ b/examples/subfolders/module/Makefile @@ -0,0 +1,3 @@ +MODULE := my_module + +include $(RIOTBASE)/Makefile.base diff --git a/examples/subfolders/module/a.c b/examples/subfolders/module/a.c new file mode 100644 index 0000000000000..15a8f1ae6e07b --- /dev/null +++ b/examples/subfolders/module/a.c @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +void module_a(void) +{ + puts("./module/a.c"); +} diff --git a/examples/subfolders/module/b.c b/examples/subfolders/module/b.c new file mode 100644 index 0000000000000..32d98a7661a6a --- /dev/null +++ b/examples/subfolders/module/b.c @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +void module_b(void) +{ + puts("./module/b.c"); +} From aebfcef0e396aece4808175fd77e4dd5428b8f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikolai=20G=C3=BCtschow?= Date: Thu, 26 Oct 2023 16:32:17 +0200 Subject: [PATCH 3/7] Makefiles: (application) support for SRC in subfolders --- Makefile.base | 16 +++++++++++++--- Makefile.include | 2 ++ makefiles/application.inc.mk | 17 ++++++++++------- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Makefile.base b/Makefile.base index ab07fc5c94599..00d7eb059d8bf 100644 --- a/Makefile.base +++ b/Makefile.base @@ -104,20 +104,30 @@ 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)/: +$(BINDIR)/$(MODULE)/ $(SUBDIRS): $(Q)mkdir -p $@ -OLD_OBJECTS = $(wildcard $(BINDIR)/$(MODULE)/*.o) +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)/ +$(MODULE).module compile-commands $(OBJ): | $(BINDIR)/$(MODULE)/ $(SUBDIRS) $(MODULE).module: $(OBJ) $(if $(OBJECTS_TO_REMOVE),$(MODULE).cleanup) | $(DIRS:%=ALL--%) diff --git a/Makefile.include b/Makefile.include index 771f7cfd49bb0..9a5f8292d4859 100644 --- a/Makefile.include +++ b/Makefile.include @@ -720,6 +720,7 @@ COMPILE_COMMANDS_FLAGS ?= --clangd compile-commands: $(COMPILE_COMMANDS_PATH) %/compile_commands.json: $(BUILDDEPS) $(Q)DIRS="$(DIRS)" APPLICATION_BLOBS="$(BLOBS)" \ + APPLICATION_SRC="$(SRC)" APPLICATION_SRCXX="$(SRCXX)" APPLICATION_ASMSRC="$(ASMSRC)" APPLICATION_ASSMSRC="$(ASSMSRC)" \ "$(MAKE)" -C $(APPDIR) -f $(RIOTMAKE)/application.inc.mk compile-commands $(Q)$(RIOTTOOLS)/compile_commands/compile_commands.py $(COMPILE_COMMANDS_FLAGS) $(BINDIR) \ > $@ @@ -744,6 +745,7 @@ $(ELFFILE): $(BASELIBS) $(ARCHIVES) $(LD_SCRIPTS) $(APPLICATION_MODULE).module: pkg-build $(BUILDDEPS) $(Q)DIRS="$(DIRS)" APPLICATION_BLOBS="$(BLOBS)" \ + APPLICATION_SRC="$(SRC)" APPLICATION_SRCXX="$(SRCXX)" APPLICATION_ASMSRC="$(ASMSRC)" APPLICATION_ASSMSRC="$(ASSMSRC)" \ "$(MAKE)" -C $(APPDIR) -f $(RIOTMAKE)/application.inc.mk $(APPLICATION_MODULE).module: FORCE diff --git a/makefiles/application.inc.mk b/makefiles/application.inc.mk index 0460b057c163c..274ec11445f56 100644 --- a/makefiles/application.inc.mk +++ b/makefiles/application.inc.mk @@ -3,17 +3,20 @@ MODULE = $(APPLICATION_MODULE) DIRS += $(RIOTCPU)/$(CPU) $(BOARDDIR) DIRS += $(RIOTBASE)/core $(RIOTBASE)/core/lib $(RIOTBASE)/drivers $(RIOTBASE)/sys -# For regular modules, adding files to BLOBS to their Makefile is sufficient to -# create the corresponding headers. +# For regular modules, adding files to BLOBS, SRC, SRCXX, ASMSRC or ASSMSRC +# in their Makefile is sufficient to explicitely set the variables. # # Application modules are different, as they use this makefile to build, thus # application level variables are not available unless exported. # -# But exporting e.g., BLOBS, would pre-set the variable for all -# submakefiles. +# But exporting would pre-set the variables for all submakefiles. # -# As workaround, $(RIOTBASE)/Makefile.include passes BLOBS to this -# Makefile as APPLICATION_BLOBS. -BLOBS = $(APPLICATION_BLOBS) +# As workaround, $(RIOTBASE)/Makefile.include passes the above-listed variables +# to this Makefile as APPLICATION_*. +BLOBS = $(APPLICATION_BLOBS) +SRC = $(APPLICATION_SRC) +SRCXX = $(APPLICATION_SRCXX) +ASMSRC = $(APPLICATION_ASMSRC) +ASSMSRC = $(APPLICATION_ASSMSRC) include $(RIOTBASE)/Makefile.base From 834741068e71fde8023672dfa99fd9c6632aafd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikolai=20G=C3=BCtschow?= Date: Thu, 26 Oct 2023 17:25:27 +0200 Subject: [PATCH 4/7] add example showcasing application subfolders --- examples/subfolders/Makefile | 33 +++++++++ examples/subfolders/README.md | 85 ++++++++++++++++++++++++ examples/subfolders/folder/a.c | 14 ++++ examples/subfolders/folder/subfolder/b.c | 14 ++++ examples/subfolders/main.c | 39 +++++++++++ examples/subfolders/module/Makefile | 3 + examples/subfolders/module/a.c | 14 ++++ examples/subfolders/module/b.c | 14 ++++ 8 files changed, 216 insertions(+) create mode 100644 examples/subfolders/Makefile create mode 100644 examples/subfolders/README.md create mode 100644 examples/subfolders/folder/a.c create mode 100644 examples/subfolders/folder/subfolder/b.c create mode 100644 examples/subfolders/main.c create mode 100644 examples/subfolders/module/Makefile create mode 100644 examples/subfolders/module/a.c create mode 100644 examples/subfolders/module/b.c diff --git a/examples/subfolders/Makefile b/examples/subfolders/Makefile new file mode 100644 index 0000000000000..b5a8e88706877 --- /dev/null +++ b/examples/subfolders/Makefile @@ -0,0 +1,33 @@ +# name of your application +APPLICATION = subfolders + +# If no BOARD is found in the environment, use this default: +BOARD ?= native + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../.. + +# Add subfolders as modules +DIRS += module +USEMODULE += my_module # name as defined in module/Makefile + +# Add source files in subfolders manually +SRC += main.c +SRC += folder/a.c folder/subfolder/b.c + +# Alternative method to add files in subfolders using wildcards +# SRC += $(wildcard *.c folder/*.c folder/**/*.c) + +# Adding subfolders both via SRC and DIRS will generate a warning +# and likely fail during linking +# DIRS += folder + +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +DEVELHELP ?= 1 + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +include $(RIOTBASE)/Makefile.include diff --git a/examples/subfolders/README.md b/examples/subfolders/README.md new file mode 100644 index 0000000000000..14986afe579b3 --- /dev/null +++ b/examples/subfolders/README.md @@ -0,0 +1,85 @@ +# Application Example with Subfolders + +This example demonstrates the usage of subfolders in a RIOT application +show-casing two possible approaches: RIOT modules and simple subfolders. + +## Details + +Consider the following folder structure of this example. +The source files in `module` are incorporated as a RIOT module, +while the source files in `folder` are considered part of the application itself. + +``` +. +├── folder +│ ├── a.c +│ └── subfolder +│ └── b.c +├── main.c +├── Makefile +├── module +│ ├── a.c +│ ├── b.c +│ └── Makefile +└── README.md +``` + +### RIOT modules + +At a minimum, each module in RIOT requires a `Makefile` with the following content: + +```Makefile +MODULE := my_module + +include $(RIOTBASE)/Makefile.base +``` + +If `MODULE` is not specified, the name of the module's directory is automatically used, +leaving only the last line as minimal content. +It is important to note that module names have to be unique both among _all_ RIOT modules, +i.e., including the modules that are part of RIOT itself. + +If not manually specified via `SRC`, all source files which reside +directly in the module's directory are considered part of the module. +RIOT modules are also described in greater detail [in the documentation](https://doc.riot-os.org/creating-modules.html). + +Two lines need to be added to the application's Makefile in order to compile and use the module: + +```Makefile +DIRS += module +USEMODULE += my_module +``` + +The string added to `DIRS` has to match the directory name, +while the string added to `USEMODULE` has to match the module's name as defined above. + + +### Subfolders + +Compared to the module approach, no additional Makefile is needed in the subfolder. +The application's Makefile needs to add _all_ source files explicitly, +including the ones residing directly in the application directory: + +```Makefile +SRC += main.c +SRC += folder/a.c folder/subfolder/b.c +``` + +To avoid listing all source files individually, it is of course possible +to use normal GNU make functions such as `wildcard`: + +```Makefile +SRC += $(wildcard *.c folder/*.c folder/**/*.c) +``` + + +## Which approach should I use? + +In general, modules in RIOT are well-defined units of code that provide a set of features to your application. +If this matches your use-case, i.e., you have all your application tests separated into a subfolder, +RIOT modules are probably the best approach. +It is good practice to prefix all your application modules to avoid name clashes. + +If however you barely want to organize your files in a sensible folder structure, +but always require all source files to be part of your application, +the more straight-forward subfolder approach is probably the better pick. diff --git a/examples/subfolders/folder/a.c b/examples/subfolders/folder/a.c new file mode 100644 index 0000000000000..7d5f66244f0c9 --- /dev/null +++ b/examples/subfolders/folder/a.c @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +void folder_a(void) +{ + puts("./folder/a.c"); +} diff --git a/examples/subfolders/folder/subfolder/b.c b/examples/subfolders/folder/subfolder/b.c new file mode 100644 index 0000000000000..5aace94347ba5 --- /dev/null +++ b/examples/subfolders/folder/subfolder/b.c @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +void folder_b(void) +{ + puts("./folder/subfolder/b.c"); +} diff --git a/examples/subfolders/main.c b/examples/subfolders/main.c new file mode 100644 index 0000000000000..f7a8cf54b3b8d --- /dev/null +++ b/examples/subfolders/main.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief Application showcasing the use of subfolders in RIOT applications + * + * @author Mikolai Gütschow + * + * @} + */ + +#include + +void module_a(void); +void module_b(void); +void folder_a(void); +void folder_b(void); + +int main(void) +{ + puts("./main.c"); + // call functions from RIOT module + module_a(); + module_b(); + // call functions from subfolder + folder_a(); + folder_b(); + + return 0; +} diff --git a/examples/subfolders/module/Makefile b/examples/subfolders/module/Makefile new file mode 100644 index 0000000000000..831cf70a7d625 --- /dev/null +++ b/examples/subfolders/module/Makefile @@ -0,0 +1,3 @@ +MODULE := my_module + +include $(RIOTBASE)/Makefile.base diff --git a/examples/subfolders/module/a.c b/examples/subfolders/module/a.c new file mode 100644 index 0000000000000..15a8f1ae6e07b --- /dev/null +++ b/examples/subfolders/module/a.c @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +void module_a(void) +{ + puts("./module/a.c"); +} diff --git a/examples/subfolders/module/b.c b/examples/subfolders/module/b.c new file mode 100644 index 0000000000000..32d98a7661a6a --- /dev/null +++ b/examples/subfolders/module/b.c @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2023 TU Dresden + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +void module_b(void) +{ + puts("./module/b.c"); +} From 62ff1f9e317f44c226f14127fc461593a4a100bf Mon Sep 17 00:00:00 2001 From: pierre Date: Fri, 1 Nov 2024 11:31:23 +0100 Subject: [PATCH 5/7] Add tests for SRC in makefile --- tests/build_system/src_folders/Makefile | 18 ++++++++ .../blob/blob_subdir/blobtest_subdir.txt | 1 + .../build_system/src_folders/blob/blob_test.c | 17 +++++++ tests/build_system/src_folders/folder/a.c | 15 ++++++ .../src_folders/folder/subfolder/b.c | 15 ++++++ tests/build_system/src_folders/main.c | 46 +++++++++++++++++++ .../src_folders/module_testing/Makefile | 3 ++ .../src_folders/module_testing/a.c | 16 +++++++ .../src_folders/module_testing/b.c | 15 ++++++ 9 files changed, 146 insertions(+) create mode 100644 tests/build_system/src_folders/Makefile create mode 100644 tests/build_system/src_folders/blob/blob_subdir/blobtest_subdir.txt create mode 100644 tests/build_system/src_folders/blob/blob_test.c create mode 100644 tests/build_system/src_folders/folder/a.c create mode 100644 tests/build_system/src_folders/folder/subfolder/b.c create mode 100644 tests/build_system/src_folders/main.c create mode 100644 tests/build_system/src_folders/module_testing/Makefile create mode 100644 tests/build_system/src_folders/module_testing/a.c create mode 100644 tests/build_system/src_folders/module_testing/b.c diff --git a/tests/build_system/src_folders/Makefile b/tests/build_system/src_folders/Makefile new file mode 100644 index 0000000000000..ce206e3285d15 --- /dev/null +++ b/tests/build_system/src_folders/Makefile @@ -0,0 +1,18 @@ +include ../Makefile.build_system_common + +# Add subfolders as modules +DIRS += module_testing +USEMODULE += my_module + +# Add fmt to read blob +USEMODULE += fmt + +# Add blobs +BLOBS += blob/blob_subdir/blobtest_subdir.txt + +SRC += main.c +SRC += folder/a.c blob/blob_test.c folder/subfolder/b.c +# # Alternative method to add files in subfolders using wildcards +# # SRC += $(wildcard *.c blob/*.c folder/*.c folder/**/*.c) + +include $(RIOTBASE)/Makefile.include diff --git a/tests/build_system/src_folders/blob/blob_subdir/blobtest_subdir.txt b/tests/build_system/src_folders/blob/blob_subdir/blobtest_subdir.txt new file mode 100644 index 0000000000000..75560a77516f0 --- /dev/null +++ b/tests/build_system/src_folders/blob/blob_subdir/blobtest_subdir.txt @@ -0,0 +1 @@ +Hello blob_subdir! diff --git a/tests/build_system/src_folders/blob/blob_test.c b/tests/build_system/src_folders/blob/blob_test.c new file mode 100644 index 0000000000000..97edc26017008 --- /dev/null +++ b/tests/build_system/src_folders/blob/blob_test.c @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2024 Orange + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include "fmt.h" + +#include "blob/blob/blob_subdir/blobtest_subdir.txt.h" + +void blob_print(void) +{ + print((char *)blobtest_subdir_txt, blobtest_subdir_txt_len); + print("\n", 1); +} diff --git a/tests/build_system/src_folders/folder/a.c b/tests/build_system/src_folders/folder/a.c new file mode 100644 index 0000000000000..3491bf896c4ba --- /dev/null +++ b/tests/build_system/src_folders/folder/a.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2023 TU Dresden + * Copyright (C) 2024 Orange + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +void folder_a(void) +{ + puts("./folder/a.c"); +} diff --git a/tests/build_system/src_folders/folder/subfolder/b.c b/tests/build_system/src_folders/folder/subfolder/b.c new file mode 100644 index 0000000000000..af97dd0737860 --- /dev/null +++ b/tests/build_system/src_folders/folder/subfolder/b.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2023 TU Dresden + * Copyright (C) 2024 Orange + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +void folder_b(void) +{ + puts("./folder/subfolder/b.c"); +} diff --git a/tests/build_system/src_folders/main.c b/tests/build_system/src_folders/main.c new file mode 100644 index 0000000000000..b963c234a34cd --- /dev/null +++ b/tests/build_system/src_folders/main.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024 Orange + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + + +/** + * @ingroup tests + * @{ + * + * @file + * @brief Test proving SRC subfolders compatibility with RIOT. + * + * @author Pierre Le Meur + * + * + * @} + */ + +#include + +void module_a(void); +void module_b(void); +void folder_a(void); +void folder_b(void); +void blob_print(void); + +int main(void) +{ + puts("./main.c"); + + /* call functions from RIOT module */ + module_a(); + module_b(); + /* call functions from subfolder */ + folder_a(); + folder_b(); + + /* blob test */ + blob_print(); + + return 0; +} diff --git a/tests/build_system/src_folders/module_testing/Makefile b/tests/build_system/src_folders/module_testing/Makefile new file mode 100644 index 0000000000000..831cf70a7d625 --- /dev/null +++ b/tests/build_system/src_folders/module_testing/Makefile @@ -0,0 +1,3 @@ +MODULE := my_module + +include $(RIOTBASE)/Makefile.base diff --git a/tests/build_system/src_folders/module_testing/a.c b/tests/build_system/src_folders/module_testing/a.c new file mode 100644 index 0000000000000..405d783d3f1b7 --- /dev/null +++ b/tests/build_system/src_folders/module_testing/a.c @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2023 TU Dresden + * Copyright (C) 2024 Orange + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + + +#include + +void module_a(void) +{ + puts("./module_testing/a.c"); +} diff --git a/tests/build_system/src_folders/module_testing/b.c b/tests/build_system/src_folders/module_testing/b.c new file mode 100644 index 0000000000000..f1a46b4f7aff5 --- /dev/null +++ b/tests/build_system/src_folders/module_testing/b.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2023 TU Dresden + * Copyright (C) 2024 Orange + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +void module_b(void) +{ + puts("./module_testing/b.c"); +} From ae2c562fd520c7b5d40ae38c0700c16e0eb96c71 Mon Sep 17 00:00:00 2001 From: pierre Date: Mon, 4 Nov 2024 08:07:03 +0100 Subject: [PATCH 6/7] Remove duplicate example --- tests/build_system/src_folders/Makefile | 8 ++------ tests/build_system/src_folders/folder/a.c | 15 --------------- .../src_folders/folder/subfolder/b.c | 15 --------------- tests/build_system/src_folders/main.c | 12 ------------ .../src_folders/module_testing/Makefile | 3 --- .../build_system/src_folders/module_testing/a.c | 16 ---------------- .../build_system/src_folders/module_testing/b.c | 15 --------------- 7 files changed, 2 insertions(+), 82 deletions(-) delete mode 100644 tests/build_system/src_folders/folder/a.c delete mode 100644 tests/build_system/src_folders/folder/subfolder/b.c delete mode 100644 tests/build_system/src_folders/module_testing/Makefile delete mode 100644 tests/build_system/src_folders/module_testing/a.c delete mode 100644 tests/build_system/src_folders/module_testing/b.c diff --git a/tests/build_system/src_folders/Makefile b/tests/build_system/src_folders/Makefile index ce206e3285d15..cf2ff2c985f6f 100644 --- a/tests/build_system/src_folders/Makefile +++ b/tests/build_system/src_folders/Makefile @@ -1,17 +1,13 @@ include ../Makefile.build_system_common -# Add subfolders as modules -DIRS += module_testing -USEMODULE += my_module - -# Add fmt to read blob +## Add fmt to read blob USEMODULE += fmt # Add blobs BLOBS += blob/blob_subdir/blobtest_subdir.txt SRC += main.c -SRC += folder/a.c blob/blob_test.c folder/subfolder/b.c +SRC += blob/blob_test.c # # Alternative method to add files in subfolders using wildcards # # SRC += $(wildcard *.c blob/*.c folder/*.c folder/**/*.c) diff --git a/tests/build_system/src_folders/folder/a.c b/tests/build_system/src_folders/folder/a.c deleted file mode 100644 index 3491bf896c4ba..0000000000000 --- a/tests/build_system/src_folders/folder/a.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2023 TU Dresden - * Copyright (C) 2024 Orange - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -#include - -void folder_a(void) -{ - puts("./folder/a.c"); -} diff --git a/tests/build_system/src_folders/folder/subfolder/b.c b/tests/build_system/src_folders/folder/subfolder/b.c deleted file mode 100644 index af97dd0737860..0000000000000 --- a/tests/build_system/src_folders/folder/subfolder/b.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2023 TU Dresden - * Copyright (C) 2024 Orange - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -#include - -void folder_b(void) -{ - puts("./folder/subfolder/b.c"); -} diff --git a/tests/build_system/src_folders/main.c b/tests/build_system/src_folders/main.c index b963c234a34cd..e3ebb33a35c69 100644 --- a/tests/build_system/src_folders/main.c +++ b/tests/build_system/src_folders/main.c @@ -22,22 +22,10 @@ #include -void module_a(void); -void module_b(void); -void folder_a(void); -void folder_b(void); void blob_print(void); int main(void) { - puts("./main.c"); - - /* call functions from RIOT module */ - module_a(); - module_b(); - /* call functions from subfolder */ - folder_a(); - folder_b(); /* blob test */ blob_print(); diff --git a/tests/build_system/src_folders/module_testing/Makefile b/tests/build_system/src_folders/module_testing/Makefile deleted file mode 100644 index 831cf70a7d625..0000000000000 --- a/tests/build_system/src_folders/module_testing/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -MODULE := my_module - -include $(RIOTBASE)/Makefile.base diff --git a/tests/build_system/src_folders/module_testing/a.c b/tests/build_system/src_folders/module_testing/a.c deleted file mode 100644 index 405d783d3f1b7..0000000000000 --- a/tests/build_system/src_folders/module_testing/a.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2023 TU Dresden - * Copyright (C) 2024 Orange - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - - -#include - -void module_a(void) -{ - puts("./module_testing/a.c"); -} diff --git a/tests/build_system/src_folders/module_testing/b.c b/tests/build_system/src_folders/module_testing/b.c deleted file mode 100644 index f1a46b4f7aff5..0000000000000 --- a/tests/build_system/src_folders/module_testing/b.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2023 TU Dresden - * Copyright (C) 2024 Orange - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -#include - -void module_b(void) -{ - puts("./module_testing/b.c"); -} From 873378fe3b91047e787355d1485b859f24eee9d2 Mon Sep 17 00:00:00 2001 From: pierre Date: Mon, 4 Nov 2024 08:54:56 +0100 Subject: [PATCH 7/7] Add usage of SRC in doc --- doc/doxygen/src/creating-an-application.md | 68 ++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/doc/doxygen/src/creating-an-application.md b/doc/doxygen/src/creating-an-application.md index 0cdfd743869d5..3d7f468448d94 100644 --- a/doc/doxygen/src/creating-an-application.md +++ b/doc/doxygen/src/creating-an-application.md @@ -197,6 +197,74 @@ inside a modules os boards directory. The RIOT build system has both `EXTERNAL_MODULE_DIRS` and `EXTERNAL_BOARD_DIRS` variables to specify directories that contain extra modules and extra boards. +## Using subfodlers in application + +Applications can contain subfolders. + +``` +├── apps +│   └── my_app +│   ├── app_dependant +│   │   └── file.c +│   ├── Makefile +│   └── main.c +└── RIOT +``` + +To add subfolders, `SRC` can be used. + +The `Makefile` in my_app will be : + +``` +APPLICATION = my_app +PROJECT_BASE ?= $(CURDIR)/../.. +RIOTBASE ?= $(PROJECT_BASE)/RIOT + +# Declare the main.c and all .c file in subfolders +# that doesn't need to be done with module +SRC += main.c +SRC += app_dependant/file.c + +include $(RIOTBASE)/Makefile.include +``` + +`SRC` allows creating subfolders without needing to create a module with a `Makefile` but can be combined with modules: + +``` +├── apps +│   └── my_app +| ├── my_app_module +| | ├── Makefile +│   │   └── module.c +│   ├── app_dependant +│   │   └── file.c +│   ├── Makefile +│   └── main.c +└── RIOT +``` + +my_app got one subfolder and one module called my_app_module. + +When we want to add modules, we have nothing to add in `SRC`; we only add `DIRS` and `USEMODULE`: + +``` +APPLICATION = my_app +PROJECT_BASE ?= $(CURDIR)/../.. +RIOTBASE ?= $(PROJECT_BASE)/RIOT + +# Declare directory where the module is and +# usage of it. +DIRS += my_app_module +USEMODULE += my_app_module + +# Declare the main.c and all .c file in subfolders, +# which doesn't need to be done with modules. +SRC += main.c +SRC += app_dependant/file.c + +include $(RIOTBASE)/Makefile.include +``` + ## External Boards External boards can be ported in an identical way as porting a regular board to