# include guard include_guard(DIRECTORY) # ######################################################################################## # # Compilers # # ######################################################################################## # # sets (cached): # # CMAKE_C_COMPILER_IS_ CMAKE_CXX_COMPILER_IS_ # # where TYPE is: - GNU - CLANG - INTEL - INTEL_ICC - INTEL_ICPC - PGI - XLC - HP_ACC - # MIPS - MSVC # include(CheckCCompilerFlag) include(CheckCSourceCompiles) include(CheckCSourceRuns) include(CheckCXXCompilerFlag) include(CheckCXXSourceCompiles) include(CheckCXXSourceRuns) include(CMakeParseArguments) include(MacroUtilities) if("${LIBNAME}" STREQUAL "") string(TOLOWER "${PROJECT_NAME}" LIBNAME) endif() add_interface_library(${LIBNAME}-compile-options "Adds the standard set of compiler flags used by timemory") # ----------------------------------------------------------------------------------------# # macro converting string to list # ----------------------------------------------------------------------------------------# macro(to_list _VAR _STR) string(REPLACE " " " " ${_VAR} "${_STR}") string(REPLACE " " ";" ${_VAR} "${_STR}") endmacro( to_list _VAR _STR) # ----------------------------------------------------------------------------------------# # macro converting string to list # ----------------------------------------------------------------------------------------# macro(to_string _VAR _STR) string(REPLACE ";" " " ${_VAR} "${_STR}") endmacro( to_string _VAR _STR) # ----------------------------------------------------------------------------------------# # Macro to add to string # ----------------------------------------------------------------------------------------# macro(add _VAR _FLAG) if(NOT "${_FLAG}" STREQUAL "") if("${${_VAR}}" STREQUAL "") set(${_VAR} "${_FLAG}") else() set(${_VAR} "${${_VAR}} ${_FLAG}") endif() endif() endmacro() # ----------------------------------------------------------------------------------------# # macro to remove duplicates from string # ----------------------------------------------------------------------------------------# macro(set_no_duplicates _VAR) if(NOT "${ARGN}" STREQUAL "") set(${_VAR} "${ARGN}") endif() # remove the duplicates if(NOT "${${_VAR}}" STREQUAL "") # create list of flags to_list(_VAR_LIST "${${_VAR}}") list(REMOVE_DUPLICATES _VAR_LIST) to_string(${_VAR} "${_VAR_LIST}") endif(NOT "${${_VAR}}" STREQUAL "") endmacro(set_no_duplicates _VAR) # ----------------------------------------------------------------------------------------# # call before running check_{c,cxx}_compiler_flag # ----------------------------------------------------------------------------------------# macro(timemory_begin_flag_check) if(TIMEMORY_QUIET_CONFIG) if(NOT DEFINED CMAKE_REQUIRED_QUIET) set(CMAKE_REQUIRED_QUIET OFF) endif() timemory_save_variables(FLAG_CHECK VARIABLES CMAKE_REQUIRED_QUIET) set(CMAKE_REQUIRED_QUIET ON) endif() endmacro() # ----------------------------------------------------------------------------------------# # call after running check_{c,cxx}_compiler_flag # ----------------------------------------------------------------------------------------# macro(timemory_end_flag_check) if(TIMEMORY_QUIET_CONFIG) timemory_restore_variables(FLAG_CHECK VARIABLES CMAKE_REQUIRED_QUIET) endif() endmacro() # ######################################################################################## # # C compiler flags # # ######################################################################################## # ----------------------------------------------------------------------------------------# # add C flag to target # ----------------------------------------------------------------------------------------# macro(ADD_TARGET_C_FLAG _TARG) string(REPLACE "-" "_" _MAKE_TARG "${_TARG}") list(APPEND TIMEMORY_MAKE_TARGETS ${_MAKE_TARG}) target_compile_options(${_TARG} INTERFACE $<$:${ARGN}>) list(APPEND ${_MAKE_TARG}_C_FLAGS ${ARGN}) endmacro() # ----------------------------------------------------------------------------------------# # add C flag w/o check # ----------------------------------------------------------------------------------------# macro(ADD_C_FLAG FLAG) set(_TARG) set(_LTARG) if(NOT "${ARGN}" STREQUAL "") set(_TARG ${ARGN}) string(TOLOWER "_${ARGN}" _LTARG) endif() if(NOT "${FLAG}" STREQUAL "") if("${_LTARG}" STREQUAL "") list(APPEND ${PROJECT_NAME}_C_FLAGS "${FLAG}") list(APPEND ${PROJECT_NAME}_C_COMPILE_OPTIONS "${FLAG}") add_target_c_flag(${LIBNAME}-compile-options ${FLAG}) else() add_target_c_flag(${_TARG} ${FLAG}) endif() endif() unset(_TARG) unset(_LTARG) endmacro() # ----------------------------------------------------------------------------------------# # check C flag # ----------------------------------------------------------------------------------------# macro(ADD_C_FLAG_IF_AVAIL FLAG) set(_ENABLE ON) if(DEFINED TIMEMORY_BUILD_C AND NOT TIMEMORY_BUILD_C) set(_ENABLE OFF) endif() set(_TARG) set(_LTARG) if(NOT "${ARGN}" STREQUAL "") set(_TARG ${ARGN}) string(TOLOWER "_${ARGN}" _LTARG) endif() if(NOT "${FLAG}" STREQUAL "") string(REGEX REPLACE "^/" "c${_LTARG}_" FLAG_NAME "${FLAG}") string(REGEX REPLACE "^-" "c${_LTARG}_" FLAG_NAME "${FLAG_NAME}") string(REPLACE "-" "_" FLAG_NAME "${FLAG_NAME}") string(REPLACE " " "_" FLAG_NAME "${FLAG_NAME}") string(REPLACE "=" "_" FLAG_NAME "${FLAG_NAME}") if(NOT TIMEMORY_BUILD_C) set(${FLAG_NAME} ON) else() timemory_begin_flag_check() check_c_compiler_flag("-Werror" c_werror) if(c_werror) check_c_compiler_flag("${FLAG} -Werror" ${FLAG_NAME}) else() check_c_compiler_flag("${FLAG}" ${FLAG_NAME}) endif() timemory_end_flag_check() if(${FLAG_NAME}) if("${_LTARG}" STREQUAL "") list(APPEND ${PROJECT_NAME}_C_FLAGS "${FLAG}") list(APPEND ${PROJECT_NAME}_C_COMPILE_OPTIONS "${FLAG}") add_target_c_flag(${LIBNAME}-compile-options ${FLAG}) else() add_target_c_flag(${_TARG} ${FLAG}) endif() endif() endif() endif() unset(_TARG) unset(_LTARG) endmacro() # ----------------------------------------------------------------------------------------# # add C flag to target # ----------------------------------------------------------------------------------------# macro(ADD_TARGET_C_FLAG_IF_AVAIL _TARG) foreach(_FLAG ${ARGN}) add_c_flag_if_avail(${_FLAG} ${_TARG}) endforeach() endmacro() # ######################################################################################## # # CXX compiler flags # # ######################################################################################## # ----------------------------------------------------------------------------------------# # add CXX flag to target # ----------------------------------------------------------------------------------------# macro(ADD_TARGET_CXX_FLAG _TARG) string(REPLACE "-" "_" _MAKE_TARG "${_TARG}") list(APPEND TIMEMORY_MAKE_TARGETS ${_MAKE_TARG}) target_compile_options(${_TARG} INTERFACE $<$:${ARGN}>) list(APPEND ${_MAKE_TARG}_CXX_FLAGS ${ARGN}) get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) if(CMAKE_CUDA_COMPILER_IS_NVIDIA) target_compile_options(${_TARG} INTERFACE $<$:-Xcompiler=${ARGN}>) list(APPEND ${_MAKE_TARG}_CUDA_FLAGS -Xcompiler=${ARGN}) elseif(CMAKE_CUDA_COMPILER_IS_CLANG) target_compile_options(${_TARG} INTERFACE $<$:${ARGN}>) list(APPEND ${_MAKE_TARG}_CUDA_FLAGS ${ARGN}) endif() endmacro() # ----------------------------------------------------------------------------------------# # add CXX flag w/o check # ----------------------------------------------------------------------------------------# macro(ADD_CXX_FLAG FLAG) set(_TARG) set(_LTARG) if(NOT "${ARGN}" STREQUAL "") set(_TARG ${ARGN}) string(TOLOWER "_${ARGN}" _LTARG) endif() if(NOT "${FLAG}" STREQUAL "") if("${_LTARG}" STREQUAL "") list(APPEND ${PROJECT_NAME}_CXX_FLAGS "${FLAG}") list(APPEND ${PROJECT_NAME}_CXX_COMPILE_OPTIONS "${FLAG}") add_target_cxx_flag(${LIBNAME}-compile-options ${FLAG}) else() add_target_cxx_flag(${_TARG} ${FLAG}) endif() endif() unset(_TARG) unset(_LTARG) endmacro() # ----------------------------------------------------------------------------------------# # check CXX flag # ----------------------------------------------------------------------------------------# macro(ADD_CXX_FLAG_IF_AVAIL FLAG) set(_TARG) set(_LTARG) if(NOT "${ARGN}" STREQUAL "") set(_TARG ${ARGN}) string(TOLOWER "_${ARGN}" _LTARG) endif() if(NOT "${FLAG}" STREQUAL "") string(REGEX REPLACE "^/" "cxx${_LTARG}_" FLAG_NAME "${FLAG}") string(REGEX REPLACE "^-" "cxx${_LTARG}_" FLAG_NAME "${FLAG_NAME}") string(REPLACE "-" "_" FLAG_NAME "${FLAG_NAME}") string(REPLACE " " "_" FLAG_NAME "${FLAG_NAME}") string(REPLACE "=" "_" FLAG_NAME "${FLAG_NAME}") string(REPLACE "/" "_" FLAG_NAME "${FLAG_NAME}") timemory_begin_flag_check() check_cxx_compiler_flag("-Werror" cxx_werror) if(cxx_werror) check_cxx_compiler_flag("${FLAG} -Werror" ${FLAG_NAME}) else() check_cxx_compiler_flag("${FLAG}" ${FLAG_NAME}) endif() timemory_end_flag_check() if(${FLAG_NAME}) if("${_LTARG}" STREQUAL "") list(APPEND ${PROJECT_NAME}_CXX_FLAGS "${FLAG}") list(APPEND ${PROJECT_NAME}_CXX_COMPILE_OPTIONS "${FLAG}") add_target_cxx_flag(${LIBNAME}-compile-options ${FLAG}) else() add_target_cxx_flag(${_TARG} ${FLAG}) endif() endif() endif() unset(_TARG) unset(_LTARG) endmacro() # ----------------------------------------------------------------------------------------# # add CXX flag to target # ----------------------------------------------------------------------------------------# macro(ADD_TARGET_CXX_FLAG_IF_AVAIL _TARG) foreach(_FLAG ${ARGN}) add_cxx_flag_if_avail(${_FLAG} ${_TARG}) endforeach() endmacro() # ######################################################################################## # # Common # # ######################################################################################## # ----------------------------------------------------------------------------------------# # check C and CXX flag to compile-options w/o checking # ----------------------------------------------------------------------------------------# macro(ADD_FLAG) foreach(_ARG ${ARGN}) add_c_flag("${_ARG}") add_cxx_flag("${_ARG}") endforeach() endmacro() # ----------------------------------------------------------------------------------------# # add C and CXX flag w/o checking # ----------------------------------------------------------------------------------------# macro(ADD_TARGET_FLAG _TARG) foreach(_ARG ${ARGN}) add_target_c_flag(${_TARG} ${_ARG}) add_target_cxx_flag(${_TARG} ${_ARG}) endforeach() endmacro() # ----------------------------------------------------------------------------------------# # check C and CXX flag # ----------------------------------------------------------------------------------------# macro(ADD_FLAG_IF_AVAIL) foreach(_ARG ${ARGN}) add_c_flag_if_avail("${_ARG}") add_cxx_flag_if_avail("${_ARG}") endforeach() endmacro() # ----------------------------------------------------------------------------------------# # check C and CXX flag # ----------------------------------------------------------------------------------------# macro(ADD_TARGET_FLAG_IF_AVAIL _TARG) foreach(_ARG ${ARGN}) add_target_c_flag_if_avail(${_TARG} ${_ARG}) add_target_cxx_flag_if_avail(${_TARG} ${_ARG}) endforeach() endmacro() # ----------------------------------------------------------------------------------------# # check flag # ----------------------------------------------------------------------------------------# function(TIMEMORY_TARGET_FLAG _TARG_TARGET) cmake_parse_arguments(_TARG "IF_AVAIL" "MODE" "FLAGS;LANGUAGES" ${ARGN}) if(NOT _TARG_MODE) set(_TARG_MODE INTERFACE) endif() get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) if(NOT _TARG_LANGUAGES) get_property(_TARG_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) endif() string(TOLOWER "_${_TARG_TARGET}" _LTARG) foreach(_FLAG ${_TARG_FLAGS}) foreach(_LANG ${_TARG_LANGUAGES}) if(NOT _TARG_IF_AVAIL) target_compile_options(${_TARG_TARGET} ${_TARG_MODE} $<$:${_FLAG}>) continue() endif() if("${_LANG}" STREQUAL "C") string(REGEX REPLACE "^/" "c${_LTARG}_" FLAG_NAME "${_FLAG}") string(REGEX REPLACE "^-" "c${_LTARG}_" FLAG_NAME "${FLAG_NAME}") string(REPLACE "-" "_" FLAG_NAME "${FLAG_NAME}") string(REPLACE " " "_" FLAG_NAME "${FLAG_NAME}") string(REPLACE "=" "_" FLAG_NAME "${FLAG_NAME}") timemory_begin_flag_check() check_c_compiler_flag("-Werror" c_werror) if(c_werror) check_c_compiler_flag("${FLAG} -Werror" ${FLAG_NAME}) else() check_c_compiler_flag("${FLAG}" ${FLAG_NAME}) endif() timemory_end_flag_check() if(${FLAG_NAME}) target_compile_options(${_TARG_TARGET} ${_TARG_MODE} $<$:${_FLAG}>) endif() elseif("${_LANG}" STREQUAL "CXX") string(REGEX REPLACE "^/" "cxx${_LTARG}_" FLAG_NAME "${_FLAG}") string(REGEX REPLACE "^-" "cxx${_LTARG}_" FLAG_NAME "${FLAG_NAME}") string(REPLACE "-" "_" FLAG_NAME "${FLAG_NAME}") string(REPLACE " " "_" FLAG_NAME "${FLAG_NAME}") string(REPLACE "=" "_" FLAG_NAME "${FLAG_NAME}") timemory_begin_flag_check() check_cxx_compiler_flag("-Werror" cxx_werror) if(cxx_werror) check_cxx_compiler_flag("${FLAG} -Werror" ${FLAG_NAME}) else() check_cxx_compiler_flag("${FLAG}" ${FLAG_NAME}) endif() timemory_end_flag_check() if(${FLAG_NAME}) target_compile_options(${_TARG_TARGET} ${_TARG_MODE} $<$:${_FLAG}>) if(CMAKE_CUDA_COMPILER_IS_NVIDIA) target_compile_options( ${_TARG_TARGET} ${_TARG_MODE} $<$:-Xcompiler=${_FLAG}>) elseif(CMAKE_CUDA_COMPILER_IS_CLANG) target_compile_options(${_TARG_TARGET} ${_TARG_MODE} $<$:${_FLAG}>) endif() endif() endif() endforeach() endforeach() endfunction() # ----------------------------------------------------------------------------------------# # add CUDA flag to target # ----------------------------------------------------------------------------------------# macro(ADD_TARGET_CUDA_FLAG _TARG) string(REPLACE "-" "_" _MAKE_TARG "${_TARG}") list(APPEND TIMEMORY_MAKE_TARGETS ${_MAKE_TARG}) target_compile_options(${_TARG} INTERFACE $<$:${ARGN}>) list(APPEND ${_MAKE_TARG}_CUDA_FLAGS ${ARGN}) endmacro() # ----------------------------------------------------------------------------------------# # add to any language # ----------------------------------------------------------------------------------------# function(ADD_USER_FLAGS _TARGET _LANGUAGE) set(_FLAGS ${${_LANGUAGE}FLAGS} $ENV{${_LANGUAGE}FLAGS} ${${_LANGUAGE}_FLAGS} $ENV{${_LANGUAGE}_FLAGS}) string(REPLACE " " ";" _FLAGS "${_FLAGS}") set(${PROJECT_NAME}_${_LANGUAGE}_FLAGS ${${PROJECT_NAME}_${_LANGUAGE}_FLAGS} ${_FLAGS} PARENT_SCOPE) set(${PROJECT_NAME}_${_LANGUAGE}_COMPILE_OPTIONS ${${PROJECT_NAME}_${_LANGUAGE}_COMPILE_OPTIONS} ${_FLAGS} PARENT_SCOPE) target_compile_options(${_TARGET} INTERFACE $<$:${_FLAGS}>) endfunction() # ----------------------------------------------------------------------------------------# # add compiler definition # ----------------------------------------------------------------------------------------# function(TIMEMORY_TARGET_COMPILE_DEFINITIONS _TARG _VIS) foreach(_DEF ${ARGN}) target_compile_definitions(${_TARG} ${_VIS} $<$:${_DEF}>) if(CMAKE_CUDA_COMPILER_IS_NVIDIA) target_compile_definitions(${_TARG} ${_VIS} $<$:${_DEF}>) elseif(CMAKE_CUDA_COMPILER_IS_CLANG) target_compile_definitions(${_TARG} ${_VIS} $<$:${_DEF}>) endif() endforeach() endfunction() # ----------------------------------------------------------------------------------------# # determine compiler types for each language # ----------------------------------------------------------------------------------------# get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) foreach(LANG C CXX CUDA) if(NOT DEFINED CMAKE_${LANG}_COMPILER) set(CMAKE_${LANG}_COMPILER "") endif() if(NOT DEFINED CMAKE_${LANG}_COMPILER_ID) set(CMAKE_${LANG}_COMPILER_ID "") endif() function(SET_COMPILER_VAR VAR _BOOL) set(CMAKE_${LANG}_COMPILER_IS_${VAR} ${_BOOL} CACHE INTERNAL "CMake ${LANG} compiler identification (${VAR})" FORCE) mark_as_advanced(CMAKE_${LANG}_COMPILER_IS_${VAR}) endfunction() if(("${LANG}" STREQUAL "C" AND CMAKE_COMPILER_IS_GNUCC) OR ("${LANG}" STREQUAL "CXX" AND CMAKE_COMPILER_IS_GNUCXX)) # GNU compiler set_compiler_var(GNU 1) elseif(CMAKE_${LANG}_COMPILER MATCHES "icc.*") # Intel icc compiler set_compiler_var(INTEL 1) set_compiler_var(INTEL_ICC 1) elseif(CMAKE_${LANG}_COMPILER MATCHES "icpc.*") # Intel icpc compiler set_compiler_var(INTEL 1) set_compiler_var(INTEL_ICPC 1) elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "AppleClang") # Clang/LLVM compiler set_compiler_var(CLANG 1) set_compiler_var(APPLE_CLANG 1) elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "Clang") # Clang/LLVM compiler set_compiler_var(CLANG 1) elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "PGI") # PGI compiler set_compiler_var(PGI 1) elseif(CMAKE_${LANG}_COMPILER MATCHES "xlC" AND UNIX) # IBM xlC compiler set_compiler_var(XLC 1) elseif(CMAKE_${LANG}_COMPILER MATCHES "aCC" AND UNIX) # HP aC++ compiler set_compiler_var(HP_ACC 1) elseif( CMAKE_${LANG}_COMPILER MATCHES "CC" AND CMAKE_SYSTEM_NAME MATCHES "IRIX" AND UNIX) # IRIX MIPSpro CC Compiler set_compiler_var(MIPS 1) elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "Intel") set_compiler_var(INTEL 1) set(CTYPE ICC) if("${LANG}" STREQUAL "CXX") set(CTYPE ICPC) endif() set_compiler_var(INTEL_${CTYPE} 1) elseif(CMAKE_${LANG}_COMPILER MATCHES "MSVC") # Windows Visual Studio compiler set_compiler_var(MSVC 1) elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "NVIDIA") # NVCC set_compiler_var(NVIDIA 1) endif() # set other to no foreach( TYPE GNU INTEL INTEL_ICC INTEL_ICPC APPLE_CLANG CLANG PGI XLC HP_ACC MIPS MSVC NVIDIA) if(NOT DEFINED CMAKE_${LANG}_COMPILER_IS_${TYPE}) set_compiler_var(${TYPE} 0) endif() endforeach() endforeach()