summaryrefslogtreecommitdiff
path: root/Modules/FindOpenMP.cmake
diff options
context:
space:
mode:
authorChristian Pfeiffer <cpfeiffer@live.de>2017-04-24 20:41:33 +0200
committerBrad King <brad.king@kitware.com>2017-04-25 09:11:55 -0400
commitbb032c1bf583d2f26e0840b791fee07f8c7145d1 (patch)
tree612b266302d4fea284f56f90b1bb6c9b41b0ba6d /Modules/FindOpenMP.cmake
parentafc492d58f0af07d57256be3ac45ac70afecc256 (diff)
downloadcmake-bb032c1bf583d2f26e0840b791fee07f8c7145d1.tar.gz
FindOpenMP: Complete overhaul.
Diffstat (limited to 'Modules/FindOpenMP.cmake')
-rw-r--r--Modules/FindOpenMP.cmake535
1 files changed, 328 insertions, 207 deletions
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index f3998366aa..8c1b0182f7 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -13,112 +13,215 @@
# The variables may be empty if the compiler does not need a special
# flag to support OpenMP.
#
-# The following variables are set:
+# Variables
+# ^^^^^^^^^
#
-# ``OpenMP_C_FLAGS``
-# Flags to add to the C compiler for OpenMP support.
-# ``OpenMP_CXX_FLAGS``
-# Flags to add to the CXX compiler for OpenMP support.
-# ``OpenMP_Fortran_FLAGS``
-# Flags to add to the Fortran compiler for OpenMP support.
-# ``OPENMP_FOUND``
-# True if openmp is detected.
+# This module will set the following variables per language in your
+# project, where ``<lang>`` is one of C, CXX, or Fortran:
#
-# The following internal variables are set, if detected:
+# ``OpenMP_<lang>_FOUND``
+# Variable indicating if OpenMP support for ``<lang>`` was detected.
+# ``OpenMP_<lang>_FLAGS``
+# OpenMP compiler flags for ``<lang>``, separated by spaces.
#
-# ``OpenMP_C_SPEC_DATE``
-# Specification date of OpenMP version of C compiler.
-# ``OpenMP_CXX_SPEC_DATE``
-# Specification date of OpenMP version of CXX compiler.
-# ``OpenMP_Fortran_SPEC_DATE``
-# Specification date of OpenMP version of Fortran compiler.
+# For linking with OpenMP code written in ``<lang>``, the following
+# variables are provided:
#
-# The specification dates are formatted as integers of the form
-# ``CCYYMM`` where these represent the decimal digits of the century,
-# year, and month.
+# ``OpenMP_<lang>_LIB_NAMES``
+# :ref:`;-list <CMake Language Lists>` of libraries for OpenMP programs for ``<lang>``.
+# ``OpenMP_<libname>_LIBRARY``
+# Location of the individual libraries needed for OpenMP support in ``<lang>``.
+# ``OpenMP_<lang>_LIBRARIES``
+# A list of libraries needed to link with OpenMP code written in ``<lang>``.
+#
+# Additionally, the module provides :prop_tgt:`IMPORTED` targets:
+#
+# ``OpenMP::OpenMP_<lang>``
+# Target for using OpenMP from ``<lang>``.
+#
+# Specifically for Fortran, the module sets the following variables:
+#
+# ``OpenMP_Fortran_HAVE_OMPLIB_HEADER``
+# Boolean indicating if OpenMP is accessible through ``omp_lib.h``.
+# ``OpenMP_Fortran_HAVE_OMPLIB_MODULE``
+# Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module.
+#
+# The module will also try to provide the OpenMP version variables:
+#
+# ``OpenMP_<lang>_SPEC_DATE``
+# Date of the OpenMP specification implemented by the ``<lang>`` compiler.
+# ``OpenMP_<lang>_VERSION_MAJOR``
+# Major version of OpenMP implemented by the ``<lang>`` compiler.
+# ``OpenMP_<lang>_VERSION_MINOR``
+# Minor version of OpenMP implemented by the ``<lang>`` compiler.
+# ``OpenMP_<lang>_VERSION``
+# OpenMP version implemented by the ``<lang>`` compiler.
+#
+# The specification date is formatted as given in the OpenMP standard:
+# ``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of
+# the OpenMP specification implemented by the ``<lang>`` compiler.
+#
+# Backward Compatibility
+# ^^^^^^^^^^^^^^^^^^^^^^
+#
+# For backward compatibility with older versions of FindOpenMP, these
+# variables are set, but deprecated::
+#
+# OpenMP_FOUND
+#
+# In new projects, please use the ``OpenMP_<lang>_XXX`` equivalents.
-set(_OPENMP_REQUIRED_VARS)
-set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
-set(CMAKE_REQUIRED_QUIET ${OpenMP_FIND_QUIETLY})
+cmake_policy(PUSH)
+cmake_policy(SET CMP0057 NEW) # if IN_LIST
function(_OPENMP_FLAG_CANDIDATES LANG)
- set(OpenMP_FLAG_CANDIDATES
- #Empty, if compiler automatically accepts openmp
- " "
- #GNU
- "-fopenmp"
- #Clang
- "-fopenmp=libiomp5"
- "-fopenmp=libomp"
- #Microsoft Visual Studio
- "/openmp"
- #Intel windows
- "-Qopenmp"
- #PathScale, Intel
- "-openmp"
- #Sun
- "-xopenmp"
- #HP
- "+Oopenmp"
- #IBM XL C/c++
- "-qsmp"
- #Portland Group, MIPSpro
- "-mp"
- )
+ if(NOT OpenMP_${LANG}_FLAG)
+ set(OpenMP_FLAG_CANDIDATES "")
+
+ set(OMP_FLAG_GNU "-fopenmp")
+ set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5")
+ set(OMP_FLAG_HP "+Oopenmp")
+ if(WIN32)
+ set(OMP_FLAG_Intel "-Qopenmp")
+ elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
+ "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
+ set(OMP_FLAG_Intel "-openmp")
+ else()
+ set(OMP_FLAG_Intel "-qopenmp")
+ 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=omp")
+ # Cray compiles with OpenMP automatically
+
+ if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
+ list(APPEND OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
+ endif()
- set(OMP_FLAG_GNU "-fopenmp")
- set(OMP_FLAG_Clang "-fopenmp=libomp")
- set(OMP_FLAG_HP "+Oopenmp")
- if(WIN32)
- set(OMP_FLAG_Intel "-Qopenmp")
- elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
- "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
- set(OMP_FLAG_Intel "-openmp")
+ list(APPEND OpenMP_FLAG_CANDIDATES " ")
+ set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
else()
- set(OMP_FLAG_Intel "-qopenmp")
- 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")
- set(OMP_FLAG_Cray " ")
-
- # 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}}")
+ set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE)
endif()
-
- set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
endfunction()
# sample openmp source code to test
-set(OpenMP_C_TEST_SOURCE
+set(OpenMP_C_CXX_TEST_SOURCE
"
#include <omp.h>
int main() {
-#ifdef _OPENMP
- return 0;
-#else
+#ifndef _OPENMP
breaks_on_purpose
#endif
}
")
-# same in Fortran
+# in Fortran, an implementation may provide an omp_lib.h header
+# or omp_lib module, or both (OpenMP standard, section 3.1)
+# Furthmore !$ is the Fortran equivalent of #ifdef _OPENMP (OpenMP standard, 2.2.2)
+# Without the conditional compilation, some compilers (e.g. PGI) might compile OpenMP code
+# while not actually enabling OpenMP, building code sequentially
set(OpenMP_Fortran_TEST_SOURCE
"
program test
- use omp_lib
- integer :: n
+ @OpenMP_Fortran_INCLUDE_LINE@
+ !$ integer :: n
n = omp_get_num_threads()
end program test
"
- )
+)
+
+function(_OPENMP_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_FILE_FULLPATH)
+ set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP)
+ if("${LANG}" STREQUAL "C")
+ set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.c")
+ file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
+ elseif("${LANG}" STREQUAL "CXX")
+ set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.cpp")
+ file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
+ elseif("${LANG}" STREQUAL "Fortran")
+ set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.f90")
+ file(WRITE "${SRC_FILE}_in" "${OpenMP_Fortran_${SRC_FILE_CONTENT_VAR}}")
+ configure_file("${SRC_FILE}_in" "${SRC_FILE}" @ONLY)
+ endif()
+ set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE)
+endfunction()
+
+include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
+
+function(_OPENMP_GET_FLAGS LANG OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
+ _OPENMP_FLAG_CANDIDATES("${LANG}")
+ _OPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenMPTryFlag _OPENMP_TEST_SRC)
+
+ foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES)
+ set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}")
+ if(CMAKE_${LANG}_VERBOSE_FLAG)
+ string(APPEND OPENMP_FLAGS_TEST " ${CMAKE_${LANG}_VERBOSE_FLAG}")
+ endif()
+ try_compile( OpenMP_TRY_COMPILE_RESULT ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
+ CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
+ OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
+ )
+
+ if(OpenMP_TRY_COMPILE_RESULT)
+ unset(OpenMP_TRY_COMPILE_RESULT CACHE)
+ set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
+
+ if(CMAKE_${LANG}_VERBOSE_FLAG)
+ unset(OpenMP_${LANG}_IMPLICIT_LIBRARIES)
+ unset(OpenMP_${LANG}_IMPLICIT_LINK_DIRS)
+ unset(OpenMP_${LANG}_IMPLICIT_FWK_DIRS)
+ unset(OpenMP_${LANG}_LOG_VAR)
+
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
+
+ cmake_parse_implicit_link_info("${OpenMP_TRY_COMPILE_OUTPUT}"
+ OpenMP_${LANG}_IMPLICIT_LIBRARIES
+ OpenMP_${LANG}_IMPLICIT_LINK_DIRS
+ OpenMP_${LANG}_IMPLICIT_FWK_DIRS
+ OpenMP_${LANG}_LOG_VAR
+ "${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}"
+ )
+
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n")
+
+ unset(_OPENMP_LIB_NAMES)
+ foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES)
+ if(NOT "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES)
+ find_library(OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY
+ NAMES "${_OPENMP_IMPLICIT_LIB}"
+ HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS}
+ )
+ mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY)
+ list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB})
+ endif()
+ endforeach()
+ set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
+ else()
+ # The Intel compiler on windows has no verbose mode, so we need to treat it explicitly
+ if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Intel" AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
+ set("${OPENMP_LIB_NAMES_VAR}" "libiomp5md" PARENT_SCOPE)
+ find_library(OpenMP_libiomp5md_LIBRARY
+ NAMES "libiomp5md"
+ HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
+ )
+ mark_as_advanced(OpenMP_libiomp5md_LIBRARY)
+ else()
+ set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
+ endif()
+ endif()
+ break()
+ endif()
+ set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE)
+ set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE)
+ unset(OpenMP_TRY_COMPILE_RESULT CACHE)
+ endforeach()
+endfunction()
set(OpenMP_C_CXX_CHECK_VERSION_SOURCE
"
@@ -133,17 +236,16 @@ const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M',
('0' + ((_OPENMP/10)%10)),
('0' + ((_OPENMP/1)%10)),
']', '\\0' };
-int main(int argc, char *argv[])
+int main()
{
- printf(\"%s\\n\", ompver_str);
- return 0;
+ puts(ompver_str);
}
")
set(OpenMP_Fortran_CHECK_VERSION_SOURCE
"
program omp_ver
- use omp_lib
+ @OpenMP_Fortran_INCLUDE_LINE@
integer, parameter :: zero = ichar('0')
integer, parameter :: ompv = openmp_version
character, dimension(24), parameter :: ompver_str =&
@@ -160,20 +262,10 @@ set(OpenMP_Fortran_CHECK_VERSION_SOURCE
")
function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
- set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP)
- if("${LANG}" STREQUAL "C")
- set(SRC_FILE ${WORK_DIR}/ompver.c)
- file(WRITE ${SRC_FILE} "${OpenMP_C_CXX_CHECK_VERSION_SOURCE}")
- elseif("${LANG}" STREQUAL "CXX")
- set(SRC_FILE ${WORK_DIR}/ompver.cpp)
- file(WRITE ${SRC_FILE} "${OpenMP_C_CXX_CHECK_VERSION_SOURCE}")
- else() # ("${LANG}" STREQUAL "Fortran")
- set(SRC_FILE ${WORK_DIR}/ompver.f90)
- file(WRITE ${SRC_FILE} "${OpenMP_Fortran_CHECK_VERSION_SOURCE}")
- endif()
+ _OPENMP_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC)
- set(BIN_FILE ${WORK_DIR}/ompver_${LANG}.bin)
- try_compile(OpenMP_TRY_COMPILE_RESULT ${CMAKE_BINARY_DIR} ${SRC_FILE}
+ set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin")
+ try_compile(OpenMP_TRY_COMPILE_RESULT "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}"
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}"
COPY_FILE ${BIN_FILE})
@@ -188,144 +280,173 @@ function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
unset(OpenMP_TRY_COMPILE_RESULT CACHE)
endfunction()
+macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG)
+ set(OpenMP_SPEC_DATE_MAP
+ # Combined versions, 2.5 onwards
+ "201511=4.5"
+ "201307=4.0"
+ "201107=3.1"
+ "200805=3.0"
+ "200505=2.5"
+ # C/C++ version 2.0
+ "200203=2.0"
+ # Fortran version 2.0
+ "200011=2.0"
+ # Fortran version 1.1
+ "199911=1.1"
+ # C/C++ version 1.0 (there's no 1.1 for C/C++)
+ "199810=1.0"
+ # Fortran version 1.0
+ "199710=1.0"
+ )
-# check c compiler
-if(CMAKE_C_COMPILER_LOADED)
- # 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)
+ string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}")
+ if(NOT _version_match STREQUAL "")
+ set(OpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1})
+ set(OpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2})
+ set(OpenMP_${LANG}_VERSION "${OpenMP_${LANG}_VERSION_MAJOR}.${OpenMP_${LANG}_VERSION_MINOR}")
else()
- _OPENMP_FLAG_CANDIDATES("C")
- include(${CMAKE_CURRENT_LIST_DIR}/CheckCSourceCompiles.cmake)
+ unset(OpenMP_${LANG}_VERSION_MAJOR)
+ unset(OpenMP_${LANG}_VERSION_MINOR)
+ unset(OpenMP_${LANG}_VERSION)
endif()
-
- foreach(FLAG IN LISTS OpenMP_C_FLAG_CANDIDATES)
- set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
- set(CMAKE_REQUIRED_FLAGS "${FLAG}")
- unset(OpenMP_FLAG_DETECTED CACHE)
- if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Try OpenMP C flag = [${FLAG}]")
- endif()
- 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()
+ unset(_version_match)
+ unset(OpenMP_SPEC_DATE_MAP)
+endmacro()
+
+foreach(LANG IN ITEMS C CXX)
+ if(CMAKE_${LANG}_COMPILER_LOADED)
+ if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
+ OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
+ _OPENMP_GET_FLAGS("${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK)
endif()
- endforeach()
-
- 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)
-
- if (NOT OpenMP_C_SPEC_DATE)
- _OPENMP_GET_SPEC_DATE("C" OpenMP_C_SPEC_DATE_INTERNAL)
- set(OpenMP_C_SPEC_DATE "${OpenMP_C_SPEC_DATE_INTERNAL}" CACHE
- INTERNAL "C compiler's OpenMP specification date")
+ set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
+ CACHE STRING "${LANG} compiler flags for OpenMP parallelization")
+ set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
+ CACHE STRING "${LANG} compiler libraries for OpenMP parallelization")
+ mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
endif()
-endif()
+endforeach()
-# check cxx compiler
-if(CMAKE_CXX_COMPILER_LOADED)
- # 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(${CMAKE_CURRENT_LIST_DIR}/CheckCXXSourceCompiles.cmake)
+if(CMAKE_Fortran_COMPILER_LOADED)
+ if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
+ OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
+ OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
+ set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
+ _OPENMP_GET_FLAGS("Fortran" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
+ if(OpenMP_Fortran_FLAGS_WORK)
+ set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "")
+ endif()
- # use the same source for CXX as C for now
- set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE})
+ set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
+ CACHE STRING "Fortran compiler flags for OpenMP parallelization")
+ set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
+ CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
+ mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES)
endif()
- foreach(FLAG IN LISTS OpenMP_CXX_FLAG_CANDIDATES)
- set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
- set(CMAKE_REQUIRED_FLAGS "${FLAG}")
- unset(OpenMP_FLAG_DETECTED CACHE)
- if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Try OpenMP CXX flag = [${FLAG}]")
- endif()
- 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()
+ if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
+ OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
+ OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
+ set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
+ _OPENMP_GET_FLAGS("Fortran" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
+ if(OpenMP_Fortran_FLAGS_WORK)
+ set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "")
endif()
- endforeach()
- set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS_INTERNAL}"
- CACHE STRING "C++ compiler flags for OpenMP parallization")
+ set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
+ CACHE STRING "Fortran compiler flags for OpenMP parallelization")
- list(APPEND _OPENMP_REQUIRED_VARS OpenMP_CXX_FLAGS)
- unset(OpenMP_CXX_FLAG_CANDIDATES)
-
- if (NOT OpenMP_CXX_SPEC_DATE)
- _OPENMP_GET_SPEC_DATE("CXX" OpenMP_CXX_SPEC_DATE_INTERNAL)
- set(OpenMP_CXX_SPEC_DATE "${OpenMP_CXX_SPEC_DATE_INTERNAL}" CACHE
- INTERNAL "C++ compiler's OpenMP specification date")
+ set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES}"
+ CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
endif()
-endif()
-# check Fortran compiler
-if(CMAKE_Fortran_COMPILER_LOADED)
- # if these are set then do not try to find them again,
- # by avoiding any try_compiles for the flags
- if(OpenMP_Fortran_FLAGS)
- unset(OpenMP_Fortran_FLAG_CANDIDATES)
+ if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
+ set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
else()
- _OPENMP_FLAG_CANDIDATES("Fortran")
- include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranSourceCompiles.cmake)
+ set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
endif()
+endif()
- foreach(FLAG IN LISTS OpenMP_Fortran_FLAG_CANDIDATES)
- set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
- set(CMAKE_REQUIRED_FLAGS "${FLAG}")
- unset(OpenMP_FLAG_DETECTED CACHE)
- if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Try OpenMP Fortran flag = [${FLAG}]")
- endif()
- check_fortran_source_compiles("${OpenMP_Fortran_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
- set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
- if(OpenMP_FLAG_DETECTED)
- set(OpenMP_Fortran_FLAGS_INTERNAL "${FLAG}")
- break()
- endif()
- endforeach()
+set(OPENMP_FOUND TRUE)
- set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_INTERNAL}"
- CACHE STRING "Fortran compiler flags for OpenMP parallization")
+foreach(LANG IN ITEMS C CXX Fortran)
+ if(CMAKE_${LANG}_COMPILER_LOADED)
+ if (NOT OpenMP_${LANG}_SPEC_DATE)
+ _OPENMP_GET_SPEC_DATE("${LANG}" OpenMP_${LANG}_SPEC_DATE_INTERNAL)
+ set(OpenMP_${LANG}_SPEC_DATE "${OpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE
+ INTERNAL "${LANG} compiler's OpenMP specification date")
+ _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}")
+ endif()
- list(APPEND _OPENMP_REQUIRED_VARS OpenMP_Fortran_FLAGS)
- unset(OpenMP_Fortran_FLAG_CANDIDATES)
+ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
- if (NOT OpenMP_Fortran_SPEC_DATE)
- _OPENMP_GET_SPEC_DATE("Fortran" OpenMP_Fortran_SPEC_DATE_INTERNAL)
- set(OpenMP_Fortran_SPEC_DATE "${OpenMP_Fortran_SPEC_DATE_INTERNAL}" CACHE
- INTERNAL "Fortran compiler's OpenMP specification date")
- endif()
-endif()
+ set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMP_FIND_QUIETLY})
+ set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMP_FIND_REQUIRED})
+ set(OpenMP_${LANG}_FIND_VERSION ${OpenMP_FIND_VERSION})
+ set(OpenMP_${LANG}_FIND_VERSION_EXACT ${OpenMP_FIND_VERSION_EXACT})
-set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
-
-if(_OPENMP_REQUIRED_VARS)
- include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+ set(_OPENMP_${LANG}_REQUIRED_VARS OpenMP_${LANG}_FLAGS)
+ if("${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
+ set(_OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${LANG}_LIB_NAMES)
+ else()
+ foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
+ list(APPEND _OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY)
+ endforeach()
+ endif()
- find_package_handle_standard_args(OpenMP
- REQUIRED_VARS ${_OPENMP_REQUIRED_VARS})
+ find_package_handle_standard_args(OpenMP_${LANG}
+ REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
+ VERSION_VAR OpenMP_${LANG}_VERSION
+ )
+
+ if(OpenMP_${LANG}_FOUND)
+ set(OpenMP_${LANG}_LIBRARIES "")
+ foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
+ list(APPEND OpenMP_${LANG}_LIBRARIES "${OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY}")
+ endforeach()
+
+ if(NOT TARGET OpenMP::OpenMP_${LANG})
+ add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED)
+ endif()
+ if(OpenMP_${LANG}_FLAGS)
+ if(CMAKE_HOST_WIN32)
+ separate_arguments(_OpenMP_${LANG}_OPTIONS WINDOWS_COMMAND "${OpenMP_${LANG}_FLAGS}")
+ else()
+ separate_arguments(_OpenMP_${LANG}_OPTIONS UNIX_COMMAND "${OpenMP_${LANG}_FLAGS}")
+ endif()
+ set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
+ INTERFACE_COMPILE_OPTIONS "${_OpenMP_${LANG}_OPTIONS}")
+ unset(_OpenMP_${LANG}_OPTIONS)
+ endif()
+ if(OpenMP_${LANG}_LIBRARIES)
+ set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
+ INTERFACE_LINK_LIBRARIES "${OpenMP_${LANG}_LIBRARIES}")
+ endif()
+ else()
+ set(OPENMP_FOUND FALSE)
+ endif()
+ endif()
+endforeach()
- mark_as_advanced(${_OPENMP_REQUIRED_VARS})
+if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND)
+ if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
+ set(OpenMP_Fortran_HAVE_OMPLIB_MODULE FALSE CACHE BOOL INTERNAL "")
+ endif()
+ if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
+ set(OpenMP_Fortran_HAVE_OMPLIB_HEADER FALSE CACHE BOOL INTERNAL "")
+ endif()
+endif()
- unset(_OPENMP_REQUIRED_VARS)
-else()
- message(SEND_ERROR "FindOpenMP requires C or CXX language to be enabled")
+if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
+ message(SEND_ERROR "FindOpenMP requires the C, CXX or Fortran languages to be enabled")
endif()
-unset(OpenMP_C_TEST_SOURCE)
-unset(OpenMP_CXX_TEST_SOURCE)
+unset(OpenMP_C_CXX_TEST_SOURCE)
unset(OpenMP_Fortran_TEST_SOURCE)
unset(OpenMP_C_CXX_CHECK_VERSION_SOURCE)
unset(OpenMP_Fortran_CHECK_VERSION_SOURCE)
+unset(OpenMP_Fortran_INCLUDE_LINE)
+
+cmake_policy(POP)