This is an issue which I have since several years now and which always kept preventing me from transitioning to cmake for a larger STM32 project. I never found a reasonable solution so far, until I recently found a semi-acceptable work around, actually a very straight forward one.
The structure looks like this
shared
| LibA
| LibB
| ... (about 30 libraries)
stm32f7xx
| BoardA
| BoardB
stm32f4xx
| BoardC
I have everything set up and running, but I need to comment in/out the corresponding definitions
# only build stm32f7xx targets
set(MCU STM32F765xx)
add_definitions(-DSTM32F765xx)
# only build stm32f4xx targets
#set(MCU STM32F407xx)
#add_definitions(-DSTM32F407xx)
add_subdirectory(shared)
add_subdirectory(stm32f7xx)
add_subdirectory(stm32f4xx)
The BoardX
projects are wrapped in a conditional clause to only build when the proper MCU
is configured. So this way I can use make BoardA BoardB
but not make BoardC
.
I’ve tried a lot but I couldn’t find a proper way to build the shared directory twice without getting target name collisions. I tried around a lot with ExternalProject_Add
, but I couldn’t get it to work. I tried using execute_process
to call a secondary cmake
instance, which I don’t like very much.
I think the only cmake feature which might help would be Project-level namespaces as proposed in #22687.
So the only workaround I found so far is manually simulating namespaces, but it is a bit tedious. It effectively looks like this in EVERY project in any subdirectory, except the top level one.
project(${NS}LibA)
...
## dependencies
target_link_libraries(${PROJECT_NAME} ${NS}LibB)
...
add_library(${NS}Lib::LibA ALIAS ${PROJECT_NAME})
and then using it like this
set(NS STM32F4xx)
set(STM32_FAMILY STM32F4xx)
add_subdirectory(shared shared_stm32f4xx)
add_subdirectory(BoardA)
set(NS STM32F7xx)
set(STM32_FAMILY STM32F7xx)
add_subdirectory(shared shared_stm32f7xx)
add_subdirectory(BoardB)
This way I can just type
$ make BoardA BoardC
[ 33%] Built target STM32F4xxLibB
[ 66%] Built target STM32F4xxLibA
[100%] Built target BoardA
[ 33%] Built target STM32F7xxLibB
[ 66%] Built target STM32F7xxLibA
[100%] Built target BoardC
After month of procrastination because of this issue, I think I found an acceptable solution, although it requires to modify all CMakeLists it is something which can even be done automatically via Search&Replace. What do you think, any better suggestions how I could have solved this problem?
I really hope one day we get target namespaces, without knowning the details of the cmake code it looks to be something which would not require tremendous changes, but I know the devil is always in the detail.