Changeset View
Changeset View
Standalone View
Standalone View
cmake/modules/AddCompilerFlags.cmake
Show All 10 Lines | function(check_compiler_flag RESULT LANGUAGE FLAG) | ||||
elseif("${LANGUAGE}" STREQUAL "CXX") | elseif("${LANGUAGE}" STREQUAL "CXX") | ||||
CHECK_CXX_COMPILER_FLAG(${FLAG} ${TEST_NAME}) | CHECK_CXX_COMPILER_FLAG(${FLAG} ${TEST_NAME}) | ||||
else() | else() | ||||
message(FATAL_ERROR "check_compiler_flag LANGUAGE should be C or CXX") | message(FATAL_ERROR "check_compiler_flag LANGUAGE should be C or CXX") | ||||
endif() | endif() | ||||
set(${RESULT} ${${TEST_NAME}} PARENT_SCOPE) | set(${RESULT} ${${TEST_NAME}} PARENT_SCOPE) | ||||
endfunction() | endfunction() | ||||
function(add_c_compiler_flags) | function(add_compiler_flags_to_var TARGET LANGUAGE) | ||||
foreach(f ${ARGN}) | foreach(f ${ARGN}) | ||||
check_compiler_flag(FLAG_IS_SUPPORTED C ${f}) | check_compiler_flag(FLAG_IS_SUPPORTED ${LANGUAGE} ${f}) | ||||
if(${FLAG_IS_SUPPORTED}) | if(${FLAG_IS_SUPPORTED}) | ||||
string(APPEND CMAKE_C_FLAGS " ${f}") | string(APPEND ${TARGET} " ${f}") | ||||
endif() | endif() | ||||
endforeach() | endforeach() | ||||
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} PARENT_SCOPE) | set(${TARGET} ${${TARGET}} PARENT_SCOPE) | ||||
endfunction() | endfunction() | ||||
function(add_cxx_compiler_flags) | macro(add_c_compiler_flags) | ||||
foreach(f ${ARGN}) | add_compiler_flags_to_var(CMAKE_C_FLAGS C ${ARGN}) | ||||
check_compiler_flag(FLAG_IS_SUPPORTED CXX ${f}) | endmacro() | ||||
if(${FLAG_IS_SUPPORTED}) | |||||
string(APPEND CMAKE_CXX_FLAGS " ${f}") | macro(add_cxx_compiler_flags) | ||||
endif() | add_compiler_flags_to_var(CMAKE_CXX_FLAGS CXX ${ARGN}) | ||||
endforeach() | endmacro() | ||||
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} PARENT_SCOPE) | |||||
endfunction() | |||||
macro(add_compiler_flags) | macro(add_compiler_flags) | ||||
add_c_compiler_flags(${ARGN}) | add_c_compiler_flags(${ARGN}) | ||||
add_cxx_compiler_flags(${ARGN}) | add_cxx_compiler_flags(${ARGN}) | ||||
endmacro() | endmacro() | ||||
macro(remove_c_compiler_flags) | macro(remove_compiler_flags_from_var TARGET) | ||||
if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "") | |||||
string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE) | |||||
set(BUILD_TYPE_C_FLAGS "CMAKE_C_FLAGS_${BUILD_TYPE}") | |||||
endif() | |||||
foreach(f ${ARGN}) | foreach(f ${ARGN}) | ||||
string(REGEX REPLACE "${f}( |$)" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") | string(REGEX REPLACE "${f}( |$)" "" ${TARGET} "${${TARGET}}") | ||||
if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "") | |||||
string(REGEX REPLACE "${f}( |$)" "" ${BUILD_TYPE_C_FLAGS} "${${BUILD_TYPE_C_FLAGS}}") | |||||
endif() | |||||
endforeach() | endforeach() | ||||
endmacro() | endmacro() | ||||
macro(remove_cxx_compiler_flags) | function(remove_c_compiler_flags) | ||||
remove_compiler_flags_from_var(CMAKE_C_FLAGS ${ARGN}) | |||||
if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "") | if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "") | ||||
string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE) | string(TOUPPER "CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}" BUILD_TYPE_FLAGS) | ||||
set(BUILD_TYPE_CXX_FLAGS "CMAKE_CXX_FLAGS_${BUILD_TYPE}") | remove_compiler_flags_from_var(${BUILD_TYPE_FLAGS} ${ARGN}) | ||||
endif() | endif() | ||||
set(${BUILD_TYPE_FLAGS} ${${BUILD_TYPE_FLAGS}} PARENT_SCOPE) | |||||
endfunction() | |||||
foreach(f ${ARGN}) | function(remove_cxx_compiler_flags) | ||||
string(REGEX REPLACE "${f}( |$)" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") | remove_compiler_flags_from_var(CMAKE_CXX_FLAGS ${ARGN}) | ||||
if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "") | if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "") | ||||
string(REGEX REPLACE "${f}( |$)" "" ${BUILD_TYPE_CXX_FLAGS} "${${BUILD_TYPE_CXX_FLAGS}}") | string(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" BUILD_TYPE_FLAGS) | ||||
remove_compiler_flags_from_var(${BUILD_TYPE_FLAGS} ${ARGN}) | |||||
endif() | endif() | ||||
endforeach() | set(${BUILD_TYPE_FLAGS} ${${BUILD_TYPE_FLAGS}} PARENT_SCOPE) | ||||
endmacro() | endfunction() | ||||
macro(remove_compiler_flags) | macro(remove_compiler_flags) | ||||
remove_c_compiler_flags(${ARGN}) | remove_c_compiler_flags(${ARGN}) | ||||
remove_cxx_compiler_flags(${ARGN}) | remove_cxx_compiler_flags(${ARGN}) | ||||
endmacro() | endmacro() | ||||
function(add_cxx_compiler_flag_with_fallback TARGET_VAR FLAG FALLBACK) | function(add_cxx_compiler_flag_with_fallback TARGET_VAR FLAG FALLBACK) | ||||
# Remove the fallback flag if it exists, so that the main flag will override | # Remove the fallback flag if it exists, so that the main flag will override | ||||
# it if it was previously added. | # it if it was previously added. | ||||
remove_cxx_compiler_flags(${FALLBACK}) | remove_cxx_compiler_flags(${FALLBACK}) | ||||
set(FLAG_CANDIDATE ${FLAG}) | set(FLAG_CANDIDATE ${FLAG}) | ||||
check_compiler_flag(FLAG_IS_SUPPORTED CXX ${FLAG_CANDIDATE}) | check_compiler_flag(FLAG_IS_SUPPORTED CXX ${FLAG_CANDIDATE}) | ||||
if(NOT ${FLAG_IS_SUPPORTED}) | if(NOT ${FLAG_IS_SUPPORTED}) | ||||
set(FLAG_CANDIDATE ${FALLBACK}) | set(FLAG_CANDIDATE ${FALLBACK}) | ||||
check_compiler_flag(FLAG_IS_SUPPORTED CXX ${FLAG_CANDIDATE}) | |||||
endif() | endif() | ||||
if(${FLAG_IS_SUPPORTED}) | add_compiler_flags_to_var(${TARGET_VAR} CXX ${FLAG_CANDIDATE}) | ||||
string(APPEND ${TARGET_VAR} " ${FLAG_CANDIDATE}") | |||||
set(${TARGET_VAR} ${${TARGET_VAR}} PARENT_SCOPE) | set(${TARGET_VAR} ${${TARGET_VAR}} PARENT_SCOPE) | ||||
endif() | |||||
endfunction() | endfunction() | ||||
# Note that CMake does not provide any facility to check that a linker flag is | # Note that CMake does not provide any facility to check that a linker flag is | ||||
# supported by the compiler. | # supported by the compiler. | ||||
# However since CMake 3.2 introduced the CMP0056 policy, the | # However since CMake 3.2 introduced the CMP0056 policy, the | ||||
# CMAKE_EXE_LINKER_FLAGS variable is used by the try_compile function, so there | # CMAKE_EXE_LINKER_FLAGS variable is used by the try_compile function, so there | ||||
# is a workaround that allow for testing the linker flags. | # is a workaround that allow for testing the linker flags. | ||||
function(add_linker_flags) | function(add_linker_flags) | ||||
foreach(f ${ARGN}) | foreach(f ${ARGN}) | ||||
sanitize_c_cxx_definition("have_linker_" ${f} FLAG_IS_SUPPORTED) | sanitize_c_cxx_definition("have_linker_" ${f} FLAG_IS_SUPPORTED) | ||||
# Some linkers (e.g.: Clang) will issue a -Wunused-command-line-argument | # Some linkers (e.g.: Clang) will issue a -Wunused-command-line-argument | ||||
# warning when an unknown linker flag is set. | # warning when an unknown linker flag is set. | ||||
# Using -Werror will promote these warnings to errors so | # Using -Werror will promote these warnings to errors so | ||||
# CHECK_CXX_COMPILER_FLAG() will return false, preventing the flag from | # CHECK_CXX_COMPILER_FLAG() will return false, preventing the flag from | ||||
# being set. | # being set. | ||||
check_compiler_flag(WUNUSED_CLI_ARGUMENT_IS_SUPPORTED | add_compiler_flags_to_var( | ||||
CMAKE_REQUIRED_FLAGS | |||||
CXX | CXX | ||||
"-Wunused-command-line-argument" | "-Wunused-command-line-argument" | ||||
) | ) | ||||
if(${WUNUSED_CLI_ARGUMENT_IS_SUPPORTED}) | |||||
string(APPEND | |||||
CMAKE_REQUIRED_FLAGS | |||||
" -Werror=unused-command-line-argument" | |||||
) | |||||
endif() | |||||
# Save the current linker flags | # Save the current linker flags | ||||
set(SAVE_CMAKE_EXE_LINKERFLAGS ${CMAKE_EXE_LINKER_FLAGS}) | set(SAVE_CMAKE_EXE_LINKERFLAGS ${CMAKE_EXE_LINKER_FLAGS}) | ||||
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${f}") | string(APPEND CMAKE_EXE_LINKER_FLAGS " ${f}") | ||||
# CHECK_CXX_COMPILER_FLAG calls CHECK_CXX_SOURCE_COMPILES which in turn | # CHECK_CXX_COMPILER_FLAG calls CHECK_CXX_SOURCE_COMPILES which in turn | ||||
# calls try_compile, so it will check our flag | # calls try_compile, so it will check our flag | ||||
CHECK_CXX_COMPILER_FLAG("" ${FLAG_IS_SUPPORTED}) | CHECK_CXX_COMPILER_FLAG("" ${FLAG_IS_SUPPORTED}) | ||||
# Unset the -Werror=unused-command-line-argument flag if it is set. | # Unset the -Werror=unused-command-line-argument flag if it is set. | ||||
string(REGEX REPLACE | remove_compiler_flags_from_var( | ||||
" -Werror=unused-command-line-argument" | |||||
"" | |||||
CMAKE_REQUIRED_FLAGS | CMAKE_REQUIRED_FLAGS | ||||
"${CMAKE_REQUIRED_FLAGS}" | "-Wunused-command-line-argument" | ||||
) | ) | ||||
# If the flag is not supported restore CMAKE_EXE_LINKER_FLAGS | # If the flag is not supported restore CMAKE_EXE_LINKER_FLAGS | ||||
if(NOT ${FLAG_IS_SUPPORTED}) | if(NOT ${FLAG_IS_SUPPORTED}) | ||||
set(CMAKE_EXE_LINKER_FLAGS ${SAVE_CMAKE_EXE_LINKERFLAGS}) | set(CMAKE_EXE_LINKER_FLAGS ${SAVE_CMAKE_EXE_LINKERFLAGS}) | ||||
endif() | endif() | ||||
endforeach() | endforeach() | ||||
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} PARENT_SCOPE) | set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} PARENT_SCOPE) | ||||
endfunction() | endfunction() |