| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728 |
- # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- # file Copyright.txt or https://cmake.org/licensing for details.
- #[=======================================================================[.rst:
- FindOpenMP
- ----------
- Finds Open Multi-Processing (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 returned in variables for the different languages.
- The variables may be empty if the compiler does not need a special
- flag to support OpenMP.
- .. versionadded:: 3.5
- Clang support.
- Input Variables
- ^^^^^^^^^^^^^^^
- The following variables may be set to influence this module's behavior:
- ``OpenMP_RUNTIME_MSVC``
- .. versionadded:: 3.30
- Specify the `OpenMP Runtime <msvc-openmp_>`_ when compiling with MSVC.
- If set to a non-empty value, such as ``experimental`` or ``llvm``, it
- will be passed as the value of the ``-openmp:`` flag.
- .. _`msvc-openmp`: https://learn.microsoft.com/en-us/cpp/build/reference/openmp-enable-openmp-2-0-support
- Result Variables
- ^^^^^^^^^^^^^^^^
- .. versionadded:: 3.10
- The module exposes the components ``C``, ``CXX``, and ``Fortran``.
- Each of these controls the various languages to search OpenMP support for.
- .. versionadded:: 3.31
- The ``CUDA`` language component is supported when using a CUDA compiler
- that supports OpenMP on the host.
- Depending on the enabled components the following variables will be set:
- ``OpenMP_FOUND``
- Variable indicating that OpenMP flags for all requested languages have been found.
- If no components are specified, this is true if OpenMP settings for all enabled languages
- were detected.
- ``OpenMP_VERSION``
- Minimal version of the OpenMP standard detected among the requested languages,
- or all enabled languages if no components were specified.
- This module will set the following variables per language in your
- project, where ``<lang>`` is one of C, CXX, CUDA, or Fortran:
- ``OpenMP_<lang>_FOUND``
- Variable indicating if OpenMP support for ``<lang>`` was detected.
- ``OpenMP_<lang>_FLAGS``
- OpenMP compiler flags for ``<lang>``, separated by spaces.
- ``OpenMP_<lang>_INCLUDE_DIRS``
- Directories that must be added to the header search path for ``<lang>``
- when using OpenMP.
- For linking with OpenMP code written in ``<lang>``, the following
- variables are provided:
- ``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``
- .. versionadded:: 3.7
- 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.
- For some compilers, it may be necessary to add a header search path to find
- the relevant OpenMP headers. This location may be language-specific. Where
- this is needed, the module may attempt to find the location, but it can be
- provided directly by setting the ``OpenMP_<lang>_INCLUDE_DIR`` cache variable.
- Note that this variable is an _input_ control to the module. Project code
- should use the ``OpenMP_<lang>_INCLUDE_DIRS`` _output_ variable if it needs
- to know what include directories are needed.
- #]=======================================================================]
- cmake_policy(PUSH)
- cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
- function(_OPENMP_FLAG_CANDIDATES LANG)
- if(NOT OpenMP_${LANG}_FLAG)
- unset(OpenMP_FLAG_CANDIDATES)
- set(OMP_FLAG_GNU "-fopenmp")
- set(OMP_FLAG_LCC "-fopenmp")
- set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp" "-Xclang -fopenmp")
- set(OMP_FLAG_AppleClang "-Xclang -fopenmp")
- 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()
- if(CMAKE_${LANG}_COMPILER_ID STREQUAL "IntelLLVM" AND
- "x${CMAKE_${LANG}_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
- set(OMP_FLAG_IntelLLVM "-Qiopenmp")
- else()
- set(OMP_FLAG_IntelLLVM "-fiopenmp")
- endif()
- if(OpenMP_RUNTIME_MSVC)
- set(OMP_FLAG_MSVC "-openmp:${OpenMP_RUNTIME_MSVC}")
- else()
- set(OMP_FLAG_MSVC "-openmp")
- endif()
- set(OMP_FLAG_PathScale "-openmp")
- set(OMP_FLAG_NAG "-openmp")
- set(OMP_FLAG_Absoft "-openmp")
- set(OMP_FLAG_NVHPC "-mp")
- set(OMP_FLAG_PGI "-mp")
- set(OMP_FLAG_Flang "-fopenmp")
- set(OMP_FLAG_LLVMFlang "-fopenmp")
- set(OMP_FLAG_SunPro "-xopenmp")
- set(OMP_FLAG_XL "-qsmp=omp")
- # Cray compiler activate OpenMP with -h omp, which is enabled by default.
- set(OMP_FLAG_Cray " " "-h omp")
- set(OMP_FLAG_Fujitsu "-Kopenmp" "-KOMP")
- set(OMP_FLAG_FujitsuClang "-fopenmp" "-Kopenmp")
- if(CMAKE_${LANG}_COMPILER_ID STREQUAL "NVIDIA" AND CMAKE_${LANG}_HOST_COMPILER_ID)
- set(compiler_id "${CMAKE_${LANG}_HOST_COMPILER_ID}")
- else()
- set(compiler_id "${CMAKE_${LANG}_COMPILER_ID}")
- endif()
- # If we know the correct flags, use those
- if(DEFINED OMP_FLAG_${compiler_id})
- set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${compiler_id}}")
- else()
- # Fall back to reasonable default tries otherwise
- set(OpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ")
- endif()
- set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
- else()
- set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE)
- endif()
- endfunction()
- # sample openmp source code to test
- set(OpenMP_C_CXX_TEST_SOURCE
- "
- #include <omp.h>
- int main(void) {
- #ifdef _OPENMP
- omp_get_max_threads();
- #elif !defined(__CUDA_ARCH__) && !defined(__HIP_DEVICE_COMPILE__)
- # error \"_OPENMP not defined!\"
- #endif
- return 0;
- }
- ")
- # 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
- @OpenMP_Fortran_INCLUDE_LINE@
- !$ integer :: n
- n = omp_get_num_threads()
- end program test
- "
- )
- macro(_OPENMP_PREPARE_SOURCE LANG CONTENT_ID NAME_PREFIX FULLNAME_VAR CONTENT_VAR)
- if("${LANG}" STREQUAL "C")
- set(${FULLNAME_VAR} "${NAME_PREFIX}.c")
- set(${CONTENT_VAR} "${OpenMP_C_CXX_${CONTENT_ID}}")
- elseif("${LANG}" STREQUAL "CXX")
- set(${FULLNAME_VAR} "${NAME_PREFIX}.cpp")
- set(${CONTENT_VAR} "${OpenMP_C_CXX_${CONTENT_ID}}")
- elseif("${LANG}" STREQUAL "CUDA")
- set(${FULLNAME_VAR} "${NAME_PREFIX}.cu")
- set(${CONTENT_VAR} "${OpenMP_C_CXX_${CONTENT_ID}}")
- elseif("${LANG}" STREQUAL "Fortran")
- set(${FULLNAME_VAR} "${NAME_PREFIX}.F90")
- string(CONFIGURE "${OpenMP_Fortran_${CONTENT_ID}}" ${CONTENT_VAR} @ONLY)
- endif()
- endmacro()
- include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseImplicitLinkInfo.cmake)
- function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
- _OPENMP_FLAG_CANDIDATES("${LANG}")
- _OPENMP_PREPARE_SOURCE("${LANG}" TEST_SOURCE OpenMPTryFlag
- _OPENMP_TEST_SRC_NAME _OPENMP_TEST_SRC_CONTENT)
- separate_arguments(OpenMP_VERBOSE_OPTIONS NATIVE_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}")
- foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES)
- string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
- unset(_includeDirFlags)
- if(OpenMP_${LANG}_INCLUDE_DIR)
- set(_includeDirFlags "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}")
- endif()
- if(CMAKE_${LANG}_COMPILER_ID STREQUAL "NVIDIA")
- # With NVCC we drive linking directly through the host compiler, but
- # without language-wide flags since they may be specific to nvcc.
- # Pass the candidate OpenMP flag to the host compiler when linking.
- set(_OpenMP_LINK_OPTIONS "${OPENMP_FLAG}")
- # Exclude CUDA runtime libraries that we may add ourselves.
- # See the Compiler/NVIDIA module. Do not exclude pthread,
- # as that is typically a dependency of OpenMP too.
- set(_OpenMP_EXCLUDE_IMPLICIT_LIBS cudart cudart_static cudadevrt rt dl)
- else()
- set(_OpenMP_LINK_OPTIONS "")
- set(_OpenMP_EXCLUDE_IMPLICIT_LIBS "")
- endif()
- try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
- SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
- LOG_DESCRIPTION "Detecting ${LANG} OpenMP compiler info"
- CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAG}" ${_includeDirFlags}
- LINK_OPTIONS ${OpenMP_VERBOSE_OPTIONS} ${_OpenMP_LINK_OPTIONS}
- OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
- )
- if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} AND
- NOT "${CMAKE_${LANG}_COMPILER_ID};${CMAKE_${LANG}_SIMULATE_ID}" STREQUAL "Clang;MSVC")
- 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)
- 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}"
- LANGUAGE ${LANG}
- )
- # For LCC we should additionally alanyze -print-search-dirs output
- # to check for additional implicit_dirs.
- # Note: This won't work if CMP0129 policy is set to OLD!
- if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "LCC")
- execute_process(
- COMMAND ${CMAKE_${LANG}_COMPILER} -print-search-dirs
- OUTPUT_VARIABLE output_lines
- COMMAND_ERROR_IS_FATAL ANY
- ERROR_QUIET)
- if("${output_lines}" MATCHES ".*\nlibraries:[ \t]+(.*:)\n.*")
- string(REPLACE ":" ";" implicit_dirs_addon "${CMAKE_MATCH_1}")
- list(PREPEND OpenMP_${LANG}_IMPLICIT_LINK_DIRS ${implicit_dirs_addon})
- string(APPEND OpenMP_${LANG}_LOG_VAR
- " Extended OpenMP library search paths: [${implicit_dirs}]\n")
- endif()
- endif()
- message(CONFIGURE_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)
- get_filename_component(_OPENMP_IMPLICIT_LIB_DIR "${_OPENMP_IMPLICIT_LIB}" DIRECTORY)
- get_filename_component(_OPENMP_IMPLICIT_LIB_NAME "${_OPENMP_IMPLICIT_LIB}" NAME)
- get_filename_component(_OPENMP_IMPLICIT_LIB_PLAIN "${_OPENMP_IMPLICIT_LIB}" NAME_WE)
- string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PLAIN_ESC "${_OPENMP_IMPLICIT_LIB_PLAIN}")
- string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PATH_ESC "${_OPENMP_IMPLICIT_LIB}")
- if(NOT ( "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES
- OR "${_OPENMP_IMPLICIT_LIB}" IN_LIST _OpenMP_EXCLUDE_IMPLICIT_LIBS
- OR "${CMAKE_${LANG}_STANDARD_LIBRARIES}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)"
- OR "${CMAKE_${LANG}_LINK_EXECUTABLE}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" ) )
- if(_OPENMP_IMPLICIT_LIB_DIR)
- set(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY "${_OPENMP_IMPLICIT_LIB}" CACHE FILEPATH
- "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP")
- else()
- find_library(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY
- NAMES "${_OPENMP_IMPLICIT_LIB_NAME}"
- DOC "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP"
- HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS}
- CMAKE_FIND_ROOT_PATH_BOTH
- NO_PACKAGE_ROOT_PATH
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- )
- endif()
- mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY)
- list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB_PLAIN})
- endif()
- endforeach()
- list(REVERSE _OPENMP_LIB_NAMES)
- list(REMOVE_DUPLICATES _OPENMP_LIB_NAMES)
- list(REVERSE _OPENMP_LIB_NAMES)
- set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
- else()
- # We do not know how to extract implicit OpenMP libraries for this compiler.
- # Assume that it handles them automatically, e.g. the Intel Compiler on
- # Windows should put the dependency in its object files.
- set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
- endif()
- break()
- elseif((CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang"
- AND CMAKE_${LANG}_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0") OR
- (CMAKE_${LANG}_COMPILER_ID STREQUAL "Clang" AND APPLE))
- # Check for separate OpenMP library on AppleClang 7+
- find_library(OpenMP_libomp_LIBRARY
- NAMES omp gomp iomp5
- HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
- )
- mark_as_advanced(OpenMP_libomp_LIBRARY)
- if(OpenMP_libomp_LIBRARY)
- # Try without specifying include directory first. We only want to
- # explicitly add a search path if the header can't be found on the
- # default header search path already.
- try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
- SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
- LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}'"
- COMPILE_DEFINITIONS ${OPENMP_FLAG}
- LINK_LIBRARIES ${OpenMP_libomp_LIBRARY}
- )
- if(NOT OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
- find_path(OpenMP_${LANG}_INCLUDE_DIR omp.h)
- mark_as_advanced(OpenMP_${LANG}_INCLUDE_DIR)
- set(OpenMP_${LANG}_INCLUDE_DIR "${OpenMP_${LANG}_INCLUDE_DIR}" PARENT_SCOPE)
- if(OpenMP_${LANG}_INCLUDE_DIR)
- try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
- SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
- LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}' and '${OpenMP_${LANG}_INCLUDE_DIR}'"
- CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}"
- COMPILE_DEFINITIONS ${OPENMP_FLAG}
- LINK_LIBRARIES ${OpenMP_libomp_LIBRARY}
- )
- endif()
- endif()
- if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
- set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
- set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
- break()
- endif()
- endif()
- elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "LLVMFlang" AND WIN32)
- find_library(OpenMP_libomp_LIBRARY
- NAMES omp
- HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
- )
- mark_as_advanced(OpenMP_libomp_LIBRARY)
- if(OpenMP_libomp_LIBRARY)
- # Try without specifying include directory first. We only want to
- # explicitly add a search path if the header can't be found on the
- # default header search path already.
- try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
- SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
- LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}'"
- COMPILE_DEFINITIONS ${OPENMP_FLAG}
- LINK_LIBRARIES ${OpenMP_libomp_LIBRARY}
- )
- if(NOT OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
- find_path(OpenMP_${LANG}_INCLUDE_DIR omp_lib.mod)
- mark_as_advanced(OpenMP_${LANG}_INCLUDE_DIR)
- set(OpenMP_${LANG}_INCLUDE_DIR "${OpenMP_${LANG}_INCLUDE_DIR}" PARENT_SCOPE)
- if(OpenMP_${LANG}_INCLUDE_DIR)
- try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
- SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
- LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}' and '${OpenMP_${LANG}_INCLUDE_DIR}'"
- CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}"
- COMPILE_DEFINITIONS ${OPENMP_FLAG}
- LINK_LIBRARIES ${OpenMP_libomp_LIBRARY}
- )
- endif()
- endif()
- if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
- set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
- set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
- break()
- endif()
- endif()
- elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Clang" AND WIN32)
- # Check for separate OpenMP library for Clang on Windows
- find_library(OpenMP_libomp_LIBRARY
- NAMES libomp libgomp libiomp5
- HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
- )
- mark_as_advanced(OpenMP_libomp_LIBRARY)
- if(OpenMP_libomp_LIBRARY)
- try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}
- SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
- LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}'"
- COMPILE_DEFINITIONS ${OPENMP_FLAG}
- LINK_LIBRARIES ${OpenMP_libomp_LIBRARY}
- )
- if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
- set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
- set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
- break()
- endif()
- endif()
- endif()
- set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE)
- set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE)
- endforeach()
- endfunction()
- set(OpenMP_C_CXX_CHECK_VERSION_SOURCE
- "
- #include <stdio.h>
- #include <omp.h>
- const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M',
- 'P', '-', 'd', 'a', 't', 'e', '[',
- ('0' + ((_OPENMP/100000)%10)),
- ('0' + ((_OPENMP/10000)%10)),
- ('0' + ((_OPENMP/1000)%10)),
- ('0' + ((_OPENMP/100)%10)),
- ('0' + ((_OPENMP/10)%10)),
- ('0' + ((_OPENMP/1)%10)),
- ']', '\\0' };
- int main(void)
- {
- puts(ompver_str);
- return 0;
- }
- ")
- set(OpenMP_Fortran_CHECK_VERSION_SOURCE
- "
- program omp_ver
- @OpenMP_Fortran_INCLUDE_LINE@
- integer, parameter :: zero = ichar('0')
- integer, parameter :: ompv = openmp_version
- character, dimension(24), parameter :: ompver_str =&
- (/ 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-',&
- 'd', 'a', 't', 'e', '[',&
- char(zero + mod(ompv/100000, 10)),&
- char(zero + mod(ompv/10000, 10)),&
- char(zero + mod(ompv/1000, 10)),&
- char(zero + mod(ompv/100, 10)),&
- char(zero + mod(ompv/10, 10)),&
- char(zero + mod(ompv/1, 10)), ']' /)
- print *, ompver_str
- end program omp_ver
- ")
- function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
- _OPENMP_PREPARE_SOURCE("${LANG}" CHECK_VERSION_SOURCE OpenMPCheckVersion
- _OPENMP_TEST_SRC_NAME _OPENMP_TEST_SRC_CONTENT)
- unset(_includeDirFlags)
- if(OpenMP_${LANG}_INCLUDE_DIR)
- set(_includeDirFlags "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}")
- endif()
- set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin")
- string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
- try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}
- SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT
- LOG_DESCRIPTION "Detecting ${LANG} OpenMP version"
- CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}" ${_includeDirFlags}
- COPY_FILE "${BIN_FILE}"
- )
- if(${OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}})
- file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date")
- set(regex_spec_date ".*INFO:OpenMP-date\\[0*([^]]*)\\].*")
- if("${specstr}" MATCHES "${regex_spec_date}")
- set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE)
- endif()
- endif()
- endfunction()
- macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG)
- set(OpenMP_SPEC_DATE_MAP
- "202111=5.2"
- "202011=5.1"
- # Preview versions
- "201611=5.0" # OpenMP 5.0 preview 1
- # Combined versions, 2.5 onwards
- "201811=5.0"
- "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"
- )
- if(MSVC)
- list(APPEND OpenMP_SPEC_DATE_MAP "2019=2.0")
- endif()
- if(OpenMP_${LANG}_SPEC_DATE)
- string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}")
- else()
- set(_version_match "")
- endif()
- 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()
- unset(OpenMP_${LANG}_VERSION_MAJOR)
- unset(OpenMP_${LANG}_VERSION_MINOR)
- unset(OpenMP_${LANG}_VERSION)
- endif()
- unset(_version_match)
- unset(OpenMP_SPEC_DATE_MAP)
- endmacro()
- foreach(LANG IN ITEMS C CXX CUDA)
- 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}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK)
- if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND")
- set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
- CACHE STRING "${LANG} compiler flags for OpenMP parallelization" FORCE)
- endif()
- if(NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
- set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
- CACHE STRING "${LANG} compiler libraries for OpenMP parallelization" FORCE)
- endif()
- mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
- endif()
- endif()
- endforeach()
- 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" "FortranHeader" 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()
- if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND")
- set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
- CACHE STRING "Fortran compiler flags for OpenMP parallelization" FORCE)
- endif()
- if(NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND")
- set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
- CACHE STRING "Fortran compiler libraries for OpenMP parallelization" FORCE)
- endif()
- mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES)
- endif()
- 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" "FortranModule" 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()
- if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND")
- set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
- CACHE STRING "Fortran compiler flags for OpenMP parallelization" FORCE)
- endif()
- if(NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND")
- set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
- CACHE STRING "Fortran compiler libraries for OpenMP parallelization" FORCE)
- endif()
- endif()
- if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
- set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
- else()
- set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
- endif()
- endif()
- if(NOT OpenMP_FIND_COMPONENTS)
- set(OpenMP_FINDLIST C CXX CUDA Fortran)
- else()
- set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
- endif()
- unset(_OpenMP_MIN_VERSION)
- include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
- foreach(LANG IN LISTS OpenMP_FINDLIST)
- if(CMAKE_${LANG}_COMPILER_LOADED)
- if (NOT OpenMP_${LANG}_SPEC_DATE AND OpenMP_${LANG}_FLAGS)
- _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")
- endif()
- _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}")
- 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(_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_${LANG}
- NAME_MISMATCHED
- REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
- VERSION_VAR OpenMP_${LANG}_VERSION
- )
- if(OpenMP_${LANG}_FOUND)
- if(DEFINED OpenMP_${LANG}_VERSION)
- if(NOT _OpenMP_MIN_VERSION OR _OpenMP_MIN_VERSION VERSION_GREATER OpenMP_${LANG}_VERSION)
- set(_OpenMP_MIN_VERSION OpenMP_${LANG}_VERSION)
- endif()
- endif()
- 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(OpenMP_${LANG}_INCLUDE_DIR)
- set(OpenMP_${LANG}_INCLUDE_DIRS ${OpenMP_${LANG}_INCLUDE_DIR})
- else()
- set(OpenMP_${LANG}_INCLUDE_DIRS "")
- endif()
- if(NOT TARGET OpenMP::OpenMP_${LANG})
- add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED)
- endif()
- if(OpenMP_${LANG}_FLAGS)
- set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
- INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:${LANG}>:SHELL:${OpenMP_${LANG}_FLAGS}>")
- if(CMAKE_${LANG}_COMPILER_ID STREQUAL "Fujitsu"
- OR ${CMAKE_${LANG}_COMPILER_ID} STREQUAL "IntelLLVM")
- set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
- INTERFACE_LINK_OPTIONS "SHELL:${OpenMP_${LANG}_FLAGS}")
- endif()
- endif()
- if(OpenMP_${LANG}_INCLUDE_DIRS)
- set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
- INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${OpenMP_${LANG}_INCLUDE_DIRS}>")
- endif()
- if(OpenMP_${LANG}_LIBRARIES)
- set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
- INTERFACE_LINK_LIBRARIES "${OpenMP_${LANG}_LIBRARIES}")
- endif()
- endif()
- endif()
- endforeach()
- unset(_OpenMP_REQ_VARS)
- foreach(LANG IN ITEMS C CXX CUDA Fortran)
- if((NOT OpenMP_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST OpenMP_FIND_COMPONENTS)
- list(APPEND _OpenMP_REQ_VARS "OpenMP_${LANG}_FOUND")
- endif()
- endforeach()
- find_package_handle_standard_args(OpenMP
- REQUIRED_VARS ${_OpenMP_REQ_VARS}
- VERSION_VAR ${_OpenMP_MIN_VERSION}
- HANDLE_COMPONENTS)
- 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()
- if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_CUDA_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
- message(SEND_ERROR "FindOpenMP requires the C, CXX, CUDA, or Fortran languages to be enabled")
- endif()
- 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)
|