gcccmakeninja

CMake: remove compile option


I have a CMake project that is partially generated by another software. To be exact, the project contains:

Hereunder is a minimal version of my project:

cmake_minimum_required(VERSION "3.25")

project(
    empty_cpp
    LANGUAGES C CXX ASM
)

include(empty_cpp.cmake)

add_executable(
    empty_cpp
)

target_link_libraries(empty_cpp PRIVATE
    slc_empty_cpp
)

set_target_properties(empty_cpp PROPERTIES LINKER_LANGUAGE C)
add_library(slc_empty_cpp OBJECT
    "../main.cpp"
)

target_link_libraries(slc_empty_cpp PUBLIC
    "-Wl,--start-group"
    "stdc++"
    "gcc"
    "c"
    "nosys"
    "-Wl,--end-group"
)

target_compile_options(slc_empty_cpp PUBLIC
    $<$<COMPILE_LANGUAGE:CXX>:-mcpu=cortex-m33>
    $<$<COMPILE_LANGUAGE:CXX>:-mthumb>
)

target_link_options(slc_empty_cpp INTERFACE
    -mcpu=cortex-m33
)

I would like to remove some of the compile options set in empty_cpp.cmake from CMakeLists.txt. In this example, I would like to remove the mthumb option, but I can't figure out how.

I tried to update CMakeLists.txt as followed:

cmake_minimum_required(VERSION "3.25")

project(
    empty_cpp
    LANGUAGES C CXX ASM
)

include(empty_cpp.cmake)

# start of additional code
get_target_property(interface_compile_options slc_empty_cpp INTERFACE_COMPILE_OPTIONS)
list(REMOVE_ITEM interface_compile_options 
            $<$<COMPILE_LANGUAGE:CXX>:-mthumb>
)

set_target_properties(slc_empty_cpp PROPERTIES INTERFACE_COMPILE_OPTIONS "${interface_compile_options}")

get_target_property(interface_compile_options2 slc_empty_cpp INTERFACE_COMPILE_OPTIONS)
message(STATUS "compile options ${interface_compile_options2}")
# end of additional code

add_executable(
    empty_cpp
)

target_link_libraries(empty_cpp PRIVATE
    slc_empty_cpp
)

set_target_properties(empty_cpp PROPERTIES LINKER_LANGUAGE C)

When configuring the project, the log message shows that there is no "-mthumb" option in the compile options:

[cmake] -- compile options $<$<COMPILE_LANGUAGE:CXX>:-mcpu=cortex-m33>

However, if I take a look at the generated ninja file, the option is still there :

...
build CMakeFiles/slc_empty_cpp.dir/default_config/C_/Projets/empty_cpp_test/main.cpp.obj: CXX_COMPILER__slc_empty_cpp_unscanned_default_config C$:/Projets/empty_cpp_test/main.cpp || cmake_object_order_depends_target_slc_empty_cpp_DEFAULT_CONFIG
  DEFINES = -DCMAKE_INTDIR=\"default_config\"
  DEP_FILE = CMakeFiles\slc_empty_cpp.dir\default_config\C_\Projets\empty_cpp_test\main.cpp.obj.d
  FLAGS = -mcpu=cortex-m33 -g -mthumb
  OBJECT_DIR = CMakeFiles\slc_empty_cpp.dir\default_config
  OBJECT_FILE_DIR = CMakeFiles\slc_empty_cpp.dir\default_config\C_\Projets\empty_cpp_test

What am I missing ? Is what i want to do possible ?


Solution

  • As mentionned by @Tsyvarev, target_compile_options() has been called with PUBLIC keyword. With this keyword, the function adds compile options to two properties:

    In my solution, I was only removing the option from the INTERFACE_COMPILE_OPTIONS property.

    The solution is to also remove options from the COMPILE_OPTIONS property.

    get_target_property(interface_compile_options slc_empty_cpp INTERFACE_COMPILE_OPTIONS)
    list(REMOVE_ITEM interface_compile_options 
                $<$<COMPILE_LANGUAGE:CXX>:-mthumb>
    )
    
    set_target_properties(slc_empty_cpp PROPERTIES INTERFACE_COMPILE_OPTIONS "${interface_compile_options}")
    # The same list is used for both properties, 
    # because in this example compile options have only been created with 'PUBLIC' keyword
    set_target_properties(slc_empty_cpp PROPERTIES COMPILE_OPTIONS "${interface_compile_options}")