0

I want to use CMake to create modular embedded C++ software. I separated hal-drivers static library, some common-utils library and top target device depends on those two what is marked using target_link_libraries like this:

target_link_libraries(device
     PRIVATE
         hal-drivers
         common-utils
)

It is easy to propagate compile definitions and option up in "dependency ladder" using commands like this:

target_compile_definitions(hal-drivers
    INTERFACE
        STM32F415xx
        USE_HAL_DRIVER
)

This way any target utilising hal-drivers header files will preprocess those headers correctlym, and I found this CMake scripts feature (propagation of "settings") great, but it is not the point of this question.

The question is how should I propagate common compiler options like for example -fdata-sections or -Wall for every target in my project? I know I can

  • create dummy (no source and no header files, just compile options) interface target which will be consumed by every other target in project but this looks like a workaround...
  • specify mentioned compiler options for every target separatly, since I have only about 5 targets, but it will be very problematic to maintain.
  • In my commercial work project (50 targets) my boss ended up with an ugly compromise: setting common compile options in top CMakeLists.txt as cached variable and then applying this variable in all targets manually, but we dont like it at all.

Bear in mind: I do have solutions that work, I am interested in recomended solutions. Also I am using Professional CMake: A Practical Guide 9th Edition on daily basis (its a great book), but I failed to found answer on my question in this book.

Pierwiastek
  • 134
  • 9

1 Answers1

0

I found an answer.

I guess my whining about lack of elegant solution is due to my attachment to syntactic sugar like target_compile_options, but the thing is CMake evolved in hardship and not every CMake feature is pretty, but it works.

There is an answer: https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS.html The flags in this variable will be passed to the compiler before those in the per-configuration CMAKE_<LANG>_FLAGS_<CONFIG> variant, and before flags added by the add_compile_options() or target_compile_options() commands.

So I have to append my custom options to this special CMake variable like this:

project(Device C CXX ASM) 
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdata-sections")

This way it will flood all targets with fdata-sections.

Leaving this thread as interesting note.

Pierwiastek
  • 134
  • 9