Hao Shi Hao Shi - 2 months ago 10
C++ Question

duplicate compile flag in CMAKE_CXX_FLAGS

I am trying to use cmake to link my project.

I need to find a package

mypack
, it will give me
mypack_definitions
,
mypack_flags
,
mypack_include_dirs
, and
mypack_libraries
. Here
mypack_flags
contains relevant flags for linking mypack. I will add
mypack_flags
to
CMAKE_CXX_FLAGS
.

Please see the CMakeLists.txt below:

cmake_minimum_required(VERSION 2.8)
project(QMCLIB C CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fopenmp")

find_package(mypack REQUIRED)

add_executable(QMC codeA.cpp codeB.cpp )
add_definitions(${mypack_definitions})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${mypack_flags}")
target_link_libraries(QMC ${mypack_libraries})
target_include_directories(QMC PUBLIC ${mypack_include_dirs})


However depend on the systems,
mypack_flags
might or not contain
-fopenmp
, when it contains
-fopenmp
, my
CMAKE_CXX_FLAGS
will have two
-fopenmp
. I can not remove
-fopenmp
in

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fopenmp")


If I remove it, when
mypack_flags
does not contains
-fopenmp
, then I will have no
-fopenmp
in CMAKE_CXX_FLAGS.

Is there a way to force cmake only use one
-fopenmp
? Or is it okay to have two
-fopenmp
? Thank you for your suggestion.

======================================================================

Thanks to Robert Prévost, here is a general function to remove duplicate substrings:

function(removeDuplicateSubstring stringIn stringOut)
separate_arguments(stringIn)
list(REMOVE_DUPLICATES stringIn)
string(REPLACE ";" " " stringIn "${stringIn}")
set(${stringOut} "${stringIn}" PARENT_SCOPE)
endfunction()


We can call this function by:

removeDuplicateSubstring(${CMAKE_CXX_FLAGS} CMAKE_CXX_FLAGS)

Answer

Beyond the list(REMOVE_DUPLICATES <list>) solution, I would advice to avoid using CMAKE_CXX_FLAGS nor add_* commands, and prefer target_* commands instead:

Your cmake file may become something like that:

cmake_minimum_required(VERSION 2.8)
project(QMCLIB C CXX)

function(removeDuplicateSubstring stringIn stringOut)
    separate_arguments(stringIn)
    list(REMOVE_DUPLICATES stringIn)
    string(REPLACE ";" " " stringIn "${stringIn}")
    set(${stringOut} "${stringIn}" PARENT_SCOPE)
endfunction()

find_package(mypack REQUIRED)

set(mycompile_options -fopenmp ${mypack_flags})

removeDuplicateSubstring(${mycompile_options} mycompile_options)

add_executable(QMC codeA.cpp codeB.cpp )
target_compile_definitions(QMC PUBLIC ${mypack_definitions})
target_compile_options(QMC PUBLIC ${mycompile_options})
target_compile_features(QMC PUBLIC cxx_constexpr)
target_include_directories(QMC PUBLIC ${mypack_include_dirs})
target_link_libraries(QMC ${mypack_libraries})
Comments