Hi. I would like to make a choice between 2 files to pass to the compiler options according to a macro defined in compile_definitions of CMake. How to get this macro in a variable for example and test it please?
It’s not clear to me what you’re asking. Can you share more details to make it a bit more concrete?
I am writing a library for 2 different MCUs with 2 different toolchains. I would like to be able to choose macros depending on the MCU I want to use and the appropriate toochain. In order to choose the right file for each toolchain (the linker script in locurence), I would like to be able to retrieve the defined macro in order to choose the right file to use for the right toolchain. I need a way to retrieve the macro I would have defined. There for example i want a way to retrieve and test the first macro (STM32F303). That will be test since it can either it or STM32F411
target_compile_definitions(
${TARGET_NAME} PRIVATE
-DSTM32F303
-D_DSP_LIB
-D_USE_RTTI
-D_ENABLE_IRQ
)
You can access the compile definitions for a target with get_property(defines TARGET ${TARGET_NAME} PROPERTY COMPILE_DEFINITIONS)
. Note that this only gets target-specific flags; it will miss things coming in from CMAKE_C_FLAGS
, directory-scoped add_definitions
, or usage requirements.
I think a better solution would be something like this:
add_library(mcu_stm32f411 INTERFACE)
target_compile_definitions(mcu_stm32f411 INTERFACE STM32F411)
target_link_options(mcu_stm32f411 INTERFACE "SHELL:-flag_for linker_script") # or whatever is needed
and similarly for mcu_stm32f303
. You can then choose which to use per-target without having to consider the other bits.
Thanks for your response. but i dont think it will be suitable for my case. I need something like that
if(TOOLCHAIN_DIRECTORY PATH_EQUAL "$ENV{TI_TOOLCHAIN_PATH}")
set(LINKER_FILE ${CMAKE_SOURCE_DIR}/device/linker_commands/STM32F303_boot.cmd)
elseif(TOOLCHAIN_DIRECTORY PATH_EQUAL "$ENV{GNU_TOOLCHAIN_PATH}")
set(LINKER_FILE ${CMAKE_SOURCE_DIR}/device/linker_scripts/STM32F303_boot.ld)
endif()
This is for the first toolchain depending of the target define STM32F303. Now i want a way to choose another linker files depending of that define. So i want a way to check the entered define and then proceed to the selection of the correct files. The 2 toolchains are differents and dont share the same options
To check if a symbol is defined, you can use try_compile
with a source file such as:
#ifdef YOURSYMBOL
#error WAS_DEFINED
#else
#error NOT_DEFINED
#endif
call try_compile
and then check if the error output includes the string WAS_DEFINED
.
There is not a way to get only the first macro defined here (STM32F303) and store it in a variable ?
target_compile_definitions(
${TARGET_NAME} PRIVATE
-DSTM32F303
-D_DSP_LIB
-D_USE_RTTI
-D_ENABLE_IRQ
)
I dont want it to access any of my source code. The symbols are already defined. I choose one of them with a global macro defined in CMake compile_definitions propriety
get_property
can only get the whole list. You can use list()
operations to inspect that list though.
Thanks. So get_property(defines TARGET ${TARGET_NAME} PROPERTY COMPILE_DEFINITIONS)
will get the list of all compile definitions without -D and will store them in defines
right ?
I tried many names but didn’t get the right result
target_compile_definitions(
${TARGET_NAME} PRIVATE
-DSTM32F303
-D_DSP_LIB
-D_USE_RTTI
-D_ENABLE_IRQ
)
get_target_property(DEFINES ${TARGET_NAME} COMPILE_DEFINITIONS)
# Get the first macro defined
list(GET DEFINES 0 DEVICE_DEFINE)
and then
if(DEVICE_DEFINE STREQUAL STM32F303)
set(LINKER_FILE ${CMAKE_SOURCE_DIR}/device/linker_commands/STM32F303_boot.cmd)
elseif(DEVICE_DEFINE STREQUAL STM32G473)
set(LINKER_FILE ${CMAKE_SOURCE_DIR}/device/linker_commands/STM32G473_boot.cmd)
endif()
But it didn’t worked. The file was not given to the linker as expected. Am I do something wrong ?
get_property and file solved my problem. Thanks. Now i can build for 2 targets usings 2 differents toolchains without errors