Search code examples
ccmakestm32cmakelists-optionscmake-language

Stm32 project configuration using CMake


i have recently switched my stm32 project to CMake to be independent on IDE. Root repository (application) contains multiple submodules (HAL, FreeRTOS etc.) and its CMakeLists.txt includes explicitly every single used file:

set(EXECUTABLE ${PROJECT_NAME}.elf)

add_executable(${EXECUTABLE}
    
    # Own sources
    src/main.c
    src/SEGGER_SYSVIEW_Config_FreeRTOS.c
    src/startup_stm32h723zgtx.s
    src/stm32h7xx_hal_timebase_tim.c
    src/system_stm32h7xx.c

    # Base CMSIS and HAL library
    lib-hal/stm32h7xx/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c
    lib-hal/stm32h7xx/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c
    lib-hal/stm32h7xx/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c
    lib-hal/stm32h7xx/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c
    lib-hal/stm32h7xx/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c
            
    #long list of HAL c files there...

    # FreeRTOS library
    lib-freertos/croutine.c
    lib-freertos/event_groups.c
    lib-freertos/list.c
    lib-freertos/queue.c
    lib-freertos/stream_buffer.c
    lib-freertos/tasks.c
    lib-freertos/timers.c
    lib-freertos/portable/GCC/ARM_CM7/r0p1/port.c
    lib-freertos/trace/Sample/FreeRTOSV10/SEGGER_SYSVIEW_FreeRTOS.c
    lib-freertos/trace/SEGGER/Syscalls/SEGGER_RTT_Syscalls_GCC.c
    lib-freertos/trace/SEGGER/SEGGER_RTT_ASM_ARMv7M.S
    lib-freertos/trace/SEGGER/SEGGER_RTT_printf.c
    lib-freertos/trace/SEGGER/SEGGER_RTT.c
    lib-freertos/trace/SEGGER/SEGGER_SYSVIEW.c
    )
    
target_include_directories(${EXECUTABLE}
    PRIVATE
    include
    src
    
    lib-hal/stm32h7xx/CMSIS/Include
    lib-hal/stm32h7xx/CMSIS/Device/ST/STM32H7xx/Include
    lib-hal/stm32h7xx/STM32H7xx_HAL_Driver/Inc
    
    lib-freertos/include
    lib-freertos/trace/Config
    lib-freertos/trace/SEGGER
    lib-freertos/trace/Sample/FreeRTOSV10/
    lib-freertos/portable/GCC/ARM_CM7/r0p1
    )

This solution works but i know it is not a sustainable approach. So i tried to create library in lib-hal and lib-freertos submodules, specifying their sources and includes

add_library(lib-hal-stm32h7xx)

target_include_directories(lib-hal-stm32h7xx
    PUBLIC
    CMSIS/Include
    CMSIS/Device/ST/STM32H7xx/Include
    STM32H7xx_HAL_Driver/Inc
    PRIVATE
    STM32H7xx_HAL_Driver/Src
)

target_sources(lib-hal-stm32h7xx
    PRIVATE
    STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c
    STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c
    STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c
    STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c
    STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c

    #long list of HAL c files there...
)

and then using

add_subdirectory(lib-hal/stm32h7xx)
add_subdirectory(lib-freertos)

and

target_link_library(${EXECUTABLE} lib-freertos lib-hal-stm32h7xx)

to "import" submodules into application project. But when building the executable, gcc cannot access files stm32h7xx_hal_conf.h and FreeRTOSConfig.h which are located in root directory include. I do not want to put configuration headers into submodules because they are used in multiple projects with different configurations. Is it possible to somehow extend already specified directory search scope for library after adding it into parent project?

File structure of project:

-src
-include (configuration for lib-hal and lib-freertos included there)
 -lib-hal
  -includes...
  -sources...
 -lib-freertos
  -includes...
  -sources...

Thanks in advance for response.


Solution

  • As Tsyvarev mentioned in the comments, you can modify the properties of the target in your project. To keep things clean, I usually create a function for this and place it in a separate file.

    Tip: you can also add source files to the target. In case of FreeRTOS, you could add architecture-specific files, in case all your projects don't run on the same MCU family.

    function(configure_freertos target_name)
        target_sources(${target_name}
            PRIVATE
                lib-freertos/portable/GCC/ARM_CM7/r0p1/port.c
        )
    
        target_include_directories(${target_name}
            PUBLIC
                include
                lib-freertos/portable/GCC/ARM_CM7/r0p1
        )
    endfunction()