mirror of
https://github.com/reactos/CMake.git
synced 2025-01-19 01:42:18 +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
|
||||
# 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")
|
||||
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")
|
||||
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()
|
||||
|
||||
list(APPEND OpenMP_FLAG_CANDIDATES " ")
|
||||
set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
|
||||
else()
|
||||
set(OMP_FLAG_Intel "-qopenmp")
|
||||
set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE)
|
||||
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()
|
||||
|
||||
# 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()
|
||||
unset(_version_match)
|
||||
unset(OpenMP_SPEC_DATE_MAP)
|
||||
endmacro()
|
||||
|
||||
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}]")
|
||||
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()
|
||||
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}"
|
||||
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)
|
||||
|
||||
# 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 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(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()
|
||||
|
||||
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()
|
||||
_OPENMP_FLAG_CANDIDATES("Fortran")
|
||||
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")
|
||||
set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
|
||||
set(OPENMP_FOUND TRUE)
|
||||
|
||||
if(_OPENMP_REQUIRED_VARS)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
|
||||
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()
|
||||
|
||||
find_package_handle_standard_args(OpenMP
|
||||
REQUIRED_VARS ${_OPENMP_REQUIRED_VARS})
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
|
||||
|
||||
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)
|
||||
else()
|
||||
message(SEND_ERROR "FindOpenMP requires C or CXX language to be enabled")
|
||||
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}
|
||||
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()
|
||||
|
||||
unset(OpenMP_C_TEST_SOURCE)
|
||||
unset(OpenMP_CXX_TEST_SOURCE)
|
||||
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_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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user