Search code examples
c++ccmakestm32

How can I apply target-specific compiler and linker flags to subdirectories in CMake?


I am using CMake for a STM32 project as the project is outgrowing a plain Makefile. My directory structure looks something like what's below. I have an executable defined in the root CMakeLists.txt and somelib compiled as an OBJECT library which is added to the main CMakeLists.txt using add_subdirectory.

CMakeLists.txt
src/
├─ app/
│  ├─ main.c
├─ lib/
│  ├─ somelib/
│  │  ├─ CMakeLists.txt
│  │  ├─ somelib.h
│  │  ├─ somelib.c

I need to compile and link the source files with some flags specific to my microcontroller (i.e. -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard). I set up a toolchain file for the arm-none-eabi-gcc compiler and handled the compiler-specific flags there, but I'm hesitant to put the microcontroller-specific flags in that toolchain file as well since this project could expand to where I'd want to run my project on a different microcontroller.

My problem is if I were to define the microcontroller specific flags in the root CMakeLists.txt, when it comes time to compile somelib, I don't know how I can get somelib to compile with those flags. I know that I could use the global add_compile_options and add_libraries, but that seems like a bad idea, especially if I want to support a different microcontroller in the same project as well that would have a different set of flags. How can I propagate compiler and linker settings to the subdirectories for a specific executable?


Solution

  • I'm hesitant to put the microcontroller-specific flags in that toolchain file as well since this project could expand to where I'd want to run my project on a different microcontroller.

    So don't be hesitant and do that. And when you will move to a different microcontroller, you will have a different toolchain file for it. Have one toolchain for every unique set of compiler flags. -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard flags definitely belong to a toolchain file.


    When you want to support many many many toolchain files combinations and want to go a bit advanced, you might want to use the default behavior of sourcing Platform/${CMAKE_SYSTEM_NAME}-GNU-C-${CMAKE_SYSTEM_PROCESSOR}.cmake file from CMake module search path. That, combined with some custom variables -DUSE_FLOAT=hard/soft and -DMFPU=fpv4-sp-d16 makes a nice structure view.