target_compile_definitions doesn't work in STM32CubeMX based projects

Sysprogs forums Forums VisualGDB target_compile_definitions doesn't work in STM32CubeMX based projects

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #33286
    john
    Participant

    I’m working with a project where I need to define some preprocessor symbols at build time in CMakeLists.txt. I’ve created a pair of demo projects to isolate the issue:

    I created a project using the regular embedded project wizard, opened its CMakeLists.txt, and added the line target_compile_definitions(DefineIssueDemo PRIVATE TEST_DEFINE=1). I then tested for the define in the main source file with
    #ifndef TEST_DEFINE
    #error "Missing define"
    #endif
    and the project built as expected.

    I repeated the test with a new project created with the STM32CubeMX wizard. Everything builds fine at first. I add the same lines to CMakeLists.txt (only change is that the target is named DefineIssueDemoCube) and to the main source file, and the build errors out with the “Missing define” error message I wrote.

    From my main project, I know that some other CMake target-based directives like target_link_libraries and target_link_options work fine. But target_compile_definitions and target_compile_options with -D options don’t work, it seems like the defines just get discarded.

    (For added context, the reason I need the defines is to create a bootloader. I’m following the VisualGDB advanced CMake bootloader tutorial, but because of the way the STM32CubeMX BSP works, the BSP’s main.c file is part of the build of both the main program and the bootloader. In order to have the main program move the interrupt vector table on start, I need to have different code execute in main.c depending on which target it’s being built by. Hence the need for target-specific defines.)

    Is this a bug, and is there a workaround for getting target-specific preprocessor defines into an STM32CubeMX based project?

    #33288
    support
    Keymaster

    Hi,

    This happens because CMake projects contain multiple targets, and setting the target_compile_definitions() for one target does not automatically affect others.

    You can find the list of targets (executables + static libraries) in Solution Explorer, or by analyzing the target-XXX.json files in the .visualgdb\VisualGDBCache subdirectory.

    If you are trying to setup a complex project layout involving multiple targets, we would advise first sketching how many targets it would involve, how they would reference each other, and then setting up the target_compile_definitions() accordingly. If you are new to CMake, we would advise reading about the public/private/interface definitions – it will help you setup everything efficiently.

    You can also use our CMake Debugger to step through the CMakeLists files and see how and where various settings are applied.

    #33296
    john
    Participant

    I took a look at those cached target files and I see the issue now, main.c is built as part of the “BSP” target. I changed the line to target_compile_definitions(BSP PRIVATE TEST_DEFINE=1) and the define is now available in main.c. This has also clarified for me that the BSP is actually only built once even when there’s two separate add_bsp_based_executable’s in the same solution, so I need to introduce any divergent behavior between the main program and the bootloader at link time, not compile time. So I can’t really get what I want with preprocessor defines anyway.

    I’ll see what I can do, it’s definitely a little bit of a thorn in the side that STM32CubeMX forces you to use a main() defined in an auto-generated file if you want to use the auto-generated BSP. Suppose I can always change the entry point with a target_link_options line if it really becomes an issue.

    Thanks for the help!

    #33302
    support
    Keymaster

    Good to know it works.

    The STM32CubeMX generator insists on generating the main file so that it could automatically switch between non-RTOS vs. FreeRTOS configurations, that have a completely different initialization sequence, but we do agree that it is not very convenient.

    If you absolutely want to override it, you can mark the file as “excluded from build” via the context menu, and provide your own main file, however it could cause weird conflicts in case the logic in STM32CubeMX changes in future versions.

Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.