cancel
Showing results for 
Search instead for 
Did you mean: 

CubeMX v6.14 makes impossible to use CMake-based project as part of another CMake project

imyosha
Associate

Yesterday I've switched from v6.13.0 to v6.14.1 and noticed that the new version changes the way cmake/stm32cubemx/CMakeLists.txt generated. Previously generated CMake list had relative paths like ../../Src/main.c, which works perfectly in both cases when CMakeLists.txt in root directory of project (the one generated by CubeMX) is the top-level CMake list and when it's not. But now (not sure from version 6.14.0 or 6.14.1) paths to files generated by CubeMX become absolute and use CMAKE_SOURCE_DIR variable as prefix directory (e.g. ${CMAKE_SOURCE_DIR}/Src/main.c). The new approach perfectly works when top-level CMake list is the one in project root directory generated by CubeMX, but it fails when used as part of another (non-CubeMX) top-level project, due to broken paths to source files.

 

A few words about my project structure:

my_cmake_project/
├── boards/
│   ├── BOARD_A/
│   │   ├── cmake/
│   │   │   ├── stm32cubemx/
│   │   │   │   └── CMakeLists.txt   <- defines "stm32cubemx" target with broken paths
│   │   │   └── gcc-arm-none-eabi.cmake
│   │   ├── Drivers/
│   │   ├── Inc/
│   │   ├── Src/
│   │   ├── BOARD_A.ioc
│   │   ├── CMakeLists.txt
│   │   └── ...
│   ├── BOARD_B/
│   │   └── as for BOARD_A
│   └── BOARD_C/
│       └── as for BOARD_A
├── CMakeLists.txt    <- defines library linked with executable in board/BOARD_x/CMakeLists.txt
└── src
    └── my_sources.h/c

I have a few similar boards with different microcontrollers and pin assignments, but with minor differences in business logic, all described in top-level library linked by each concrete board executable. Executables (firmwares) are generated by CubeMX for each board and only defines the driver for my library and call it functions in user code sections generated by CubeMX.

 

The problem with CMAKE_SOURCE_DIR is that it points to the most top-level CMakeLists.txt (the one located in source directory passed to cmake command with -S option), while in my case this is not BOARD_x/ directory as expects cmake/stm32cubemx/CMakeLists.txt, but my_cmake_project/ instead, which makes paths to generated sources in boards/BOARD_x/cmake/stm32cubemx/CMakeLists.txt broken. In my opinion assumption that top-level CMake list is the one generated by CubeMX is wrong, because CubeMX allows to edit this file, thus user allowed to remove project() command from it and use it as I use - within another CMake project (which is a good and flexible assumption).

 

I did not found simple way to patch this file (at least in cross-platform fashion), thus I suggest a few simple fixes for this issue:

  1. Revert things as it was before. The relative paths was right approach if we take into account how CMake-based projects are generated by CubeMX, because it does not force the project structure, but only works with paths touched by CubeMX.
  2. If there are some reason to switch from relative paths to absolute ones the cleanest approach is to change pattern to ${CMAKE_CURRENT_LIST_DIR}/../../Src/main.c. The CMAKE_CURRENT_LIST_DIR variable always points to directory where it referenced, which allows to ensure that paths are always built relative to regenerated CMake list.
  3. If presence of relative parts (../../) within the absolute path is a problem for some reason, then cmake_path() function could be used to generate normalized, absolute path:
set(MX_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../../)
cmake_path(NORMAL_PATH MX_ROOT_DIR OUTPUT_VARIABLE MX_ROOT_DIR)

target_include_directories(stm32cubemx INTERFACE
    ${MX_ROOT_DIR}/Inc
    ...
)

target_sources(stm32cubemx INTERFACE
    ${MX_ROOT_DIR}/main.c
    ...
)

Minor note about similar problems in other places

Toolchain file contains the same issue with path to linker script. It defines path to it as ${CMAKE_SOURCE_DIR}/STM32xxxxxx_FLASH.ld which has the same consequence as I described above. I've changed it to ${CMAKE_CURRENT_LIST_DIR}/../STM32xxxxxx_FLASH.ld to make things work in my project, but it will be cool if generated CMake-based project will be ready to use in more complex projects than just single binary with all user code within it.

 

The same issue appears in root CMakeLists.txt generated by CubeMX, it references variable CMAKE_PROJECT_NAME, which holds name passed to the first call of project() command, which in my case is not the thing CMake code expects. The simplest solution is to use by default PROJECT_NAME variable instead, which holds the name passed to last call of project() command.

2 REPLIES 2
Ghofrane GSOURI
ST Employee

Hello @imyosha 

Your detailed explanation is much appreciated.

This change request has been already raised to dev team in an internal ticket number  206627  .

I will keep you posted with updates .

THX

Ghofrane

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.