Hi all. I had a question about what the most correct way to approach a source code arrangement that I encounter now and again, and how to deal with it in cmake.
I am trying to self-educate on CMake after having a fair amount of success with it for embedded (microcontroller) development after switching to CLion from vscode. So, maybe this is an obvious beginner’s stumble.
In this context, I frequently have source libraries that are configured by a header file.
In this case: The FreeRTOS kernel has a FreeRTOSConfig.h
that is broadly included, and sets the RTOS heap size (plus the availability of a bunch of features).
Given that this is for MCU, the entire application is statically linked and is one monolithic binary.
The organizational issue that I am not sure how to tackle is:
Is a configuration header a part of the “application” code? Or the “library” code?
This is one approach I have had some success with is to make the config its own “interface”:
add_library(FreeRTOS_Config INTERFACE)
add_custom_target(FreeRTOS_Config.headers SOURCES Inc/FreeRTOSConfig.h)
target_include_directories(FreeRTOS_Config INTERFACE ${PROJECT_SOURCE_DIR}/Inc)
target_link_libraries(FreeRTOS_Config INTERFACE FreeRTOS_kernel)
And separately provide the kernel as a library, e.g.
#### FreeRTOS Kernel ####
# Note: the CMSIS RTOS layer is bundled in this library
add_library( FreeRTOS_kernel STATIC
Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h
Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h
# etc
)
target_include_directories( FreeRTOS_kernel PUBLIC
Middlewares/Third_Party/FreeRTOS/Source/include
#etc
)
Ultimately, the issue that got me tripped up here is:
I later declare several executables from one code base (main app, unit testing variant, etc). When I set a target_compile_option
on one of those executables, e.g.
target_compile_definitions( app.elf PUBLIC -DDEBUG )
I find that that preprocessor definition is not present when the FreeRTOS_kernel
library is built on its own.
As far as I can figure, the header file is effectively logically part of the application (and thus the executable, AND multiple executables may use different variations of the config header), but that now means that the library would depend on the app, which does not seem correct.
Any insights here? Man, I should have learned “real software engineering” somewhere along the way …