Skip to content

[build sytem] many system wide macros injected more than once #21966

@maribu

Description

@maribu

Description

The build system provides a number of predefined preprocessor macros (e.g. RIOT_VERSION, RIOT_CPU, RIOT_BOARD, ...). There are two ways the build system passes those preprocessor macros to the compiler:

  1. Via CFLAGS (e.g. -DRIOT_APPLICATION=\"default\")
  2. Via -include riotbuild.h, where riotbuild.h contains lots of generated macros

Steps to reproduce the issue

  1. Run make BOARD=nucleo-f767zi QUIET=0 -C examples/basic/default/
  2. Check the console output above for -D... arguments passed to GCC. (Looking at a single GCC call is sufficient)
  3. Check the contents of examples/basic/default/bin/nucleo-f767zi/riotbuild/riotbuild.h

Expected results

  1. Each system wide macro is injected exactly once using either riotbuild.h or -D...
  2. There is some reasoning and strategy behind using riotbuild.h over -D

Actual results

  1. Most macros are injected with both ways, one macro (-DCONFIG_GNRC_PKTBUF_SIZE=512) is injected three times with both ways
  2. Modules are only provided via riotbuild.h, other than that it looks like complete chaos
Evaluation that lead to above conclusion

When building with QUIET=0 I get the following command for compiling e.g. assert.c:

ccache arm-none-eabi-gcc \
	-DRIOT_FILE_RELATIVE=\"core/lib/assert.c\" \
	-DRIOT_FILE_NOPATH=\"assert.c\" \
	-DDEVELHELP -Werror -DCONFIG_GNRC_PKTBUF_SIZE=512 -DCONFIG_GNRC_PKTBUF_SIZE=512 -DCONFIG_GNRC_PKTBUF_SIZE=512 -DCPU_FAM_STM32F7 -DSTM32F767xx -DCPU_LINE_STM32F767xx -DSTM32_FLASHSIZE=2097152U -D__SYSTEM_STM32F7XX_H -DSYSTEM_STM32F7XX_H -mno-thumb-interwork -mcpu=cortex-m7 -mlittle-endian -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 -ffunction-sections -fdata-sections -fshort-enums -ggdb -g3 -Os -DCPU_MODEL_STM32F767ZI -DCPU_CORE_CORTEX_M7 -DCPU_HAS_BACKUP_RAM=1 --param=min-pagesize=0 -DRIOT_APPLICATION=\"default\" -DBOARD_NUCLEO_F767ZI=\"nucleo-f767zi\" -DRIOT_BOARD=BOARD_NUCLEO_F767ZI -DCPU_STM32=\"stm32\" -DRIOT_CPU=CPU_STM32 -std=c11 -fwrapv -Wstrict-overflow -fno-common -ffunction-sections -fdata-sections -Wall -Wextra -Wmissing-include-dirs -fno-delete-null-pointer-checks -fdiagnostics-color -Wstrict-prototypes -Wold-style-definition -gz -Wformat=2 -Wformat-overflow -Wformat-truncation -fmacro-prefix-map=$REPOPATH/= -Wcast-align -DCPU_RAM_BASE=0x20000000 -DCPU_RAM_SIZE=0x80000 -DRTT_FREQUENCY=RTT_MAX_FREQUENCY -D__int64_t_defined=1 -include '$REPOPATH/examples/basic/default/bin/nucleo-f767zi/riotbuild/riotbuild.h'  -isystem /usr/include/newlib/nano -I$REPOPATH/examples/basic/default -I$REPOPATH/core/lib/include -I$REPOPATH/core/include -I$REPOPATH/drivers/include -I$REPOPATH/sys/include -I$REPOPATH/boards/nucleo-f767zi/include -I$REPOPATH/boards/common/nucleo/include -I$REPOPATH/boards/common/stm32/include -I$REPOPATH/boards/common/nucleo144/include -I$REPOPATH/cpu/stm32/include -I/home/[email protected]/.cache/RIOT/stm32/cmsis/f7/Include -I$REPOPATH/cpu/stm32/include/clk -I$REPOPATH/cpu/cortexm_common/include -I$REPOPATH/sys/libc/include -isystem/home/[email protected]/.cache/RIOT/pkg/cmsis/CMSIS/Core/Include -I$REPOPATH/sys/net/gnrc/pktbuf/include -I$REPOPATH/sys/net/gnrc/pktbuf_static/include -I$REPOPATH/sys/net/link_layer/eui_provider/include -I$REPOPATH/sys/auto_init/include -I$REPOPATH/examples/basic/default/bin/nucleo-f767zi/preprocessor -MQ '$REPOPATH/examples/basic/default/bin/nucleo-f767zi/core_lib/assert.o' -MD -MP -c -o $REPOPATH/examples/basic/default/bin/nucleo-f767zi/core_lib/assert.o $REPOPATH/core/lib/assert.c

Filtering out only the macros in that command and sorting them, I get:

-DBOARD_NUCLEO_F767ZI=\"nucleo-DRIOT_BOARD=BOARD_NUCLEO_F767ZI
-DCONFIG_GNRC_PKTBUF_SIZE=512
-DCONFIG_GNRC_PKTBUF_SIZE=512
-DCONFIG_GNRC_PKTBUF_SIZE=512
-DCPU_CORE_CORTEX_M7
-DCPU_FAM_STM32F7
-DCPU_HAS_BACKUP_RAM=1
-DCPU_LINE_STM32F767xx
-DCPU_MODEL_STM32F767ZI
-DCPU_RAM_BASE=0x20000000
-DCPU_RAM_SIZE=0x80000
-DCPU_STM32=\"stm32\"
-DDEVELHELP
-D__int64_t_defined=1
-DRIOT_APPLICATION=\"default\"
-DRIOT_CPU=CPU_STM32
-DRIOT_FILE_NOPATH=\"assert.c\"
-DRIOT_FILE_RELATIVE=\"core/lib/assert.c\"
-DRTT_FREQUENCY=RTT_MAX_FREQUENCY
-DSTM32F767xx
-DSTM32_FLASHSIZE=2097152U
-D__SYSTEM_STM32F7XX_H
-DSYSTEM_STM32F7XX_H

Sorting the contents of riotbuild.h, filtering out the #ifdef DOXYGEN ... #endif and all instances of #define MODULE_..., I have:

#define BOARD_NUCLEO_F767ZI "nucleo-f767zi"
#define CONFIG_GNRC_PKTBUF_SIZE 512
#define CONFIG_GNRC_PKTBUF_SIZE 512
#define CONFIG_GNRC_PKTBUF_SIZE 512
#define CPU_CORE_CORTEX_M7 1
#define CPU_FAM_STM32F7 1
#define CPU_HAS_BACKUP_RAM 1
#define CPU_LINE_STM32F767xx 1
#define CPU_MODEL_STM32F767ZI 1
#define CPU_RAM_BASE 0x20000000
#define CPU_RAM_SIZE 0x80000
#define CPU_STM32 "stm32"
#define DEVELHELP 1
#define __int64_t_defined 1
#define RIOT_APPLICATION "default"
#define RIOT_BOARD BOARD_NUCLEO_F767ZI
#define RIOT_CPU CPU_STM32
#define RIOT_MCU        MACRO_DEPRECATED RIOT_CPU
#define RIOT_VERSION "2026.01-devel-302-g2bd24"
#define RIOT_VERSION_CODE RIOT_VERSION_NUM(2026,01,0,0)
#define RTT_FREQUENCY RTT_MAX_FREQUENCY
#define STM32F767xx 1
#define STM32_FLASHSIZE 2097152U
#define __SYSTEM_STM32F7XX_H 1
#define SYSTEM_STM32F7XX_H 1

So we see that:

  1. Every -D.... from $(CFLAGS) is injected a second time with -include riotbuild.h
  2. Some macros (e.g. CONFIG_GNRC_PKTBUF_SIZE) are provided multiple times with either method.

Versions

Current master

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions