mirror of
https://github.com/reactos/CMake.git
synced 2025-01-31 17:12:49 +00:00
FindOpenMP: Complete overhaul.
This commit is contained in:
parent
afc492d58f
commit
bb032c1bf5
@ -13,112 +13,215 @@
|
|||||||
# The variables may be empty if the compiler does not need a special
|
# The variables may be empty if the compiler does not need a special
|
||||||
# flag to support OpenMP.
|
# flag to support OpenMP.
|
||||||
#
|
#
|
||||||
# The following variables are set:
|
# Variables
|
||||||
|
# ^^^^^^^^^
|
||||||
#
|
#
|
||||||
# ``OpenMP_C_FLAGS``
|
# This module will set the following variables per language in your
|
||||||
# Flags to add to the C compiler for OpenMP support.
|
# project, where ``<lang>`` is one of C, CXX, or Fortran:
|
||||||
# ``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.
|
|
||||||
#
|
#
|
||||||
# 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``
|
# For linking with OpenMP code written in ``<lang>``, the following
|
||||||
# Specification date of OpenMP version of C compiler.
|
# variables are provided:
|
||||||
# ``OpenMP_CXX_SPEC_DATE``
|
|
||||||
# Specification date of OpenMP version of CXX compiler.
|
|
||||||
# ``OpenMP_Fortran_SPEC_DATE``
|
|
||||||
# Specification date of OpenMP version of Fortran compiler.
|
|
||||||
#
|
#
|
||||||
# The specification dates are formatted as integers of the form
|
# ``OpenMP_<lang>_LIB_NAMES``
|
||||||
# ``CCYYMM`` where these represent the decimal digits of the century,
|
# :ref:`;-list <CMake Language Lists>` of libraries for OpenMP programs for ``<lang>``.
|
||||||
# year, and month.
|
# ``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)
|
cmake_policy(PUSH)
|
||||||
set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
|
cmake_policy(SET CMP0057 NEW) # if IN_LIST
|
||||||
set(CMAKE_REQUIRED_QUIET ${OpenMP_FIND_QUIETLY})
|
|
||||||
|
|
||||||
function(_OPENMP_FLAG_CANDIDATES LANG)
|
function(_OPENMP_FLAG_CANDIDATES LANG)
|
||||||
set(OpenMP_FLAG_CANDIDATES
|
if(NOT OpenMP_${LANG}_FLAG)
|
||||||
#Empty, if compiler automatically accepts openmp
|
set(OpenMP_FLAG_CANDIDATES "")
|
||||||
" "
|
|
||||||
#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"
|
|
||||||
)
|
|
||||||
|
|
||||||
set(OMP_FLAG_GNU "-fopenmp")
|
set(OMP_FLAG_GNU "-fopenmp")
|
||||||
set(OMP_FLAG_Clang "-fopenmp=libomp")
|
set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5")
|
||||||
set(OMP_FLAG_HP "+Oopenmp")
|
set(OMP_FLAG_HP "+Oopenmp")
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(OMP_FLAG_Intel "-Qopenmp")
|
set(OMP_FLAG_Intel "-Qopenmp")
|
||||||
elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
|
elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
|
||||||
"${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
|
"${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
|
||||||
set(OMP_FLAG_Intel "-openmp")
|
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()
|
||||||
|
|
||||||
|
list(APPEND OpenMP_FLAG_CANDIDATES " ")
|
||||||
|
set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
|
||||||
else()
|
else()
|
||||||
set(OMP_FLAG_Intel "-qopenmp")
|
set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE)
|
||||||
endif()
|
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}}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# sample openmp source code to test
|
# sample openmp source code to test
|
||||||
set(OpenMP_C_TEST_SOURCE
|
set(OpenMP_C_CXX_TEST_SOURCE
|
||||||
"
|
"
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
int main() {
|
int main() {
|
||||||
#ifdef _OPENMP
|
#ifndef _OPENMP
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
breaks_on_purpose
|
breaks_on_purpose
|
||||||
#endif
|
#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
|
set(OpenMP_Fortran_TEST_SOURCE
|
||||||
"
|
"
|
||||||
program test
|
program test
|
||||||
use omp_lib
|
@OpenMP_Fortran_INCLUDE_LINE@
|
||||||
integer :: n
|
!$ integer :: n
|
||||||
n = omp_get_num_threads()
|
n = omp_get_num_threads()
|
||||||
end program test
|
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
|
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/10)%10)),
|
||||||
('0' + ((_OPENMP/1)%10)),
|
('0' + ((_OPENMP/1)%10)),
|
||||||
']', '\\0' };
|
']', '\\0' };
|
||||||
int main(int argc, char *argv[])
|
int main()
|
||||||
{
|
{
|
||||||
printf(\"%s\\n\", ompver_str);
|
puts(ompver_str);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
")
|
")
|
||||||
|
|
||||||
set(OpenMP_Fortran_CHECK_VERSION_SOURCE
|
set(OpenMP_Fortran_CHECK_VERSION_SOURCE
|
||||||
"
|
"
|
||||||
program omp_ver
|
program omp_ver
|
||||||
use omp_lib
|
@OpenMP_Fortran_INCLUDE_LINE@
|
||||||
integer, parameter :: zero = ichar('0')
|
integer, parameter :: zero = ichar('0')
|
||||||
integer, parameter :: ompv = openmp_version
|
integer, parameter :: ompv = openmp_version
|
||||||
character, dimension(24), parameter :: ompver_str =&
|
character, dimension(24), parameter :: ompver_str =&
|
||||||
@ -160,20 +262,10 @@ set(OpenMP_Fortran_CHECK_VERSION_SOURCE
|
|||||||
")
|
")
|
||||||
|
|
||||||
function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
|
function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
|
||||||
set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP)
|
_OPENMP_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC)
|
||||||
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()
|
|
||||||
|
|
||||||
set(BIN_FILE ${WORK_DIR}/ompver_${LANG}.bin)
|
set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin")
|
||||||
try_compile(OpenMP_TRY_COMPILE_RESULT ${CMAKE_BINARY_DIR} ${SRC_FILE}
|
try_compile(OpenMP_TRY_COMPILE_RESULT "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}"
|
||||||
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}"
|
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}"
|
||||||
COPY_FILE ${BIN_FILE})
|
COPY_FILE ${BIN_FILE})
|
||||||
|
|
||||||
@ -188,144 +280,173 @@ function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
|
|||||||
unset(OpenMP_TRY_COMPILE_RESULT CACHE)
|
unset(OpenMP_TRY_COMPILE_RESULT CACHE)
|
||||||
endfunction()
|
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
|
string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}")
|
||||||
if(CMAKE_C_COMPILER_LOADED)
|
if(NOT _version_match STREQUAL "")
|
||||||
# if these are set then do not try to find them again,
|
set(OpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1})
|
||||||
# by avoiding any try_compiles for the flags
|
set(OpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2})
|
||||||
if(OpenMP_C_FLAGS)
|
set(OpenMP_${LANG}_VERSION "${OpenMP_${LANG}_VERSION_MAJOR}.${OpenMP_${LANG}_VERSION_MINOR}")
|
||||||
unset(OpenMP_C_FLAG_CANDIDATES)
|
|
||||||
else()
|
else()
|
||||||
_OPENMP_FLAG_CANDIDATES("C")
|
unset(OpenMP_${LANG}_VERSION_MAJOR)
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/CheckCSourceCompiles.cmake)
|
unset(OpenMP_${LANG}_VERSION_MINOR)
|
||||||
|
unset(OpenMP_${LANG}_VERSION)
|
||||||
endif()
|
endif()
|
||||||
|
unset(_version_match)
|
||||||
|
unset(OpenMP_SPEC_DATE_MAP)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
foreach(FLAG IN LISTS OpenMP_C_FLAG_CANDIDATES)
|
foreach(LANG IN ITEMS C CXX)
|
||||||
set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
|
if(CMAKE_${LANG}_COMPILER_LOADED)
|
||||||
set(CMAKE_REQUIRED_FLAGS "${FLAG}")
|
if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
|
||||||
unset(OpenMP_FLAG_DETECTED CACHE)
|
OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
|
||||||
if(NOT CMAKE_REQUIRED_QUIET)
|
_OPENMP_GET_FLAGS("${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK)
|
||||||
message(STATUS "Try OpenMP C flag = [${FLAG}]")
|
|
||||||
endif()
|
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()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
set(OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}"
|
set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
|
||||||
CACHE STRING "C compiler flags for OpenMP parallization")
|
CACHE STRING "${LANG} compiler flags for OpenMP parallelization")
|
||||||
|
set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
|
||||||
list(APPEND _OPENMP_REQUIRED_VARS OpenMP_C_FLAGS)
|
CACHE STRING "${LANG} compiler libraries for OpenMP parallelization")
|
||||||
unset(OpenMP_C_FLAG_CANDIDATES)
|
mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
|
||||||
|
|
||||||
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")
|
|
||||||
endif()
|
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)
|
|
||||||
|
|
||||||
# use the same source for CXX as C for now
|
|
||||||
set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE})
|
|
||||||
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()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS_INTERNAL}"
|
|
||||||
CACHE STRING "C++ compiler flags for OpenMP parallization")
|
|
||||||
|
|
||||||
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")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# check Fortran compiler
|
|
||||||
if(CMAKE_Fortran_COMPILER_LOADED)
|
if(CMAKE_Fortran_COMPILER_LOADED)
|
||||||
# if these are set then do not try to find them again,
|
if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
|
||||||
# by avoiding any try_compiles for the flags
|
OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
|
||||||
if(OpenMP_Fortran_FLAGS)
|
OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
|
||||||
unset(OpenMP_Fortran_FLAG_CANDIDATES)
|
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()
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
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}"
|
||||||
|
CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
|
||||||
|
set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
|
||||||
else()
|
else()
|
||||||
_OPENMP_FLAG_CANDIDATES("Fortran")
|
set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranSourceCompiles.cmake)
|
|
||||||
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_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_INTERNAL}"
|
|
||||||
CACHE STRING "Fortran compiler flags for OpenMP parallization")
|
|
||||||
|
|
||||||
list(APPEND _OPENMP_REQUIRED_VARS OpenMP_Fortran_FLAGS)
|
|
||||||
unset(OpenMP_Fortran_FLAG_CANDIDATES)
|
|
||||||
|
|
||||||
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()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
|
set(OPENMP_FOUND TRUE)
|
||||||
|
|
||||||
if(_OPENMP_REQUIRED_VARS)
|
foreach(LANG IN ITEMS C CXX Fortran)
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
|
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()
|
||||||
|
|
||||||
find_package_handle_standard_args(OpenMP
|
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
|
||||||
REQUIRED_VARS ${_OPENMP_REQUIRED_VARS})
|
|
||||||
|
|
||||||
mark_as_advanced(${_OPENMP_REQUIRED_VARS})
|
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})
|
||||||
|
|
||||||
unset(_OPENMP_REQUIRED_VARS)
|
set(_OPENMP_${LANG}_REQUIRED_VARS OpenMP_${LANG}_FLAGS)
|
||||||
else()
|
if("${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
|
||||||
message(SEND_ERROR "FindOpenMP requires C or CXX language to be enabled")
|
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}
|
||||||
|
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()
|
||||||
|
|
||||||
|
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()
|
endif()
|
||||||
|
|
||||||
unset(OpenMP_C_TEST_SOURCE)
|
if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
|
||||||
unset(OpenMP_CXX_TEST_SOURCE)
|
message(SEND_ERROR "FindOpenMP requires the C, CXX or Fortran languages to be enabled")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
unset(OpenMP_C_CXX_TEST_SOURCE)
|
||||||
unset(OpenMP_Fortran_TEST_SOURCE)
|
unset(OpenMP_Fortran_TEST_SOURCE)
|
||||||
unset(OpenMP_C_CXX_CHECK_VERSION_SOURCE)
|
unset(OpenMP_C_CXX_CHECK_VERSION_SOURCE)
|
||||||
unset(OpenMP_Fortran_CHECK_VERSION_SOURCE)
|
unset(OpenMP_Fortran_CHECK_VERSION_SOURCE)
|
||||||
|
unset(OpenMP_Fortran_INCLUDE_LINE)
|
||||||
|
|
||||||
|
cmake_policy(POP)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user