Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change a compiler flag for just one executable in CMake?

I have a CMake project that supports multiple processor compilation in Visual Studio through the \MP flag.

Since in just one of the many executable that the project builds, I need to set the \MP flag to false (or disable it because I get errors importing a .tlb file), how can I set the flags for this target different?

add_executable(MyProgram myprogram.cpp)
target_link_libraries(MyProgram MyLibraries)

Should I give some set_target_properties to cmake or specifically remove the flag from the whole project? Thank you!

like image 952
linello Avatar asked Jun 16 '14 07:06

linello


People also ask

How does CMake know which compiler to use?

CMake needs a way to determine which compiler to use to invoke the linker. This is determined by the LANGUAGE property of source files of the target , and in the case of static libraries, the LANGUAGE of the dependent libraries. The choice CMake makes may be overridden with the LINKER_LANGUAGE target property.

Does CMake need compiler?

At a minimum, using CMake requires a C compiler, that compiler's native build tools, and a CMake executable. CMake was written in C++, requires only a C++ compiler to build, and precompiled binaries are available for most systems.

Which C++ compiler does CMake use?

Usually under Linux, one uses CMake to generate a GNU make file which then uses gcc or g++ to compile the source file and to create the executable. A CMake project is composed of source files and of one or several CMakeLists.


2 Answers

You can use set_source_files_properties to add COMPILE_FLAGS for myprogram.cpp. For example:

add_executable(MyProgram myprogram.cpp)

# Add the -std=c++11 flag as an example
set_source_files_properties( myprogram.cpp PROPERTIES COMPILE_FLAGS "-std=c++11" )
target_link_libraries(MyProgram MyLibraries)

If you need those flags for all source files in the MyProgram target, you could use set_target_properties with the target property COMPILE_FLAGS:

add_executable(MyProgram myprogram.cpp)
# Add the -std=c++11 flag as an example
target_link_libraries(MyProgram MyLibraries)
set_target_properties( MyProgram PROPERTIES COMPILE_FLAGS "-std=c++11" )

Update: To remove a single property, you can first get all the properties and manually remove the offending flag from the list. For example with get_source_file_property:

get_source_file_property( MYPROPS myprogram.cpp COMPILE_FLAGS )
STRING( REPLACE "/MP1" "" MYPROPS ${MYPROPS} )
set_source_files_properties( myprogram.cpp COMPILE_FLAGS ${MYPROPS} )

However, I would recommend splitting your source files in two. One with all the source files with the \MP flag and another with only myprogram.cpp

like image 151
André Avatar answered Sep 28 '22 03:09

André


New approach

# Simply add the opposite flag to the target
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")                                                                             
    target_compile_options(${TARGET_NAME} PRIVATE "/GR")                               
else()                                                                                                                                        
    target_compile_options(${TARGET_NAME} PRIVATE "-frtti") # works even if -fno-rtti is set to CXX_FLAGS
endif()                                                                                

Old approach:

You can disable it by removing the flag from the default compiler flags first, than set it to your target. In my case I wanted to remove enable RTTI because it was disabled by default:

function(enable_RTTI target_name)
    if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
        set(NO_RTTI "/GR-")
        set(WITH_RTTI "/GR")
    else()
        set(NO_RTTI "-fno-rtti")
    endif()

    string(REPLACE "${NO_RTTI}" "${WITH_RTTI}" COMPILE_FLAGS_RTTI_ENABLED "${CMAKE_CXX_FLAGS}")

    set_target_properties(${target_name} PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS_RTTI_ENABLED}")
endfunction()

    ...

# Do this on your specific target
enable_RTTI(${TARGET_NAME}

This works like a charm with CMake 3!

like image 33
DrumM Avatar answered Sep 28 '22 03:09

DrumM