From 51613c8c9da899b86a5d1fc5f426bf88bae2e7f5 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] 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 000000000000..b5a8e8870687 --- /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 000000000000..14986afe579b --- /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 000000000000..7d5f66244f0c --- /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 000000000000..5aace94347ba --- /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 000000000000..f7a8cf54b3b8 --- /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 000000000000..831cf70a7d62 --- /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 000000000000..15a8f1ae6e07 --- /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 000000000000..32d98a7661a6 --- /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"); +}