From 81228e9d1d94cb55fa0a75b474c5a3283b39551a Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Wed, 8 Feb 2012 18:46:57 +0100 Subject: [PATCH 1/2] FindOpenMP: do not fail if only C or CXX is enabled (#11910) Inspired-By: Raymond Wan --- Modules/FindOpenMP.cmake | 106 ++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 40 deletions(-) diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake index 652803c80..ceac8d267 100644 --- a/Modules/FindOpenMP.cmake +++ b/Modules/FindOpenMP.cmake @@ -24,9 +24,12 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -include(CheckCSourceCompiles) -include(CheckCXXSourceCompiles) -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +get_property(_ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) +list(FIND _ENABLED_LANGUAGES "C" _HAVE_LANGUAGE_C) +list(FIND _ENABLED_LANGUAGES "CXX" _HAVE_LANGUAGE_CXX) +unset(_ENABLED_LANGUAGES) + +set(_OPENMP_REQUIRED_VARS) set(OpenMP_C_FLAG_CANDIDATES #Gnu @@ -62,8 +65,6 @@ int main() { #endif } ") -# use the same source for CXX as C for now -set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE}) # if these are set then do not try to find them again, # by avoiding any try_compiles for the flags if(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) @@ -72,43 +73,68 @@ if(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) endif(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) # check c compiler -foreach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) - set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") - set(CMAKE_REQUIRED_FLAGS "${FLAG}") - unset(OpenMP_FLAG_DETECTED CACHE) - message(STATUS "Try OpenMP C flag = [${FLAG}]") - check_c_source_compiles("${OpenMP_CXX_TEST_SOURCE}" OpenMP_FLAG_DETECTED) - set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") - if(OpenMP_FLAG_DETECTED) - set(OpenMP_C_FLAGS_INTERNAL "${FLAG}") - break() - endif(OpenMP_FLAG_DETECTED) -endforeach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) +if(NOT _HAVE_LANGUAGE_C EQUAL -1) + include(CheckCSourceCompiles) + + foreach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${FLAG}") + unset(OpenMP_FLAG_DETECTED CACHE) + message(STATUS "Try OpenMP C flag = [${FLAG}]") + check_c_source_compiles("${OpenMP_C_TEST_SOURCE}" OpenMP_FLAG_DETECTED) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") + if(OpenMP_FLAG_DETECTED) + set(OpenMP_C_FLAGS_INTERNAL "${FLAG}") + break() + endif(OpenMP_FLAG_DETECTED) + endforeach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) + + set(OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}" + CACHE STRING "C compiler flags for OpenMP parallization") + + list(APPEND _OPENMP_REQUIRED_VARS OpenMP_C_FLAGS) + unset(OpenMP_C_FLAG_CANDIDATES) +endif() # check cxx compiler -foreach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) - set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") - set(CMAKE_REQUIRED_FLAGS "${FLAG}") - unset(OpenMP_FLAG_DETECTED CACHE) - message(STATUS "Try OpenMP CXX flag = [${FLAG}]") - check_cxx_source_compiles("${OpenMP_C_TEST_SOURCE}" OpenMP_FLAG_DETECTED) - set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") - if(OpenMP_FLAG_DETECTED) - set(OpenMP_CXX_FLAGS_INTERNAL "${FLAG}") - break() - endif(OpenMP_FLAG_DETECTED) -endforeach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) +if(NOT _HAVE_LANGUAGE_CXX EQUAL -1) + include(CheckCXXSourceCompiles) + # use the same source for CXX as C for now + set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE}) -set(OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}" - CACHE STRING "C compiler flags for OpenMP parallization") + foreach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${FLAG}") + unset(OpenMP_FLAG_DETECTED CACHE) + message(STATUS "Try OpenMP CXX flag = [${FLAG}]") + check_cxx_source_compiles("${OpenMP_CXX_TEST_SOURCE}" OpenMP_FLAG_DETECTED) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") + if(OpenMP_FLAG_DETECTED) + set(OpenMP_CXX_FLAGS_INTERNAL "${FLAG}") + break() + endif(OpenMP_FLAG_DETECTED) + endforeach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) -set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS_INTERNAL}" - CACHE STRING "C++ compiler flags for OpenMP parallization") -# handle the standard arguments for find_package -find_package_handle_standard_args(OpenMP DEFAULT_MSG - OpenMP_C_FLAGS OpenMP_CXX_FLAGS ) + set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS_INTERNAL}" + CACHE STRING "C++ compiler flags for OpenMP parallization") -mark_as_advanced( - OpenMP_C_FLAGS - OpenMP_CXX_FLAGS -) + list(APPEND _OPENMP_REQUIRED_VARS OpenMP_CXX_FLAGS) + unset(OpenMP_CXX_FLAG_CANDIDATES) + unset(OpenMP_CXX_TEST_SOURCE) +endif() + +unset(_HAVE_LANGUAGE_C) +unset(_HAVE_LANGUAGE_CXX) + +if(_OPENMP_REQUIRED_VARS) + include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) + + find_package_handle_standard_args(OpenMP + REQUIRED_VARS ${_OPENMP_REQUIRED_VARS}) + + mark_as_advanced(${_OPENMP_REQUIRED_VARS}) + + unset(_OPENMP_REQUIRED_VARS) +else() + message(SEND_ERROR "FindOpenMP requires C or CXX language to be enabled") +endif() From 6f573ac9ee95cb7c05c8b37c9b192f4616747214 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Wed, 8 Feb 2012 19:23:38 +0100 Subject: [PATCH 2/2] FindOpenMP: try the most likely flags first Since we know which compiler we have we can test those OpenMP flags first that are likely to be correct. This doesn't make any difference for GNU compilers, but it should avoid useless try_compiles and output cluttering for all others. --- Modules/FindOpenMP.cmake | 99 +++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 32 deletions(-) diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake index ceac8d267..e1af15e13 100644 --- a/Modules/FindOpenMP.cmake +++ b/Modules/FindOpenMP.cmake @@ -1,7 +1,7 @@ # - Finds OpenMP support # This module can be used to detect OpenMP support in a compiler. # If the compiler supports OpenMP, the flags required to compile with -# openmp support are set. +# openmp support are set. # # The following variables are set: # OpenMP_C_FLAGS - flags to add to the C compiler for OpenMP support @@ -13,6 +13,7 @@ #============================================================================= # Copyright 2009 Kitware, Inc. # Copyright 2008-2009 André Rigland Brodtkorb +# Copyright 2012 Rolf Eike Beer # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -31,27 +32,52 @@ unset(_ENABLED_LANGUAGES) set(_OPENMP_REQUIRED_VARS) -set(OpenMP_C_FLAG_CANDIDATES - #Gnu - "-fopenmp" - #Microsoft Visual Studio - "/openmp" - #Intel windows - "-Qopenmp" - #Intel - "-openmp" - #Empty, if compiler automatically accepts openmp - " " - #Sun - "-xopenmp" - #HP - "+Oopenmp" - #IBM XL C/c++ - "-qsmp" - #Portland Group - "-mp" -) -set(OpenMP_CXX_FLAG_CANDIDATES ${OpenMP_C_FLAG_CANDIDATES}) +function(_OPENMP_FLAG_CANDIDATES LANG) + set(OpenMP_FLAG_CANDIDATES + #GNU + "-fopenmp" + #Microsoft Visual Studio + "/openmp" + #Intel windows + "-Qopenmp" + #PathScale, Intel + "-openmp" + #Empty, if compiler automatically accepts openmp + " " + #Sun + "-xopenmp" + #HP + "+Oopenmp" + #IBM XL C/c++ + "-qsmp" + #Portland Group, MIPSpro + "-mp" + ) + + set(OMP_FLAG_GNU "-fopenmp") + set(OMP_FLAG_HP "+Oopenmp") + if(WIN32) + set(OMP_FLAG_Intel "-Qopenmp") + else() + set(OMP_FLAG_Intel "-openmp") + endif() + set(OMP_FLAG_MIPSpro "-mp") + set(OMP_FLAG_MSVC "/openmp") + set(OMP_FLAG_PathScale "-openmp") + set(OMP_FLAG_PGI "-mp") + set(OMP_FLAG_SunPro "-xopenmp") + set(OMP_FLAG_XL "-qsmp") + + # Move the flag that matches the compiler to the head of the list, + # this is faster and doesn't clutter the output that much. If that + # flag doesn't work we will still try all. + if(OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}) + list(REMOVE_ITEM OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}") + list(INSERT OpenMP_FLAG_CANDIDATES 0 "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}") + endif() + + set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE) +endfunction(_OPENMP_FLAG_CANDIDATES) # sample openmp source code to test set(OpenMP_C_TEST_SOURCE @@ -65,16 +91,17 @@ int main() { #endif } ") -# if these are set then do not try to find them again, -# by avoiding any try_compiles for the flags -if(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) - set(OpenMP_C_FLAG_CANDIDATES) - set(OpenMP_CXX_FLAG_CANDIDATES) -endif(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) # check c compiler if(NOT _HAVE_LANGUAGE_C EQUAL -1) - include(CheckCSourceCompiles) + # if these are set then do not try to find them again, + # by avoiding any try_compiles for the flags + if(OpenMP_C_FLAGS) + unset(OpenMP_C_FLAG_CANDIDATES) + else() + _OPENMP_FLAG_CANDIDATES("C") + include(CheckCSourceCompiles) + endif() foreach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") @@ -98,9 +125,17 @@ endif() # check cxx compiler if(NOT _HAVE_LANGUAGE_CXX EQUAL -1) - include(CheckCXXSourceCompiles) - # use the same source for CXX as C for now - set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE}) + # if these are set then do not try to find them again, + # by avoiding any try_compiles for the flags + if(OpenMP_CXX_FLAGS) + unset(OpenMP_CXX_FLAG_CANDIDATES) + else() + _OPENMP_FLAG_CANDIDATES("CXX") + include(CheckCXXSourceCompiles) + + # use the same source for CXX as C for now + set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE}) + endif() foreach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")