From ed9a77122764b07dc9062e2d9516f62389f43bf3 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Wed, 4 Nov 2020 21:21:46 -0600 Subject: [PATCH 01/17] Add initial CMake build support --- .gitignore | 3 + CMakeLists.txt | 39 ++ CMakeSettings.json | 28 ++ base64/CMakeLists.txt | 21 + cmake/AddCompilerFlag.cmake | 130 +++++++ cmake/CheckCCompilerFlag.cmake | 73 ++++ cmake/CheckCXXCompilerFlag.cmake | 73 ++++ cmake/OptimizeForArchitecture.cmake | 581 ++++++++++++++++++++++++++++ dllsrc/CMakeLists.txt | 16 + jsrc/CMakeLists.txt | 231 +++++++++++ sleef/CMakeLists.txt | 36 ++ 11 files changed, 1231 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 CMakeSettings.json create mode 100644 base64/CMakeLists.txt create mode 100644 cmake/AddCompilerFlag.cmake create mode 100644 cmake/CheckCCompilerFlag.cmake create mode 100644 cmake/CheckCXXCompilerFlag.cmake create mode 100644 cmake/OptimizeForArchitecture.cmake create mode 100644 dllsrc/CMakeLists.txt create mode 100644 jsrc/CMakeLists.txt create mode 100644 sleef/CMakeLists.txt diff --git a/.gitignore b/.gitignore index 182d36594..c9548fdbb 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ jj.ijs *.sln* *.vcxproj* !*.template +.vs/ # mac .DS_Store @@ -58,6 +59,8 @@ release /test/temp.ijs # build folders +out/ +build/ bin/ make2/ jlibrary/addons/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..5e191ce34 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.17) + +get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(is_multi_config) + set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING + "Semicolon separated list of supported configuration types") + mark_as_advanced(CMAKE_CONFIGURATION_TYPES) +elseif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS) + message(WARNING "No CMAKE_BUILD_TYPE is selected") +endif() + +project(j) +enable_language(C CXX) + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +include(OptimizeForArchitecture) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) + +find_package(OpenMP) + +set(TARGET_ARCHITECTURE "skylake" CACHE STRING "CPU architecture") +OptimizeForArchitecture() +add_compile_options("$<$:${Vc_ARCHITECTURE_FLAGS}>") +add_compile_options("$<$:${Vc_ARCHITECTURE_FLAGS}>") + +add_subdirectory(jsrc) +add_subdirectory(sleef) +add_subdirectory(base64) +add_subdirectory(dllsrc) + +target_link_libraries(j PRIVATE j-blis j-openssl-sha j-sleef j-base64) +if(WIN32) + target_link_libraries(j PRIVATE j-dll) + target_sources(j PRIVATE dllsrc/jdll.def dllsrc/jdll.rc dllsrc/jdll.tlb) +endif() diff --git a/CMakeSettings.json b/CMakeSettings.json new file mode 100644 index 000000000..f5e73573b --- /dev/null +++ b/CMakeSettings.json @@ -0,0 +1,28 @@ +{ + "configurations": [ + { + "name": "x64-Clang-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "clang_cl_x64_x64" ], + "variables": [] + }, + { + "name": "x64-Clang-Release", + "generator": "Ninja", + "configurationType": "RelWithDebInfo", + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "clang_cl_x64_x64" ], + "variables": [] + } + ] +} \ No newline at end of file diff --git a/base64/CMakeLists.txt b/base64/CMakeLists.txt new file mode 100644 index 000000000..eb533dc9c --- /dev/null +++ b/base64/CMakeLists.txt @@ -0,0 +1,21 @@ +add_library(j-base64 OBJECT) +target_compile_definitions(j-base64 PRIVATE HAVE_AVX2=1) +target_sources(j-base64 PRIVATE + include/libbase64.h + lib/arch/avx/codec-avx.c + lib/arch/avx2/codec-avx2.c + lib/arch/generic/codec-generic.c + lib/arch/neon64/codec-neon64.c + lib/arch/sse41/codec-sse41.c + lib/arch/sse42/codec-sse42.c + lib/arch/ssse3/codec-ssse3.c + lib/codecs.h + lib/codec_choose.c + lib/config.h + lib/env.h + lib/lib.c + lib/tables/tables.c + lib/tables/tables.h + lib/tables/table_dec_32bit.h + lib/tables/table_enc_12bit.h +) diff --git a/cmake/AddCompilerFlag.cmake b/cmake/AddCompilerFlag.cmake new file mode 100644 index 000000000..6684fa54a --- /dev/null +++ b/cmake/AddCompilerFlag.cmake @@ -0,0 +1,130 @@ +# - Add a given compiler flag to flags variables. +# AddCompilerFlag( []) +# or +# AddCompilerFlag( [C_FLAGS ] [CXX_FLAGS ] [C_RESULT ] +# [CXX_RESULT ]) + +#============================================================================= +# Copyright 2010-2015 Matthias Kretz +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the names of contributing organizations nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +get_filename_component(_currentDir "${CMAKE_CURRENT_LIST_FILE}" PATH) +include("${_currentDir}/CheckCCompilerFlag.cmake") +include("${_currentDir}/CheckCXXCompilerFlag.cmake") + +macro(AddCompilerFlag _flag) + string(REGEX REPLACE "[-.+/:= ]" "_" _flag_esc "${_flag}") + + set(_c_flags "CMAKE_C_FLAGS") + set(_cxx_flags "CMAKE_CXX_FLAGS") + set(_c_result tmp) + set(_cxx_result tmp) + if(${ARGC} EQUAL 2) + message(WARNING "Deprecated use of the AddCompilerFlag macro.") + unset(_c_result) + set(_cxx_result ${ARGV1}) + elseif(${ARGC} GREATER 2) + set(state 0) + unset(_c_flags) + unset(_cxx_flags) + unset(_c_result) + unset(_cxx_result) + foreach(_arg ${ARGN}) + if("x${_arg}" STREQUAL "xC_FLAGS") + set(state 1) + if(NOT DEFINED _c_result) + set(_c_result tmp0) + endif() + elseif("x${_arg}" STREQUAL "xCXX_FLAGS") + set(state 2) + if(NOT DEFINED _cxx_result) + set(_cxx_result tmp1) + endif() + elseif("x${_arg}" STREQUAL "xC_RESULT") + set(state 3) + elseif("x${_arg}" STREQUAL "xCXX_RESULT") + set(state 4) + elseif(state EQUAL 1) + set(_c_flags "${_arg}") + elseif(state EQUAL 2) + set(_cxx_flags "${_arg}") + elseif(state EQUAL 3) + set(_c_result "${_arg}") + elseif(state EQUAL 4) + set(_cxx_result "${_arg}") + else() + message(FATAL_ERROR "Syntax error for AddCompilerFlag") + endif() + endforeach() + endif() + + set(_c_code "int main() { return 0; }") + set(_cxx_code "int main() { return 0; }") + if("${_flag}" STREQUAL "-mfma") + # Compiling with FMA3 support may fail only at the assembler level. + # In that case we need to have such an instruction in the test code + set(_c_code "#include + __m128 foo(__m128 x) { return _mm_fmadd_ps(x, x, x); } + int main() { return 0; }") + set(_cxx_code "${_c_code}") + elseif("${_flag}" STREQUAL "-stdlib=libc++") + # Compiling with libc++ not only requires a compiler that understands it, but also + # the libc++ headers itself + set(_cxx_code "#include + #include + int main() { return 0; }") + else() + set(_cxx_code "#include + int main() { return 0; }") + endif() + + if(DEFINED _c_result) + check_c_compiler_flag("${_flag}" check_c_compiler_flag_${_flag_esc} "${_c_code}") + set(${_c_result} ${check_c_compiler_flag_${_flag_esc}}) + endif() + if(DEFINED _cxx_result) + check_cxx_compiler_flag("${_flag}" check_cxx_compiler_flag_${_flag_esc} "${_cxx_code}") + set(${_cxx_result} ${check_cxx_compiler_flag_${_flag_esc}}) + endif() + + macro(my_append _list _flag _special) + if("x${_list}" STREQUAL "x${_special}") + set(${_list} "${${_list}} ${_flag}") + else() + list(APPEND ${_list} "${_flag}") + endif() + endmacro() + + if(check_c_compiler_flag_${_flag_esc} AND DEFINED _c_flags) + my_append(${_c_flags} "${_flag}" CMAKE_C_FLAGS) + endif() + if(check_cxx_compiler_flag_${_flag_esc} AND DEFINED _cxx_flags) + my_append(${_cxx_flags} "${_flag}" CMAKE_CXX_FLAGS) + endif() +endmacro(AddCompilerFlag) diff --git a/cmake/CheckCCompilerFlag.cmake b/cmake/CheckCCompilerFlag.cmake new file mode 100644 index 000000000..07ec156e0 --- /dev/null +++ b/cmake/CheckCCompilerFlag.cmake @@ -0,0 +1,73 @@ +# - Check whether the C compiler supports a given flag. +# CHECK_C_COMPILER_FLAG( ) +# - the compiler flag +# - variable to store the result +# This internally calls the check_c_source_compiles macro. +# See help for CheckCSourceCompiles for a listing of variables +# that can modify the build. + +#============================================================================= +# Copyright 2006-2009 Kitware, Inc. +# Copyright 2006 Alexander Neundorf +# Copyright 2011-2013 Matthias Kretz +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * The names of Kitware, Inc., the Insight Consortium, or the names of +# any consortium members, or of any contributors, may not be used to +# endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +INCLUDE(CheckCSourceCompiles) + +MACRO (CHECK_C_COMPILER_FLAG _FLAG _RESULT) + SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") + SET(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") + if(${ARGC} GREATER 2) + SET(TEST_SOURCE "${ARGV2}") + else() + SET(TEST_SOURCE "int main() { return 0;}") + endif() + CHECK_C_SOURCE_COMPILES("${TEST_SOURCE}" ${_RESULT} + # Some compilers do not fail with a bad flag + FAIL_REGEX "error: bad value (.*) for .* switch" # GNU + FAIL_REGEX "argument unused during compilation" # clang + FAIL_REGEX "is valid for .* but not for C" # GNU + FAIL_REGEX "unrecognized .*option" # GNU + FAIL_REGEX "ignored for target" # GNU + FAIL_REGEX "ignoring unknown option" # MSVC + FAIL_REGEX "warning D9002" # MSVC + FAIL_REGEX "[Uu]nknown option" # HP + FAIL_REGEX "[Ww]arning: [Oo]ption" # SunPro + FAIL_REGEX "command option .* is not recognized" # XL + FAIL_REGEX "WARNING: unknown flag:" # Open64 + FAIL_REGEX "command line error" # ICC + FAIL_REGEX "command line warning" # ICC + FAIL_REGEX "#10236:" # ICC: File not found + FAIL_REGEX " #10159: " # ICC + FAIL_REGEX " #10353: " # ICC: option '-mfma' ignored, suggest using '-march=core-avx2' + ) + SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") +ENDMACRO (CHECK_C_COMPILER_FLAG) + diff --git a/cmake/CheckCXXCompilerFlag.cmake b/cmake/CheckCXXCompilerFlag.cmake new file mode 100644 index 000000000..e3b0188a4 --- /dev/null +++ b/cmake/CheckCXXCompilerFlag.cmake @@ -0,0 +1,73 @@ +# - Check whether the CXX compiler supports a given flag. +# CHECK_CXX_COMPILER_FLAG( ) +# - the compiler flag +# - variable to store the result +# This internally calls the check_cxx_source_compiles macro. See help +# for CheckCXXSourceCompiles for a listing of variables that can +# modify the build. + +#============================================================================= +# Copyright 2006-2009 Kitware, Inc. +# Copyright 2006 Alexander Neundorf +# Copyright 2011-2013 Matthias Kretz +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * The names of Kitware, Inc., the Insight Consortium, or the names of +# any consortium members, or of any contributors, may not be used to +# endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +INCLUDE(CheckCXXSourceCompiles) + +MACRO (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT) + SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") + SET(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") + if(${ARGC} GREATER 2) + SET(TEST_SOURCE "${ARGV2}") + else() + SET(TEST_SOURCE "int main() { return 0;}") + endif() + CHECK_CXX_SOURCE_COMPILES("${TEST_SOURCE}" ${_RESULT} + # Some compilers do not fail with a bad flag + FAIL_REGEX "error: bad value (.*) for .* switch" # GNU + FAIL_REGEX "argument unused during compilation" # clang + FAIL_REGEX "is valid for .* but not for C\\\\+\\\\+" # GNU + FAIL_REGEX "unrecognized .*option" # GNU + FAIL_REGEX "ignored for target" # GNU + FAIL_REGEX "ignoring unknown option" # MSVC + FAIL_REGEX "warning D9002" # MSVC + FAIL_REGEX "[Uu]nknown option" # HP + FAIL_REGEX "[Ww]arning: [Oo]ption" # SunPro + FAIL_REGEX "command option .* is not recognized" # XL + FAIL_REGEX "WARNING: unknown flag:" # Open64 + FAIL_REGEX "command line error" # ICC + FAIL_REGEX "command line warning" # ICC + FAIL_REGEX "#10236:" # ICC: File not found + FAIL_REGEX " #10159: " # ICC + FAIL_REGEX " #10353: " # ICC: option '-mfma' ignored, suggest using '-march=core-avx2' + ) + SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") +ENDMACRO (CHECK_CXX_COMPILER_FLAG) + diff --git a/cmake/OptimizeForArchitecture.cmake b/cmake/OptimizeForArchitecture.cmake new file mode 100644 index 000000000..075956c2e --- /dev/null +++ b/cmake/OptimizeForArchitecture.cmake @@ -0,0 +1,581 @@ +# Determine the host CPU feature set and determine the best set of compiler +# flags to enable all supported SIMD relevant features. Alternatively, the +# target CPU can be explicitly selected (for generating more generic binaries +# or for targeting a different system). +# Compilers provide e.g. the -march=native flag to achieve a similar result. +# This fails to address the need for building for a different microarchitecture +# than the current host. +# The script tries to deduce all settings from the model and family numbers of +# the CPU instead of reading the CPUID flags from e.g. /proc/cpuinfo. This makes +# the detection more independent from the CPUID code in the kernel (e.g. avx2 is +# not listed on older kernels). +# +# Usage: +# OptimizeForArchitecture() +# If either of Vc_SSE_INTRINSICS_BROKEN, Vc_AVX_INTRINSICS_BROKEN, +# Vc_AVX2_INTRINSICS_BROKEN is defined and set, the OptimizeForArchitecture +# macro will consequently disable the relevant features via compiler flags. + +#============================================================================= +# Copyright 2010-2016 Matthias Kretz +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the names of contributing organizations nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +get_filename_component(_currentDir "${CMAKE_CURRENT_LIST_FILE}" PATH) +include("${_currentDir}/AddCompilerFlag.cmake") +include(CheckIncludeFileCXX) + +macro(_my_find _list _value _ret) + list(FIND ${_list} "${_value}" _found) + if(_found EQUAL -1) + set(${_ret} FALSE) + else(_found EQUAL -1) + set(${_ret} TRUE) + endif(_found EQUAL -1) +endmacro(_my_find) + +macro(AutodetectHostArchitecture) + set(TARGET_ARCHITECTURE "generic") + set(Vc_ARCHITECTURE_FLAGS) + set(_vendor_id) + set(_cpu_family) + set(_cpu_model) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + file(READ "/proc/cpuinfo" _cpuinfo) + string(REGEX REPLACE ".*vendor_id[ \t]*:[ \t]+([a-zA-Z0-9_-]+).*" "\\1" _vendor_id "${_cpuinfo}") + string(REGEX REPLACE ".*cpu family[ \t]*:[ \t]+([a-zA-Z0-9_-]+).*" "\\1" _cpu_family "${_cpuinfo}") + string(REGEX REPLACE ".*model[ \t]*:[ \t]+([a-zA-Z0-9_-]+).*" "\\1" _cpu_model "${_cpuinfo}") + string(REGEX REPLACE ".*flags[ \t]*:[ \t]+([^\n]+).*" "\\1" _cpu_flags "${_cpuinfo}") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + exec_program("/usr/sbin/sysctl -n machdep.cpu.vendor machdep.cpu.model machdep.cpu.family machdep.cpu.features" OUTPUT_VARIABLE _sysctl_output_string) + string(REPLACE "\n" ";" _sysctl_output ${_sysctl_output_string}) + list(GET _sysctl_output 0 _vendor_id) + list(GET _sysctl_output 1 _cpu_model) + list(GET _sysctl_output 2 _cpu_family) + list(GET _sysctl_output 3 _cpu_flags) + + string(TOLOWER "${_cpu_flags}" _cpu_flags) + string(REPLACE "." "_" _cpu_flags "${_cpu_flags}") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + get_filename_component(_vendor_id "[HKEY_LOCAL_MACHINE\\Hardware\\Description\\System\\CentralProcessor\\0;VendorIdentifier]" NAME CACHE) + get_filename_component(_cpu_id "[HKEY_LOCAL_MACHINE\\Hardware\\Description\\System\\CentralProcessor\\0;Identifier]" NAME CACHE) + mark_as_advanced(_vendor_id _cpu_id) + string(REGEX REPLACE ".* Family ([0-9]+) .*" "\\1" _cpu_family "${_cpu_id}") + string(REGEX REPLACE ".* Model ([0-9]+) .*" "\\1" _cpu_model "${_cpu_id}") + endif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + if(_vendor_id STREQUAL "GenuineIntel") + if(_cpu_family EQUAL 6) + # taken from the Intel ORM + # http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html + # CPUID Signature Values of Of Recent Intel Microarchitectures + # 4E 5E | Skylake microarchitecture + # 3D 47 56 | Broadwell microarchitecture + # 3C 45 46 3F | Haswell microarchitecture + # 3A 3E | Ivy Bridge microarchitecture + # 2A 2D | Sandy Bridge microarchitecture + # 25 2C 2F | Intel microarchitecture Westmere + # 1A 1E 1F 2E | Intel microarchitecture Nehalem + # 17 1D | Enhanced Intel Core microarchitecture + # 0F | Intel Core microarchitecture + # + # Intel SDM Vol. 3C 35-1 / December 2016: + # 57 | Xeon Phi 3200, 5200, 7200 [Knights Landing] + # 85 | Future Xeon Phi + # 8E 9E | 7th gen. Core [Kaby Lake] + # 55 | Future Xeon [Skylake w/ AVX512] + # 4E 5E | 6th gen. Core / E3 v5 [Skylake w/o AVX512] + # 56 | Xeon D-1500 [Broadwell] + # 4F | Xeon E5 v4, E7 v4, i7-69xx [Broadwell] + # 47 | 5th gen. Core / Xeon E3 v4 [Broadwell] + # 3D | M-5xxx / 5th gen. [Broadwell] + # 3F | Xeon E5 v3, E7 v3, i7-59xx [Haswell-E] + # 3C 45 46 | 4th gen. Core, Xeon E3 v3 [Haswell] + # 3E | Xeon E5 v2, E7 v2, i7-49xx [Ivy Bridge-E] + # 3A | 3rd gen. Core, Xeon E3 v2 [Ivy Bridge] + # 2D | Xeon E5, i7-39xx [Sandy Bridge] + # 2F | Xeon E7 + # 2A | Xeon E3, 2nd gen. Core [Sandy Bridge] + # 2E | Xeon 7500, 6500 series + # 25 2C | Xeon 3600, 5600 series, Core i7, i5 and i3 + # + # Values from the Intel SDE: + # 5C | Goldmont + # 5A | Silvermont + # 57 | Knights Landing + # 66 | Cannonlake + # 55 | Skylake Server + # 4E | Skylake Client + # 3C | Broadwell (likely a bug in the SDE) + # 3C | Haswell + if(_cpu_model EQUAL 87) # 57 + set(TARGET_ARCHITECTURE "knl") # Knights Landing + elseif(_cpu_model EQUAL 92) + set(TARGET_ARCHITECTURE "goldmont") + elseif(_cpu_model EQUAL 90 OR _cpu_model EQUAL 76) + set(TARGET_ARCHITECTURE "silvermont") + elseif(_cpu_model EQUAL 102) + set(TARGET_ARCHITECTURE "cannonlake") + elseif(_cpu_model EQUAL 142 OR _cpu_model EQUAL 158) # 8E, 9E + set(TARGET_ARCHITECTURE "kaby-lake") + elseif(_cpu_model EQUAL 85) # 55 + set(TARGET_ARCHITECTURE "skylake-avx512") + elseif(_cpu_model EQUAL 78 OR _cpu_model EQUAL 94) # 4E, 5E + set(TARGET_ARCHITECTURE "skylake") + elseif(_cpu_model EQUAL 61 OR _cpu_model EQUAL 71 OR _cpu_model EQUAL 79 OR _cpu_model EQUAL 86) # 3D, 47, 4F, 56 + set(TARGET_ARCHITECTURE "broadwell") + elseif(_cpu_model EQUAL 60 OR _cpu_model EQUAL 69 OR _cpu_model EQUAL 70 OR _cpu_model EQUAL 63) + set(TARGET_ARCHITECTURE "haswell") + elseif(_cpu_model EQUAL 58 OR _cpu_model EQUAL 62) + set(TARGET_ARCHITECTURE "ivy-bridge") + elseif(_cpu_model EQUAL 42 OR _cpu_model EQUAL 45) + set(TARGET_ARCHITECTURE "sandy-bridge") + elseif(_cpu_model EQUAL 37 OR _cpu_model EQUAL 44 OR _cpu_model EQUAL 47) + set(TARGET_ARCHITECTURE "westmere") + elseif(_cpu_model EQUAL 26 OR _cpu_model EQUAL 30 OR _cpu_model EQUAL 31 OR _cpu_model EQUAL 46) + set(TARGET_ARCHITECTURE "nehalem") + elseif(_cpu_model EQUAL 23 OR _cpu_model EQUAL 29) + set(TARGET_ARCHITECTURE "penryn") + elseif(_cpu_model EQUAL 15) + set(TARGET_ARCHITECTURE "merom") + elseif(_cpu_model EQUAL 28) + set(TARGET_ARCHITECTURE "atom") + elseif(_cpu_model EQUAL 14) + set(TARGET_ARCHITECTURE "core") + elseif(_cpu_model LESS 14) + message(WARNING "Your CPU (family ${_cpu_family}, model ${_cpu_model}) is not known. Auto-detection of optimization flags failed and will use the generic CPU settings with SSE2.") + set(TARGET_ARCHITECTURE "generic") + else() + message(WARNING "Your CPU (family ${_cpu_family}, model ${_cpu_model}) is not known. Auto-detection of optimization flags failed and will use the 65nm Core 2 CPU settings.") + set(TARGET_ARCHITECTURE "merom") + endif() + elseif(_cpu_family EQUAL 7) # Itanium (not supported) + message(WARNING "Your CPU (Itanium: family ${_cpu_family}, model ${_cpu_model}) is not supported by OptimizeForArchitecture.cmake.") + elseif(_cpu_family EQUAL 15) # NetBurst + list(APPEND _available_vector_units_list "sse" "sse2") + if(_cpu_model GREATER 2) # Not sure whether this must be 3 or even 4 instead + list(APPEND _available_vector_units_list "sse" "sse2" "sse3") + endif(_cpu_model GREATER 2) + endif(_cpu_family EQUAL 6) + elseif(_vendor_id STREQUAL "AuthenticAMD") + if(_cpu_family EQUAL 23) + set(TARGET_ARCHITECTURE "zen") + elseif(_cpu_family EQUAL 22) # 16h + set(TARGET_ARCHITECTURE "AMD 16h") + elseif(_cpu_family EQUAL 21) # 15h + if(_cpu_model LESS 2) + set(TARGET_ARCHITECTURE "bulldozer") + else() + set(TARGET_ARCHITECTURE "piledriver") + endif() + elseif(_cpu_family EQUAL 20) # 14h + set(TARGET_ARCHITECTURE "AMD 14h") + elseif(_cpu_family EQUAL 18) # 12h + elseif(_cpu_family EQUAL 16) # 10h + set(TARGET_ARCHITECTURE "barcelona") + elseif(_cpu_family EQUAL 15) + set(TARGET_ARCHITECTURE "k8") + if(_cpu_model GREATER 64) # I don't know the right number to put here. This is just a guess from the hardware I have access to + set(TARGET_ARCHITECTURE "k8-sse3") + endif(_cpu_model GREATER 64) + endif() + endif(_vendor_id STREQUAL "GenuineIntel") +endmacro() + +macro(OptimizeForArchitecture) + if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(x86|AMD64)") + OptimizeForArchitectureX86() + else() + message(STATUS "No support for auto-detection of the target instruction set/extension") + set(TARGET_ARCHITECTURE "unused" CACHE STRING "CPU architecture to optimize for. (unused)") + endif() +endmacro() + +macro(OptimizeForArchitectureX86) + set(TARGET_ARCHITECTURE "auto" CACHE STRING "CPU architecture to optimize for. \ +Using an incorrect setting here can result in crashes of the resulting binary because of invalid instructions used. \ +Setting the value to \"auto\" will try to optimize for the architecture where cmake is called. \ +Other supported values are: \"none\", \"generic\", \"core\", \"merom\" (65nm Core2), \ +\"penryn\" (45nm Core2), \"nehalem\", \"westmere\", \"sandy-bridge\", \"ivy-bridge\", \ +\"haswell\", \"broadwell\", \"skylake\", \"skylake-xeon\", \"kaby-lake\", \"cannonlake\", \"silvermont\", \ +\"goldmont\", \"knl\" (Knights Landing), \"atom\", \"k8\", \"k8-sse3\", \"barcelona\", \ +\"istanbul\", \"magny-cours\", \"bulldozer\", \"interlagos\", \"piledriver\", \ +\"AMD 14h\", \"AMD 16h\", \"zen\".") + set(_force) + if(NOT _last_target_arch STREQUAL "${TARGET_ARCHITECTURE}") + message(STATUS "target changed from \"${_last_target_arch}\" to \"${TARGET_ARCHITECTURE}\"") + set(_force FORCE) + endif() + set(_last_target_arch "${TARGET_ARCHITECTURE}" CACHE STRING "" FORCE) + mark_as_advanced(_last_target_arch) + string(TOLOWER "${TARGET_ARCHITECTURE}" TARGET_ARCHITECTURE) + + set(_march_flag_list) + set(_available_vector_units_list) + + if(TARGET_ARCHITECTURE STREQUAL "auto") + AutodetectHostArchitecture() + message(STATUS "Detected CPU: ${TARGET_ARCHITECTURE}") + endif(TARGET_ARCHITECTURE STREQUAL "auto") + + macro(_nehalem) + list(APPEND _march_flag_list "nehalem") + list(APPEND _march_flag_list "corei7") + list(APPEND _march_flag_list "core2") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4.1" "sse4.2") + endmacro() + macro(_westmere) + list(APPEND _march_flag_list "westmere") + _nehalem() + endmacro() + macro(_sandybridge) + list(APPEND _march_flag_list "sandybridge") + list(APPEND _march_flag_list "corei7-avx") + _westmere() + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4.1" "sse4.2" "avx") + endmacro() + macro(_ivybridge) + list(APPEND _march_flag_list "ivybridge") + list(APPEND _march_flag_list "core-avx-i") + _sandybridge() + list(APPEND _available_vector_units_list "rdrnd" "f16c") + endmacro() + macro(_haswell) + list(APPEND _march_flag_list "haswell") + list(APPEND _march_flag_list "core-avx2") + _ivybridge() + list(APPEND _available_vector_units_list "avx2" "fma" "bmi" "bmi2") + endmacro() + macro(_broadwell) + list(APPEND _march_flag_list "broadwell") + _haswell() + endmacro() + macro(_skylake) + list(APPEND _march_flag_list "skylake") + _broadwell() + endmacro() + macro(_skylake_avx512) + list(APPEND _march_flag_list "skylake-avx512") + _skylake() + list(APPEND _available_vector_units_list "avx512f" "avx512cd" "avx512dq" "avx512bw" "avx512vl") + endmacro() + macro(_cannonlake) + list(APPEND _march_flag_list "cannonlake") + _skylake_avx512() + list(APPEND _available_vector_units_list "avx512ifma" "avx512vbmi") + endmacro() + macro(_knightslanding) + list(APPEND _march_flag_list "knl") + _broadwell() + list(APPEND _available_vector_units_list "avx512f" "avx512pf" "avx512er" "avx512cd") + endmacro() + macro(_silvermont) + list(APPEND _march_flag_list "silvermont") + _westmere() + list(APPEND _available_vector_units_list "rdrnd") + endmacro() + macro(_goldmont) + list(APPEND _march_flag_list "goldmont") + _silvermont() + endmacro() + + if(TARGET_ARCHITECTURE STREQUAL "core") + list(APPEND _march_flag_list "core2") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3") + elseif(TARGET_ARCHITECTURE STREQUAL "merom") + list(APPEND _march_flag_list "merom") + list(APPEND _march_flag_list "core2") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3") + elseif(TARGET_ARCHITECTURE STREQUAL "penryn") + list(APPEND _march_flag_list "penryn") + list(APPEND _march_flag_list "core2") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3") + message(STATUS "Sadly the Penryn architecture exists in variants with SSE4.1 and without SSE4.1.") + if(_cpu_flags MATCHES "sse4_1") + message(STATUS "SSE4.1: enabled (auto-detected from this computer's CPU flags)") + list(APPEND _available_vector_units_list "sse4.1") + else() + message(STATUS "SSE4.1: disabled (auto-detected from this computer's CPU flags)") + endif() + elseif(TARGET_ARCHITECTURE STREQUAL "knl") + _knightslanding() + elseif(TARGET_ARCHITECTURE STREQUAL "cannonlake") + _cannonlake() + elseif(TARGET_ARCHITECTURE STREQUAL "kaby-lake") + _skylake() + elseif(TARGET_ARCHITECTURE STREQUAL "skylake-xeon" OR TARGET_ARCHITECTURE STREQUAL "skylake-avx512") + _skylake_avx512() + elseif(TARGET_ARCHITECTURE STREQUAL "skylake") + _skylake() + elseif(TARGET_ARCHITECTURE STREQUAL "broadwell") + _broadwell() + elseif(TARGET_ARCHITECTURE STREQUAL "haswell") + _haswell() + elseif(TARGET_ARCHITECTURE STREQUAL "ivy-bridge") + _ivybridge() + elseif(TARGET_ARCHITECTURE STREQUAL "sandy-bridge") + _sandybridge() + elseif(TARGET_ARCHITECTURE STREQUAL "westmere") + _westmere() + elseif(TARGET_ARCHITECTURE STREQUAL "nehalem") + _nehalem() + elseif(TARGET_ARCHITECTURE STREQUAL "goldmont") + _goldmont() + elseif(TARGET_ARCHITECTURE STREQUAL "silvermont") + _silvermont() + elseif(TARGET_ARCHITECTURE STREQUAL "atom") + list(APPEND _march_flag_list "atom") + list(APPEND _march_flag_list "core2") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3") + elseif(TARGET_ARCHITECTURE STREQUAL "k8") + list(APPEND _march_flag_list "k8") + list(APPEND _available_vector_units_list "sse" "sse2") + elseif(TARGET_ARCHITECTURE STREQUAL "k8-sse3") + list(APPEND _march_flag_list "k8-sse3") + list(APPEND _march_flag_list "k8") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3") + elseif(TARGET_ARCHITECTURE STREQUAL "AMD 16h") + list(APPEND _march_flag_list "btver2") + list(APPEND _march_flag_list "btver1") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a" "sse4.1" "sse4.2" "avx" "f16c") + elseif(TARGET_ARCHITECTURE STREQUAL "AMD 14h") + list(APPEND _march_flag_list "btver1") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a") + elseif(TARGET_ARCHITECTURE STREQUAL "zen") + list(APPEND _march_flag_list "znver1") + _skylake() + list(APPEND _available_vector_units_list "sse4a") + elseif(TARGET_ARCHITECTURE STREQUAL "piledriver") + list(APPEND _march_flag_list "bdver2") + list(APPEND _march_flag_list "bdver1") + list(APPEND _march_flag_list "bulldozer") + list(APPEND _march_flag_list "barcelona") + list(APPEND _march_flag_list "core2") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a" "sse4.1" "sse4.2" "avx" "xop" "fma4" "fma" "f16c") + elseif(TARGET_ARCHITECTURE STREQUAL "interlagos") + list(APPEND _march_flag_list "bdver1") + list(APPEND _march_flag_list "bulldozer") + list(APPEND _march_flag_list "barcelona") + list(APPEND _march_flag_list "core2") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a" "sse4.1" "sse4.2" "avx" "xop" "fma4") + elseif(TARGET_ARCHITECTURE STREQUAL "bulldozer") + list(APPEND _march_flag_list "bdver1") + list(APPEND _march_flag_list "bulldozer") + list(APPEND _march_flag_list "barcelona") + list(APPEND _march_flag_list "core2") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a" "sse4.1" "sse4.2" "avx" "xop" "fma4") + elseif(TARGET_ARCHITECTURE STREQUAL "barcelona") + list(APPEND _march_flag_list "barcelona") + list(APPEND _march_flag_list "core2") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "sse4a") + elseif(TARGET_ARCHITECTURE STREQUAL "istanbul") + list(APPEND _march_flag_list "barcelona") + list(APPEND _march_flag_list "core2") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "sse4a") + elseif(TARGET_ARCHITECTURE STREQUAL "magny-cours") + list(APPEND _march_flag_list "barcelona") + list(APPEND _march_flag_list "core2") + list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "sse4a") + elseif(TARGET_ARCHITECTURE STREQUAL "generic") + list(APPEND _march_flag_list "generic") + elseif(TARGET_ARCHITECTURE STREQUAL "none") + # add this clause to remove it from the else clause + else(TARGET_ARCHITECTURE STREQUAL "core") + message(FATAL_ERROR "Unknown target architecture: \"${TARGET_ARCHITECTURE}\". Please set TARGET_ARCHITECTURE to a supported value.") + endif(TARGET_ARCHITECTURE STREQUAL "core") + + if(NOT TARGET_ARCHITECTURE STREQUAL "none") + set(_disable_vector_unit_list) + set(_enable_vector_unit_list) + if(DEFINED Vc_AVX_INTRINSICS_BROKEN AND Vc_AVX_INTRINSICS_BROKEN) + UserWarning("AVX disabled per default because of old/broken toolchain") + set(_avx_broken true) + set(_avx2_broken true) + set(_fma4_broken true) + set(_xop_broken true) + else() + set(_avx_broken false) + if(DEFINED Vc_FMA4_INTRINSICS_BROKEN AND Vc_FMA4_INTRINSICS_BROKEN) + UserWarning("FMA4 disabled per default because of old/broken toolchain") + set(_fma4_broken true) + else() + set(_fma4_broken false) + endif() + if(DEFINED Vc_XOP_INTRINSICS_BROKEN AND Vc_XOP_INTRINSICS_BROKEN) + UserWarning("XOP disabled per default because of old/broken toolchain") + set(_xop_broken true) + else() + set(_xop_broken false) + endif() + if(DEFINED Vc_AVX2_INTRINSICS_BROKEN AND Vc_AVX2_INTRINSICS_BROKEN) + UserWarning("AVX2 disabled per default because of old/broken toolchain") + set(_avx2_broken true) + else() + set(_avx2_broken false) + endif() + endif() + + macro(_enable_or_disable _name _flag _documentation _broken) + if(_broken) + set(_found false) + else() + _my_find(_available_vector_units_list "${_flag}" _found) + endif() + set(USE_${_name} ${_found} CACHE BOOL "${documentation}" ${_force}) + mark_as_advanced(USE_${_name}) + if(USE_${_name}) + list(APPEND _enable_vector_unit_list "${_flag}") + else() + list(APPEND _disable_vector_unit_list "${_flag}") + endif() + endmacro() + _enable_or_disable(SSE2 "sse2" "Use SSE2. If SSE2 instructions are not enabled the SSE implementation will be disabled." false) + _enable_or_disable(SSE3 "sse3" "Use SSE3. If SSE3 instructions are not enabled they will be emulated." false) + _enable_or_disable(SSSE3 "ssse3" "Use SSSE3. If SSSE3 instructions are not enabled they will be emulated." false) + _enable_or_disable(SSE4_1 "sse4.1" "Use SSE4.1. If SSE4.1 instructions are not enabled they will be emulated." false) + _enable_or_disable(SSE4_2 "sse4.2" "Use SSE4.2. If SSE4.2 instructions are not enabled they will be emulated." false) + _enable_or_disable(SSE4a "sse4a" "Use SSE4a. If SSE4a instructions are not enabled they will be emulated." false) + _enable_or_disable(AVX "avx" "Use AVX. This will all floating-point vector sizes relative to SSE." _avx_broken) + _enable_or_disable(FMA "fma" "Use FMA." _avx_broken) + _enable_or_disable(BMI2 "bmi2" "Use BMI2." _avx_broken) + _enable_or_disable(AVX2 "avx2" "Use AVX2. This will double all of the vector sizes relative to SSE." _avx2_broken) + _enable_or_disable(XOP "xop" "Use XOP." _xop_broken) + _enable_or_disable(FMA4 "fma4" "Use FMA4." _fma4_broken) + _enable_or_disable(AVX512F "avx512f" "Use AVX512F. This will double all floating-point vector sizes relative to AVX2." false) + _enable_or_disable(AVX512VL "avx512vl" "Use AVX512VL. This enables 128- and 256-bit vector length instructions with EVEX coding (improved write-masking & more vector registers)." _avx2_broken) + _enable_or_disable(AVX512PF "avx512pf" "Use AVX512PF. This enables prefetch instructions for gathers and scatters." false) + _enable_or_disable(AVX512ER "avx512er" "Use AVX512ER. This enables exponential and reciprocal instructions." false) + _enable_or_disable(AVX512CD "avx512cd" "Use AVX512CD." false) + _enable_or_disable(AVX512DQ "avx512dq" "Use AVX512DQ." false) + _enable_or_disable(AVX512BW "avx512bw" "Use AVX512BW." false) + _enable_or_disable(AVX512IFMA "avx512ifma" "Use AVX512IFMA." false) + _enable_or_disable(AVX512VBMI "avx512vbmi" "Use AVX512VBMI." false) + + if(MSVC) + # MSVC on 32 bit can select /arch:SSE2 (since 2010 also /arch:AVX) + # MSVC on 64 bit cannot select anything (should have changed with MSVC 2010) + _my_find(_enable_vector_unit_list "avx2" _found) + if(_found) + AddCompilerFlag("/arch:AVX2" CXX_FLAGS Vc_ARCHITECTURE_FLAGS CXX_RESULT _found) + endif() + if(NOT _found) + _my_find(_enable_vector_unit_list "avx" _found) + if(_found) + AddCompilerFlag("/arch:AVX" CXX_FLAGS Vc_ARCHITECTURE_FLAGS CXX_RESULT _found) + endif() + endif() + if(NOT _found) + _my_find(_enable_vector_unit_list "sse2" _found) + if(_found) + AddCompilerFlag("/arch:SSE2" CXX_FLAGS Vc_ARCHITECTURE_FLAGS) + endif() + endif() + foreach(_flag ${_enable_vector_unit_list}) + string(TOUPPER "${_flag}" _flag) + string(REPLACE "." "_" _flag "__${_flag}__") + add_definitions("-D${_flag}") + endforeach(_flag) + elseif(CMAKE_CXX_COMPILER MATCHES "/(icpc|icc)$") # ICC (on Linux) + set(OFA_map_knl "-xMIC-AVX512") + set(OFA_map_cannonlake "-xCORE-AVX512") + set(OFA_map_skylake-avx512 "-xCORE-AVX512") + set(OFA_map_skylake "-xCORE-AVX2") + set(OFA_map_broadwell "-xCORE-AVX2") + set(OFA_map_haswell "-xCORE-AVX2") + set(OFA_map_ivybridge "-xCORE-AVX-I") + set(OFA_map_sandybridge "-xAVX") + set(OFA_map_westmere "-xSSE4.2") + set(OFA_map_nehalem "-xSSE4.2") + set(OFA_map_penryn "-xSSSE3") + set(OFA_map_merom "-xSSSE3") + set(OFA_map_core2 "-xSSE3") + set(_ok FALSE) + foreach(arch ${_march_flag_list}) + if(DEFINED OFA_map_${arch}) + AddCompilerFlag(${OFA_map_${arch}} CXX_FLAGS Vc_ARCHITECTURE_FLAGS CXX_RESULT _ok) + if(_ok) + break() + endif() + endif() + endforeach() + if(NOT _ok) + # This is the Intel compiler, so SSE2 is a very reasonable baseline. + message(STATUS "Did not recognize the requested architecture flag, falling back to SSE2") + AddCompilerFlag("-xSSE2" CXX_FLAGS Vc_ARCHITECTURE_FLAGS) + endif() + else() # not MSVC and not ICC => GCC, Clang, Open64 + foreach(_flag ${_march_flag_list}) + AddCompilerFlag("-march=${_flag}" CXX_RESULT _good CXX_FLAGS Vc_ARCHITECTURE_FLAGS) + if(_good) + break() + endif(_good) + endforeach(_flag) + foreach(_flag ${_enable_vector_unit_list}) + AddCompilerFlag("-m${_flag}" CXX_RESULT _result) + if(_result) + set(_header FALSE) + if(_flag STREQUAL "sse3") + set(_header "pmmintrin.h") + elseif(_flag STREQUAL "ssse3") + set(_header "tmmintrin.h") + elseif(_flag STREQUAL "sse4.1") + set(_header "smmintrin.h") + elseif(_flag STREQUAL "sse4.2") + set(_header "smmintrin.h") + elseif(_flag STREQUAL "sse4a") + set(_header "ammintrin.h") + elseif(_flag STREQUAL "avx") + set(_header "immintrin.h") + elseif(_flag STREQUAL "avx2") + set(_header "immintrin.h") + elseif(_flag STREQUAL "fma4") + set(_header "x86intrin.h") + elseif(_flag STREQUAL "xop") + set(_header "x86intrin.h") + endif() + set(_resultVar "HAVE_${_header}") + string(REPLACE "." "_" _resultVar "${_resultVar}") + if(_header) + CHECK_INCLUDE_FILE_CXX("${_header}" ${_resultVar} "-m${_flag}") + if(NOT ${_resultVar}) + set(_useVar "USE_${_flag}") + string(TOUPPER "${_useVar}" _useVar) + string(REPLACE "." "_" _useVar "${_useVar}") + message(STATUS "disabling ${_useVar} because ${_header} is missing") + set(${_useVar} FALSE) + list(APPEND _disable_vector_unit_list "${_flag}") + endif() + endif() + if(NOT _header OR ${_resultVar}) + list(APPEND Vc_ARCHITECTURE_FLAGS "-m${_flag}") + endif() + endif() + endforeach(_flag) + foreach(_flag ${_disable_vector_unit_list}) + AddCompilerFlag("-mno-${_flag}" CXX_FLAGS Vc_ARCHITECTURE_FLAGS) + endforeach(_flag) + endif() + endif() +endmacro() diff --git a/dllsrc/CMakeLists.txt b/dllsrc/CMakeLists.txt new file mode 100644 index 000000000..189f31b7c --- /dev/null +++ b/dllsrc/CMakeLists.txt @@ -0,0 +1,16 @@ +add_library(j-dll OBJECT) +set_source_files_properties(jdllcomx.cpp PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO +) +target_compile_definitions(j-dll PRIVATE _JDLL) +target_compile_definitions(j-dll PRIVATE _CRT_SECURE_NO_WARNINGS) +target_sources(j-dll PRIVATE + jdll.c + jdll.h + jdllcom.h + jdllcomx.cpp + jdlltype.h + jexe.h +) diff --git a/jsrc/CMakeLists.txt b/jsrc/CMakeLists.txt new file mode 100644 index 000000000..21b6f7572 --- /dev/null +++ b/jsrc/CMakeLists.txt @@ -0,0 +1,231 @@ +add_compile_definitions(C_AVX=1 C_AVX2=1 EMU_AVX=1) +if(WIN32) + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) +endif() + +add_library(j SHARED) +set_target_properties(j PROPERTIES CXX_VISIBILITY_PRESET hidden) +set_source_files_properties(aes-ni.c PROPERTIES COMPILE_FLAGS -maes) +target_sources(j PRIVATE + a.h + aes-arm_table.h + aes-c.h + ar.h + avx2intrin-emu.h + avxintrin-emu.h + avxintrin-neon.h + cip_t.h + cipfloatmm_t.h + com_jsoftware_j_JInterface.h + cpuinfo.h + cr_t.h + crc32c.h + crc32ctables.h + d.h + dtoa.h + fnmatch.h + gemm.h + j.h + ja.h + jc.h + je.h + jerr.h + jfex.h + js.h + jt.h + jtype.h + jversion-x.h + jversion.h + jx_utils_jnative.h + linenoise.h + m.h + p.h + result.h + s.h + sse2neon.h + sse2neon2.h + va.h + vasm.h + vcomp.h + vdx.h + ve.h + vg.h + vgmerge.h + vgmergemincomp.h + vgsort.h + vgsortq.h + vq.h + vx.h + vz.h + w.h + x.h + xc.h + a.c + ab.c + aes-c.c + aes-ni.c + aes-sse2.c + af.c + ai.c + am.c + am1.c + amn.c + ao.c + ap.c + ar.c + as.c + au.c + c.c + ca.c + cc.c + cd.c + cf.c + cg.c + ch.c + cip.c + cl.c + cp.c + cpdtsp.c + cpuinfo.c + cr.c + crs.c + ct.c + cu.c + cv.c + cx.c + d.c + dc.c + dss.c + dstop.c + dsusp.c + dtoa.c + f.c + f2.c + fbu.c + gemm.c + i.c + io.c + j.c + jdlllic.c + k.c + m.c + mbx.c + p.c + pv.c + px.c + r.c + rl.c + rt.c + s.c + sc.c + sl.c + sn.c + t.c + u.c + v.c + v0.c + v1.c + v2.c + va1.c + va1ss.c + va2.c + va2s.c + va2ss.c + vamultsp.c + vb.c + vbang.c + vbit.c + vcant.c + vcat.c + vcatsp.c + vchar.c + vcomp.c + vcompsc.c + vd.c + vdx.c + ve.c + vf.c + vfft.c + vfrom.c + vfromsp.c + vg.c + vgauss.c + vgcomp.c + vgranking.c + vgsort.c + vgsp.c + vi.c + viavx.c + viix.c + visp.c + vm.c + vo.c + vp.c + vq.c + vrand.c + vrep.c + vs.c + vsb.c + vt.c + vu.c + vx.c + vz.c + w.c + wc.c + wn.c + ws.c + x.c + x15.c + xa.c + xaes.c + xb.c + xc.c + xcrc.c + xd.c + xf.c + xfmt.c + xh.c + xi.c + xl.c + xo.c + xs.c + xsha.c + xt.c + xu.c + crc32c.c +) + +add_library(j-blis OBJECT) +target_sources(j-blis PRIVATE + blis.h + blis/gemm_c-ref.c + blis/gemm_int-aarch64.c + blis/gemm_int-avx.c + blis/gemm_int-fma.c + blis/gemm_int-sse2.c + blis/gemm_vec-ref.c +) + +add_library(j-openssl-sha OBJECT) +target_compile_definitions(j-openssl-sha PRIVATE NO_SHA_ASM) +target_sources(j-openssl-sha PRIVATE + openssl/sha/md32_common.h + openssl/sha/md4.h + openssl/sha/md4_locl.h + openssl/sha/md5.h + openssl/sha/md5_locl.h + openssl/sha/openssl.h + openssl/sha/sha.h + openssl/sha/sha3.h + openssl/sha/sha_locl.h + openssl/sha/keccak1600.c + openssl/sha/md4_dgst.c + openssl/sha/md4_one.c + openssl/sha/md5_dgst.c + openssl/sha/md5_one.c + openssl/sha/openssl-util.c + openssl/sha/sha1_one.c + openssl/sha/sha256.c + openssl/sha/sha3.c + openssl/sha/sha512.c +) diff --git a/sleef/CMakeLists.txt b/sleef/CMakeLists.txt new file mode 100644 index 000000000..c417b0de9 --- /dev/null +++ b/sleef/CMakeLists.txt @@ -0,0 +1,36 @@ +if(WIN32) + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) +endif() + +add_library(j-sleef OBJECT) +target_include_directories(j-sleef PRIVATE src/arch src/common) +target_compile_definitions(j-sleef INTERFACE SLEEF=1) +target_compile_definitions(j-sleef PRIVATE SLEEF_STATIC_LIBS ENABLE_AVX2 DORENAME=1) +target_sources(j-sleef PRIVATE + include/sleef.h + src/arch/avxintrin-emu.h + src/arch/helperadvsimd.h + src/arch/helperavx.h + src/arch/helperavx2.h + src/arch/helpersse2.h + src/arch/helpervecext.h + src/common/arraymap.c + src/common/arraymap.h + src/common/common.c + src/common/common.h + src/common/misc.h + src/libm/dd.h + src/libm/estrin.h + src/libm/funcproto.h + src/libm/importsample.h + src/libm/norename.h + src/libm/rempitab.c + src/libm/rename.h + src/libm/renameadvsimd.h + src/libm/renameadvsimdnofma.h + src/libm/renameavx.h + src/libm/renameavx2.h + src/libm/renamesse2.h + src/libm/renamevecext.h + src/libm/sleefsimddp.c +) From 69341849b83b1808af0022a4ae17fe6e6df8cf28 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Thu, 5 Nov 2020 11:27:49 -0600 Subject: [PATCH 02/17] Add all warning controls and drop MSBuild support MSBuild has a bug right now, it cannot distinguish C and C++ sources. We cannot add flags based on that. --- CMakeLists.txt | 38 ++++++++++++++++++++++++++++++++++++++ dllsrc/CMakeLists.txt | 5 ----- sleef/CMakeLists.txt | 5 +---- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e191ce34..41810eb05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,9 @@ include(OptimizeForArchitecture) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) find_package(OpenMP) @@ -27,6 +30,41 @@ OptimizeForArchitecture() add_compile_options("$<$:${Vc_ARCHITECTURE_FLAGS}>") add_compile_options("$<$:${Vc_ARCHITECTURE_FLAGS}>") +add_compile_options($<$:-fno-strict-aliasing>) +add_compile_options($<$:-Werror>) +add_compile_options($<$:-Wextra>) +add_compile_options($<$:-Wno-unknown-warning-option>) +add_compile_options($<$:-Wno-unused-parameter>) +add_compile_options($<$:-Wno-unused-value>) +add_compile_options($<$:-Wno-unused-function>) +add_compile_options($<$:-Wno-unused-variable>) +add_compile_options($<$:-Wno-sign-compare>) +add_compile_options($<$:-Wno-cast-function-type>) +add_compile_options($<$:-Wno-clobbered>) +add_compile_options($<$:-Wno-empty-body>) +add_compile_options($<$:-Wno-parentheses>) +add_compile_options($<$:-Wno-pointer-sign>) +add_compile_options($<$:-Wno-format-overflow>) +add_compile_options($<$:-Wno-implicit-fallthrough>) +add_compile_options($<$:-Wno-missing-field-initializers>) +add_compile_options($<$:-Wno-shift-negative-value>) +add_compile_options($<$:-Wno-maybe-uninitialized>) +add_compile_options($<$:-Wno-uninitialized>) +add_compile_options($<$:-Wno-type-limits>) +add_compile_options($<$:-Wno-sometimes-uninitialized>) +add_compile_options($<$:-Wtautological-constant-out-of-range-compare>) +add_compile_options($<$:-Wuninitialized>) +add_compile_options($<$:-Wno-char-subscripts>) +add_compile_options($<$:-Wno-consumed>) +add_compile_options($<$:-Wno-implicit-float-conversion>) +add_compile_options($<$:-Wno-implicit-int-float-conversion>) +add_compile_options($<$:-Wno-int-in-bool-context>) +add_compile_options($<$:-Wno-string-plus-int>) +add_compile_options($<$:-Wno-missing-braces>) +add_compile_options($<$:-Wno-ignored-qualifiers>) +add_compile_options($<$:-Wno-unknown-pragmas>) +add_compile_options($<$:-Wno-delete-non-abstract-non-virtual-dtor>) + add_subdirectory(jsrc) add_subdirectory(sleef) add_subdirectory(base64) diff --git a/dllsrc/CMakeLists.txt b/dllsrc/CMakeLists.txt index 189f31b7c..02c5e74f1 100644 --- a/dllsrc/CMakeLists.txt +++ b/dllsrc/CMakeLists.txt @@ -1,9 +1,4 @@ add_library(j-dll OBJECT) -set_source_files_properties(jdllcomx.cpp PROPERTIES - CXX_STANDARD 17 - CXX_STANDARD_REQUIRED YES - CXX_EXTENSIONS NO -) target_compile_definitions(j-dll PRIVATE _JDLL) target_compile_definitions(j-dll PRIVATE _CRT_SECURE_NO_WARNINGS) target_sources(j-dll PRIVATE diff --git a/sleef/CMakeLists.txt b/sleef/CMakeLists.txt index c417b0de9..3bdc6dea5 100644 --- a/sleef/CMakeLists.txt +++ b/sleef/CMakeLists.txt @@ -1,11 +1,8 @@ -if(WIN32) - add_compile_definitions(_CRT_SECURE_NO_WARNINGS) -endif() - add_library(j-sleef OBJECT) target_include_directories(j-sleef PRIVATE src/arch src/common) target_compile_definitions(j-sleef INTERFACE SLEEF=1) target_compile_definitions(j-sleef PRIVATE SLEEF_STATIC_LIBS ENABLE_AVX2 DORENAME=1) +target_compile_definitions(j-sleef PRIVATE $<$:_CRT_SECURE_NO_WARNINGS>) target_sources(j-sleef PRIVATE include/sleef.h src/arch/avxintrin-emu.h From 23337cf7e80d502f4743a03ce6bfc323cb398c82 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Thu, 5 Nov 2020 21:43:52 +0000 Subject: [PATCH 03/17] Fix the build configuration for gcc under Linux --- CMakeLists.txt | 3 ++- dllsrc/CMakeLists.txt | 1 + jsrc/xl.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41810eb05..edfd8ea00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,6 @@ include(OptimizeForArchitecture) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) -set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) @@ -70,6 +69,8 @@ add_subdirectory(sleef) add_subdirectory(base64) add_subdirectory(dllsrc) +set_target_properties(j-blis j-openssl-sha j-sleef j-base64 PROPERTIES + POSITION_INDEPENDENT_CODE ON) target_link_libraries(j PRIVATE j-blis j-openssl-sha j-sleef j-base64) if(WIN32) target_link_libraries(j PRIVATE j-dll) diff --git a/dllsrc/CMakeLists.txt b/dllsrc/CMakeLists.txt index 02c5e74f1..80d206977 100644 --- a/dllsrc/CMakeLists.txt +++ b/dllsrc/CMakeLists.txt @@ -1,6 +1,7 @@ add_library(j-dll OBJECT) target_compile_definitions(j-dll PRIVATE _JDLL) target_compile_definitions(j-dll PRIVATE _CRT_SECURE_NO_WARNINGS) +set_target_properties(j-dll PROPERTIES EXCLUDE_FROM_ALL YES) target_sources(j-dll PRIVATE jdll.c jdll.h diff --git a/jsrc/xl.c b/jsrc/xl.c index 826ecd27f..6d63d51e4 100644 --- a/jsrc/xl.c +++ b/jsrc/xl.c @@ -17,6 +17,7 @@ static B jtdolock(J jt,B lk,F f,I i,I n){ASSERT(0,EVNONCE);} #if (SYS & SYS_UNIX) || (SY_WIN32 && SYS&SYS_DOS && !SY_WINCE) typedef long long INT64; #include +#include #define LOCK 1 #if (SYS & SYS_UNIX) #include From cfbd625885cd67f168a7a8a93a52d43e1e748997 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Thu, 5 Nov 2020 23:34:28 +0000 Subject: [PATCH 04/17] Enable all assembly --- CMakeLists.txt | 3 +- jsrc/CMakeLists.txt | 24 ------------ jsrc/openssl/sha/CMakeLists.txt | 68 +++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 25 deletions(-) create mode 100644 jsrc/openssl/sha/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index edfd8ea00..55045c21b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ elseif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_C_FLAGS) endif() project(j) -enable_language(C CXX) +enable_language(C CXX ASM) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) @@ -68,6 +68,7 @@ add_subdirectory(jsrc) add_subdirectory(sleef) add_subdirectory(base64) add_subdirectory(dllsrc) +add_subdirectory(jsrc/openssl/sha) set_target_properties(j-blis j-openssl-sha j-sleef j-base64 PROPERTIES POSITION_INDEPENDENT_CODE ON) diff --git a/jsrc/CMakeLists.txt b/jsrc/CMakeLists.txt index 21b6f7572..17956b3c4 100644 --- a/jsrc/CMakeLists.txt +++ b/jsrc/CMakeLists.txt @@ -205,27 +205,3 @@ target_sources(j-blis PRIVATE blis/gemm_int-sse2.c blis/gemm_vec-ref.c ) - -add_library(j-openssl-sha OBJECT) -target_compile_definitions(j-openssl-sha PRIVATE NO_SHA_ASM) -target_sources(j-openssl-sha PRIVATE - openssl/sha/md32_common.h - openssl/sha/md4.h - openssl/sha/md4_locl.h - openssl/sha/md5.h - openssl/sha/md5_locl.h - openssl/sha/openssl.h - openssl/sha/sha.h - openssl/sha/sha3.h - openssl/sha/sha_locl.h - openssl/sha/keccak1600.c - openssl/sha/md4_dgst.c - openssl/sha/md4_one.c - openssl/sha/md5_dgst.c - openssl/sha/md5_one.c - openssl/sha/openssl-util.c - openssl/sha/sha1_one.c - openssl/sha/sha256.c - openssl/sha/sha3.c - openssl/sha/sha512.c -) diff --git a/jsrc/openssl/sha/CMakeLists.txt b/jsrc/openssl/sha/CMakeLists.txt new file mode 100644 index 000000000..cfa645245 --- /dev/null +++ b/jsrc/openssl/sha/CMakeLists.txt @@ -0,0 +1,68 @@ +add_library(j-openssl-sha OBJECT) +target_sources(j-openssl-sha PRIVATE + md32_common.h + md4.h + md4_locl.h + md5.h + md5_locl.h + openssl.h + sha.h + sha3.h + sha_locl.h + keccak1600.c + md4_dgst.c + md4_one.c + md5_dgst.c + md5_one.c + openssl-util.c + sha1_one.c + sha256.c + sha3.c + sha512.c +) + +if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^(aarch64|arm)") + target_sources(j-openssl-sha PRIVATE + $<$:asm/keccak1600-armv8-elf.S> + $<$:asm/sha1-armv8-elf.S> + $<$:asm/sha256-armv8-elf.S> + $<$:asm/sha512-armv8-elf.S> + $<$:asm/keccak1600-armv4-elf.S> + $<$:asm/sha1-armv4-elf.S> + $<$:asm/sha256-armv4-elf.S> + $<$:asm/sha512-armv4-elf.S> + ) +elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + target_sources(j PRIVATE + $<$:../openssl-asm/keccak1600-x86_64-nasm.o> + $<$:../openssl-asm/sha1-x86_64-nasm.o> + $<$:../openssl-asm/sha256-x86_64-nasm.o> + $<$:../openssl-asm/sha512-x86_64-nasm.o> + $<$:../openssl-asm/keccak1600-mmx-nasm.o> + $<$:../openssl-asm/sha1-586-nasm.o> + $<$:../openssl-asm/sha256-586-nasm.o> + $<$:../openssl-asm/sha512-586-nasm.o> + ) +elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + target_sources(j-openssl-sha PRIVATE + $<$:asm/keccak1600-x86_64-elf.S> + $<$:asm/sha1-x86_64-elf.S> + $<$:asm/sha256-x86_64-elf.S> + $<$:asm/sha512-x86_64-elf.S> + $<$:asm/keccak1600-mmx-elf.S> + $<$:asm/sha1-586-elf.S> + $<$:asm/sha256-586-elf.S> + $<$:asm/sha512-586-elf.S> + ) +elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + target_sources(j-openssl-sha PRIVATE + $<$:asm/keccak1600-x86_64-macho.S> + $<$:asm/sha1-x86_64-macho.S> + $<$:asm/sha256-x86_64-macho.S> + $<$:asm/sha512-x86_64-macho.S> + $<$:asm/keccak1600-mmx-macho.S> + $<$:asm/sha1-586-macho.S> + $<$:asm/sha256-586-macho.S> + $<$:asm/sha512-586-macho.S> + ) +endif() From 7fc028878ea17714aa4353bd19a55709a827a01f Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Fri, 6 Nov 2020 10:31:25 -0600 Subject: [PATCH 05/17] Build JEXEServer if we are a subproject --- CMakeLists.txt | 10 ++++++++-- dllsrc/CMakeLists.txt | 2 +- jsrc/CMakeLists.txt | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 55045c21b..8e1a6224d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,10 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) include(OptimizeForArchitecture) +if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + set(BUILD_SHARED_LIBS ON) +endif() + set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 17) @@ -70,8 +74,10 @@ add_subdirectory(base64) add_subdirectory(dllsrc) add_subdirectory(jsrc/openssl/sha) -set_target_properties(j-blis j-openssl-sha j-sleef j-base64 PROPERTIES - POSITION_INDEPENDENT_CODE ON) +if(BUILD_SHARED_LIBS) + set_target_properties(j-blis j-openssl-sha j-sleef j-base64 PROPERTIES + POSITION_INDEPENDENT_CODE ON) +endif() target_link_libraries(j PRIVATE j-blis j-openssl-sha j-sleef j-base64) if(WIN32) target_link_libraries(j PRIVATE j-dll) diff --git a/dllsrc/CMakeLists.txt b/dllsrc/CMakeLists.txt index 80d206977..2a13d1928 100644 --- a/dllsrc/CMakeLists.txt +++ b/dllsrc/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(j-dll OBJECT) -target_compile_definitions(j-dll PRIVATE _JDLL) +target_compile_definitions(j-dll PRIVATE $<$:_JDLL>) target_compile_definitions(j-dll PRIVATE _CRT_SECURE_NO_WARNINGS) set_target_properties(j-dll PROPERTIES EXCLUDE_FROM_ALL YES) target_sources(j-dll PRIVATE diff --git a/jsrc/CMakeLists.txt b/jsrc/CMakeLists.txt index 17956b3c4..3b20127fb 100644 --- a/jsrc/CMakeLists.txt +++ b/jsrc/CMakeLists.txt @@ -3,7 +3,7 @@ if(WIN32) add_compile_definitions(_CRT_SECURE_NO_WARNINGS) endif() -add_library(j SHARED) +add_library(j) set_target_properties(j PROPERTIES CXX_VISIBILITY_PRESET hidden) set_source_files_properties(aes-ni.c PROPERTIES COMPILE_FLAGS -maes) target_sources(j PRIVATE From bee31df50a0fa996d3c6257bdb281dc576a701fe Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Fri, 6 Nov 2020 11:56:56 -0600 Subject: [PATCH 06/17] Tweak warnings and the rest of the flags --- CMakeLists.txt | 10 +++++++--- dllsrc/jdllcomx.cpp | 1 - jsrc/CMakeLists.txt | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e1a6224d..b20d2322c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,12 @@ add_compile_options("$<$:${Vc_ARCHITECTURE_FLAGS}>") add_compile_options($<$:-fno-strict-aliasing>) add_compile_options($<$:-Werror>) -add_compile_options($<$:-Wextra>) +if("${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC") + add_compile_options($<$:/W3>) + add_compile_options($<$:/Zc:strictStrings>) +else() + add_compile_options($<$:-Wextra>) +endif() add_compile_options($<$:-Wno-unknown-warning-option>) add_compile_options($<$:-Wno-unused-parameter>) add_compile_options($<$:-Wno-unused-value>) @@ -46,7 +51,7 @@ add_compile_options($<$:-Wno-cast-function-type>) add_compile_options($<$:-Wno-clobbered>) add_compile_options($<$:-Wno-empty-body>) add_compile_options($<$:-Wno-parentheses>) -add_compile_options($<$:-Wno-pointer-sign>) +add_compile_options($<$:-Wno-pointer-sign>) add_compile_options($<$:-Wno-format-overflow>) add_compile_options($<$:-Wno-implicit-fallthrough>) add_compile_options($<$:-Wno-missing-field-initializers>) @@ -64,7 +69,6 @@ add_compile_options($<$:-Wno-implicit-in add_compile_options($<$:-Wno-int-in-bool-context>) add_compile_options($<$:-Wno-string-plus-int>) add_compile_options($<$:-Wno-missing-braces>) -add_compile_options($<$:-Wno-ignored-qualifiers>) add_compile_options($<$:-Wno-unknown-pragmas>) add_compile_options($<$:-Wno-delete-non-abstract-non-virtual-dtor>) diff --git a/dllsrc/jdllcomx.cpp b/dllsrc/jdllcomx.cpp index 0bd45a40d..2a786bd04 100644 --- a/dllsrc/jdllcomx.cpp +++ b/dllsrc/jdllcomx.cpp @@ -270,7 +270,6 @@ STDMETHODIMP CJServer::Invoke(DISPID dispID, REFIID riid { HRESULT hr; ITypeInfo *pTI; - LANGID langID=PRIMARYLANGID(lcid); if (IID_NULL!=riid) return DISP_E_UNKNOWNINTERFACE; hr=GetTypeInfo(0, lcid, &pTI); diff --git a/jsrc/CMakeLists.txt b/jsrc/CMakeLists.txt index 3b20127fb..8161206bc 100644 --- a/jsrc/CMakeLists.txt +++ b/jsrc/CMakeLists.txt @@ -1,4 +1,4 @@ -add_compile_definitions(C_AVX=1 C_AVX2=1 EMU_AVX=1) +add_compile_definitions(C_NA=0 C_AVX=1 C_AVX2=1 EMU_AVX=1) if(WIN32) add_compile_definitions(_CRT_SECURE_NO_WARNINGS) endif() From b5ea503e57d6bc02ce51c1881e820e9b893e1211 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Fri, 6 Nov 2020 16:37:20 -0600 Subject: [PATCH 07/17] Refactor j target and build tsdll & jconsole --- CMakeLists.txt | 7 ++- cmake/FindStandardMathLibrary.cmake | 68 +++++++++++++++++++++++++++++ dllsrc/CMakeLists.txt | 3 +- jsrc/CMakeLists.txt | 64 ++++++++++++++++++++++----- 4 files changed, 127 insertions(+), 15 deletions(-) create mode 100755 cmake/FindStandardMathLibrary.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index b20d2322c..ce176a005 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,10 +22,13 @@ endif() set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_VISIBILITY_PRESET hidden) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +find_package(StandardMathLibrary REQUIRED) find_package(OpenMP) set(TARGET_ARCHITECTURE "skylake" CACHE STRING "CPU architecture") @@ -79,10 +82,10 @@ add_subdirectory(dllsrc) add_subdirectory(jsrc/openssl/sha) if(BUILD_SHARED_LIBS) - set_target_properties(j-blis j-openssl-sha j-sleef j-base64 PROPERTIES + set_target_properties(j-openssl-sha j-sleef j-base64 PROPERTIES POSITION_INDEPENDENT_CODE ON) endif() -target_link_libraries(j PRIVATE j-blis j-openssl-sha j-sleef j-base64) +target_link_libraries(j PRIVATE j-openssl-sha j-sleef j-base64) if(WIN32) target_link_libraries(j PRIVATE j-dll) target_sources(j PRIVATE dllsrc/jdll.def dllsrc/jdll.rc dllsrc/jdll.tlb) diff --git a/cmake/FindStandardMathLibrary.cmake b/cmake/FindStandardMathLibrary.cmake new file mode 100755 index 000000000..c01b1df13 --- /dev/null +++ b/cmake/FindStandardMathLibrary.cmake @@ -0,0 +1,68 @@ +# - Try to find how to link to the standard math library, if anything at all is needed to do. +# On most platforms this is automatic, but for example it's not automatic on QNX. +# +# Once done this will define +# +# STANDARD_MATH_LIBRARY_FOUND - we found how to successfully link to the standard math library +# STANDARD_MATH_LIBRARY - the name of the standard library that one has to link to. +# -- this will be left empty if it's automatic (most platforms). +# -- this will be set to "m" on platforms where one must explicitly +# pass the "-lm" linker flag. +# +# Copyright (c) 2010 Benoit Jacob +# 2020 Susi Lehtola +# Redistribution and use is allowed according to the terms of the 2-clause BSD license. + + +include(CheckCSourceCompiles) + +# a little test program for c math functions. + +# We read in the arguments from standard input to avoid the compiler optimizing away the calls +set(find_standard_math_library_test_program +" +#include +int main(int argc, char **argv){ +return fetestexcept(argc); +}") + +# first try compiling/linking the test program without any linker flags + +set(CMAKE_REQUIRED_FLAGS "") +set(CMAKE_REQUIRED_LIBRARIES "") +CHECK_C_SOURCE_COMPILES( + "${find_standard_math_library_test_program}" + standard_math_library_linked_to_automatically +) + +if(standard_math_library_linked_to_automatically) + + # the test program linked successfully without any linker flag. + set(STANDARD_MATH_LIBRARY "") + set(STANDARD_MATH_LIBRARY_FOUND TRUE) + +else() + + # the test program did not link successfully without any linker flag. + # This is a very uncommon case that so far we only saw on QNX. The next try is the + # standard name 'm' for the standard math library. + + set(CMAKE_REQUIRED_LIBRARIES "m") + CHECK_C_SOURCE_COMPILES( + "${find_standard_math_library_test_program}" + standard_math_library_linked_to_as_m) + + if(standard_math_library_linked_to_as_m) + + # the test program linked successfully when linking to the 'm' library + set(STANDARD_MATH_LIBRARY "m") + set(STANDARD_MATH_LIBRARY_FOUND TRUE) + + else() + + # the test program still doesn't link successfully + set(STANDARD_MATH_LIBRARY_FOUND FALSE) + + endif() + +endif() diff --git a/dllsrc/CMakeLists.txt b/dllsrc/CMakeLists.txt index 2a13d1928..26b0b9230 100644 --- a/dllsrc/CMakeLists.txt +++ b/dllsrc/CMakeLists.txt @@ -1,7 +1,6 @@ -add_library(j-dll OBJECT) +add_library(j-dll OBJECT EXCLUDE_FROM_ALL) target_compile_definitions(j-dll PRIVATE $<$:_JDLL>) target_compile_definitions(j-dll PRIVATE _CRT_SECURE_NO_WARNINGS) -set_target_properties(j-dll PROPERTIES EXCLUDE_FROM_ALL YES) target_sources(j-dll PRIVATE jdll.c jdll.h diff --git a/jsrc/CMakeLists.txt b/jsrc/CMakeLists.txt index 8161206bc..9cfeff250 100644 --- a/jsrc/CMakeLists.txt +++ b/jsrc/CMakeLists.txt @@ -1,10 +1,7 @@ -add_compile_definitions(C_NA=0 C_AVX=1 C_AVX2=1 EMU_AVX=1) -if(WIN32) - add_compile_definitions(_CRT_SECURE_NO_WARNINGS) -endif() - add_library(j) -set_target_properties(j PROPERTIES CXX_VISIBILITY_PRESET hidden) +target_compile_definitions(j PRIVATE C_NA=0 C_AVX=1 C_AVX2=1 EMU_AVX=1) +target_compile_definitions(j PRIVATE $<$:_CRT_SECURE_NO_WARNINGS>) +target_link_libraries(j PRIVATE ${STANDARD_MATH_LIBRARY}) set_source_files_properties(aes-ni.c PROPERTIES COMPILE_FLAGS -maes) target_sources(j PRIVATE a.h @@ -16,7 +13,6 @@ target_sources(j PRIVATE avxintrin-neon.h cip_t.h cipfloatmm_t.h - com_jsoftware_j_JInterface.h cpuinfo.h cr_t.h crc32c.h @@ -34,9 +30,7 @@ target_sources(j PRIVATE js.h jt.h jtype.h - jversion-x.h jversion.h - jx_utils_jnative.h linenoise.h m.h p.h @@ -195,8 +189,9 @@ target_sources(j PRIVATE crc32c.c ) -add_library(j-blis OBJECT) -target_sources(j-blis PRIVATE +configure_file(jversion-x.h ${CMAKE_CURRENT_SOURCE_DIR}/jversion.h COPYONLY) + +target_sources(j PRIVATE blis.h blis/gemm_c-ref.c blis/gemm_int-aarch64.c @@ -205,3 +200,50 @@ target_sources(j-blis PRIVATE blis/gemm_int-sse2.c blis/gemm_vec-ref.c ) + +if(NOT BUILD_SHARED_LIBS) + return() +endif() + +add_library(tsdll SHARED) +target_link_libraries(tsdll PRIVATE ${STANDARD_MATH_LIBRARY}) +target_sources(tsdll PRIVATE + tsdll.c + ../makevs/tsdll/tsdll.def +) + +add_library(linenoise OBJECT EXCLUDE_FROM_ALL) +target_compile_definitions(linenoise INTERFACE USE_LINENOISE) +target_compile_definitions(linenoise PUBLIC $<$:_CRT_SECURE_NO_WARNINGS>) +target_sources(linenoise PRIVATE + linenoise.h + linenoise.c +) + +add_executable(jconsole) +target_compile_definitions(jconsole PRIVATE READLINE) +if(NOT UNIX OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "^(aarch64|arm)") + target_link_libraries(jconsole PRIVATE linenoise) +endif() +if("${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC") + target_link_options(jconsole PRIVATE /STACK:0x1000000) +endif() +target_link_libraries(jconsole PRIVATE ${CMAKE_DL_LIBS}) +target_sources(jconsole PRIVATE + jconsole.c + jeload.h + jeload.c + jlib.h + ../makevs/jconsole/jconsole.rc + ../makevs/jconsole/resource1.h + ../makevs/jconsole/jgray.ico +) + +file(TO_NATIVE_PATH "${PROJECT_SOURCE_DIR}/jlibrary/bin" J_BINPATH) +file(TO_NATIVE_PATH "/profile.ijs" J_PROFILE_SCRIPT) +file(GENERATE + OUTPUT "$<${is_multi_config}:$/>profile.ijs" + CONTENT "NB. loaded under debug +BINPATH_z_=: '${J_BINPATH}' +0!:0 Date: Sat, 7 Nov 2020 13:22:13 -0600 Subject: [PATCH 08/17] Default to OpenMP build --- CMakeLists.txt | 6 + cmake/FindOpenMP.cmake | 605 +++++++++++++++++++++++++++++++++++++++++ jsrc/CMakeLists.txt | 13 + 3 files changed, 624 insertions(+) create mode 100644 cmake/FindOpenMP.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ce176a005..e3b028bad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,12 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_VISIBILITY_PRESET hidden) +if("${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC") + get_filename_component(_cl_bin_dir ${CMAKE_C_COMPILER} DIRECTORY) + file(TO_CMAKE_PATH "${_cl_bin_dir}/../lib/libomp.lib" OpenMP_libomp_LIBRARY) + file(TO_CMAKE_PATH "${_cl_bin_dir}/libomp.dll" OpenMP_libomp_DLL) +endif() + find_package(StandardMathLibrary REQUIRED) find_package(OpenMP) diff --git a/cmake/FindOpenMP.cmake b/cmake/FindOpenMP.cmake new file mode 100644 index 000000000..f5a7e6679 --- /dev/null +++ b/cmake/FindOpenMP.cmake @@ -0,0 +1,605 @@ +# 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. + +Variables +^^^^^^^^^ + +The module exposes the components ``C``, ``CXX``, and ``Fortran``. +Each of these controls the various languages to search OpenMP support for. + +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 ```` is one of C, CXX, or Fortran: + +``OpenMP__FOUND`` + Variable indicating if OpenMP support for ```` was detected. +``OpenMP__FLAGS`` + OpenMP compiler flags for ````, separated by spaces. +``OpenMP__INCLUDE_DIRS`` + Directories that must be added to the header search path for ```` + when using OpenMP. + +For linking with OpenMP code written in ````, the following +variables are provided: + +``OpenMP__LIB_NAMES`` + :ref:`;-list ` of libraries for OpenMP programs for ````. +``OpenMP__LIBRARY`` + Location of the individual libraries needed for OpenMP support in ````. +``OpenMP__LIBRARIES`` + A list of libraries needed to link with OpenMP code written in ````. + +Additionally, the module provides :prop_tgt:`IMPORTED` targets: + +``OpenMP::OpenMP_`` + Target for using OpenMP from ````. + +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__SPEC_DATE`` + Date of the OpenMP specification implemented by the ```` compiler. +``OpenMP__VERSION_MAJOR`` + Major version of OpenMP implemented by the ```` compiler. +``OpenMP__VERSION_MINOR`` + Minor version of OpenMP implemented by the ```` compiler. +``OpenMP__VERSION`` + OpenMP version implemented by the ```` 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 ```` 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__INCLUDE_DIR`` cache variable. +Note that this variable is an _input_ control to the module. Project code +should use the ``OpenMP__INCLUDE_DIRS`` _output_ variable if it needs +to know what include directories are needed. +#]=======================================================================] + +cmake_policy(PUSH) +cmake_policy(SET CMP0012 NEW) # if() recognizes numbers and booleans +cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced +cmake_policy(SET CMP0057 NEW) # if IN_LIST + +function(_OPENMP_FLAG_CANDIDATES LANG) + if(NOT OpenMP_${LANG}_FLAG) + unset(OpenMP_FLAG_CANDIDATES) + + set(OMP_FLAG_GNU "-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() + set(OMP_FLAG_MSVC "-openmp") + set(OMP_FLAG_PathScale "-openmp") + set(OMP_FLAG_NAG "-openmp") + set(OMP_FLAG_Absoft "-openmp") + set(OMP_FLAG_PGI "-mp") + set(OMP_FLAG_Flang "-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") + + # If we know the correct flags, use those + if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}) + set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}") + # Fall back to reasonable default tries otherwise + else() + 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 +int main(void) { +#ifdef _OPENMP + omp_get_max_threads(); + return 0; +#elif defined(__HIP_DEVICE_COMPILE__) + return 0; +#else + breaks_on_purpose +#endif +} +") + +# 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 + " +) + +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(CMakeParseImplicitLinkInfo) + +function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) + _OPENMP_FLAG_CANDIDATES("${LANG}") + _OPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenMPTryFlag _OPENMP_TEST_SRC) + + unset(OpenMP_VERBOSE_COMPILE_OPTIONS) + separate_arguments(OpenMP_VERBOSE_OPTIONS NATIVE_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}") + foreach(_VERBOSE_OPTION IN LISTS OpenMP_VERBOSE_OPTIONS) + if(NOT _VERBOSE_OPTION MATCHES "^-Wl,") + list(APPEND OpenMP_VERBOSE_COMPILE_OPTIONS ${_VERBOSE_OPTION}) + endif() + endforeach() + + foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES) + set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}") + if(OpenMP_VERBOSE_COMPILE_OPTIONS) + string(APPEND OPENMP_FLAGS_TEST " ${OpenMP_VERBOSE_COMPILE_OPTIONS}") + endif() + string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}") + try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} + CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" + LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} + OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT + ) + + if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}) + 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) + 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 "${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_DEFAULT_PATH + ) + endif() + mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY) + list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB_PLAIN}) + endif() + endforeach() + 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") + + # 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} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} + CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" + LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY} + OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT + ) + 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} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} + CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" + "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}" + LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY} + OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT + ) + 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} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} + CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" + LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY} + OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT + ) + 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() + else() + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Detecting ${LANG} OpenMP failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n") + endif() + set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE) + set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE) + endforeach() + + unset(OpenMP_VERBOSE_COMPILE_OPTIONS) +endfunction() + +set(OpenMP_C_CXX_CHECK_VERSION_SOURCE +" +#include +#include +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_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC) + + 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} "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}" + CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}" ${_includeDirFlags} + COPY_FILE ${BIN_FILE} + OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT) + + 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() + else() + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Detecting ${LANG} OpenMP version failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n") + endif() +endfunction() + +macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG) + set(OpenMP_SPEC_DATE_MAP + # 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) + 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) + set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}" + CACHE STRING "${LANG} compiler flags for OpenMP parallelization" FORCE) + set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}" + CACHE STRING "${LANG} compiler libraries for OpenMP parallelization" FORCE) + 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() + + 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" "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() + + 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() + set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'") + endif() +endif() + +if(NOT OpenMP_FIND_COMPONENTS) + set(OpenMP_FINDLIST C CXX Fortran) +else() + set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS}) +endif() + +unset(_OpenMP_MIN_VERSION) + +include(FindPackageHandleStandardArgs) + +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) + separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}") + set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY + INTERFACE_COMPILE_OPTIONS "$<$:${_OpenMP_${LANG}_OPTIONS}>") + unset(_OpenMP_${LANG}_OPTIONS) + endif() + if(OpenMP_${LANG}_INCLUDE_DIRS) + set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "$") + 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 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) + +set(OPENMP_FOUND ${OpenMP_FOUND}) + +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_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) diff --git a/jsrc/CMakeLists.txt b/jsrc/CMakeLists.txt index 9cfeff250..2a5f5a236 100644 --- a/jsrc/CMakeLists.txt +++ b/jsrc/CMakeLists.txt @@ -191,6 +191,19 @@ target_sources(j PRIVATE configure_file(jversion-x.h ${CMAKE_CURRENT_SOURCE_DIR}/jversion.h COPYONLY) +if(OpenMP_C_FOUND) + target_link_libraries(j PRIVATE OpenMP::OpenMP_C) + + if(DEFINED OpenMP_libomp_DLL) + add_custom_command( + TARGET j POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${OpenMP_libomp_DLL} + "${CMAKE_CURRENT_BINARY_DIR}$<${is_multi_config}:/$>" + ) + endif() +endif() + target_sources(j PRIVATE blis.h blis/gemm_c-ref.c From 72634cf5c53b4da6f73357f8b9a8e041aa61e67f Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Sun, 8 Nov 2020 00:33:37 -0600 Subject: [PATCH 09/17] Run unit tests with ctest --- CMakeLists.txt | 2 + jsrc/CMakeLists.txt | 7 - test/CMakeLists.txt | 433 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 435 insertions(+), 7 deletions(-) create mode 100644 test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index e3b028bad..df8528975 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ enable_language(C CXX ASM) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) +include(CTest) include(OptimizeForArchitecture) if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) @@ -90,6 +91,7 @@ add_subdirectory(jsrc/openssl/sha) if(BUILD_SHARED_LIBS) set_target_properties(j-openssl-sha j-sleef j-base64 PROPERTIES POSITION_INDEPENDENT_CODE ON) + add_subdirectory(test) endif() target_link_libraries(j PRIVATE j-openssl-sha j-sleef j-base64) if(WIN32) diff --git a/jsrc/CMakeLists.txt b/jsrc/CMakeLists.txt index 2a5f5a236..313e94c9a 100644 --- a/jsrc/CMakeLists.txt +++ b/jsrc/CMakeLists.txt @@ -218,13 +218,6 @@ if(NOT BUILD_SHARED_LIBS) return() endif() -add_library(tsdll SHARED) -target_link_libraries(tsdll PRIVATE ${STANDARD_MATH_LIBRARY}) -target_sources(tsdll PRIVATE - tsdll.c - ../makevs/tsdll/tsdll.def -) - add_library(linenoise OBJECT EXCLUDE_FROM_ALL) target_compile_definitions(linenoise INTERFACE USE_LINENOISE) target_compile_definitions(linenoise PUBLIC $<$:_CRT_SECURE_NO_WARNINGS>) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 000000000..0d3ac8a0c --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,433 @@ +if(BUILD_TESTING) + add_library(tsdll SHARED) + target_link_libraries(tsdll PRIVATE ${STANDARD_MATH_LIBRARY}) + target_sources(tsdll PRIVATE + ../jsrc/tsdll.c + ../makevs/tsdll/tsdll.def + ) +endif() + +set(test_cases + g0 + g000 + g000a + g000i + g000p + g000s + g001 + g010 + g010a + g010i + g010p + g010s + g011 + g011a + g011i + g011p + g011s + g012 + g012a + g012i + g012p + g012s + g020 + g020a + g020i + g020p + g020s + g021 + g021a + g021i + g021p + g021s + g022 + g022a + g022i + g022p + g022s + g030 + g030a + g031 + g032 + g0a + g0x + g100 + g100a + g100i + g100p + g100s + g101 + g101a + g101i + g101p + g101s + g102 + g102a + g102i + g102p + g102s + g110 + g110a + g110i + g110p + g110s + g111 + g111a + g111i + g111p + g111s + g112 + g112a + g112i + g112p + g112s + g120 + g120a + g120i + g120p + g120s + g121 + g122 + g122a + g128x + g128x3 + g128x5 + g128x6 + g128x7 + g130 + g130a + g130i + g130p + g131 + g132 + g13x + g15x + # g18x + g1x + g1x0 + g1x1 + g1x11 + g1x12 + g1x2 + g1x20 + g1x3 + g1x30 + g1x4 + g1x43 + g1x5 + g1x55 + g1x7 + g200 + g200a + g200i + g200m + g200p + g201 + g202 + g202b + g210 + g210a + g211 + g212 + g220 + g220t + g221 + g222 + g222a + g222i + g222p + g222s + g230 + g230a + g230i + g230p + g230s + g231 + g232 + g2x + g300 + g300b + g300t + g301 + g310 + g310a + g310names + g310r + g310t + g311 + g312 + g320 + g320ip + g320ipt + g321 + g321t + g322 + g330 + g330f + g330t + g331 + g331bx + g331col + g331ins + g331ps + g331sp + g332 + g332s + g3x + g3x4 + g3x5 + g3x6 + g400 + g400e + g401 + g402 + g410 + g410a + g410i + g410p + g410s + g411 + g412 + # g420 + g420ce + g420fg + g420r2 + g420stch + g420t + g421 + g421c + g421d + g421e + g421i + g421p + g421t + g422 + g422os + g422rk + g422sort + g422sort1 + g422tao + g430 + g430a2 + g430avg + g430b + g430d + g430fin + g430inv + g431 + g431a + g432 + g4x + g4x5 + g500 + g502 + g510 + g520 + g520b + g520p + g521 + g522 + g530 + g530t + g531 + g532 + g5x + g5x0 + g5x1 + g5x2 + g5x30 + g5x4 + g5x5 + g5x6 + g5x7 + g600 + g600ip + g601 + g602 + g610 + g612 + g620 + g620a + g621 + g622 + g630 + g631 + g631c + g632 + g640 + g640k + g640r + g641 + g6x + g6x0 + g6x14 + g7x + g7x5 + g7x6 + g8x + g9x + g9x40 + ga + gassert + gb + gbpar + gc + gchar + gcompsc + gct + gctrl + gd + gddot + gdll + gdll_df + ge + gebar + gesc + gf + gfor + gft + ggoto + gh + gi + gi0 + gibs + gibst + gicap + gicap2 + gico + giconv + gif + gimaxmin + gintdiv + gintg + gintovfl + giph + gipht + giscode + git + gix + gj + glco + gldot + glocale + gmean + gmemo + gmmf + gmmf1s + gmmf1u + gmmf1w + gmnom + gn + gnan + gnum + gnvv + go + goi + goox + gop + gos + gparse + gpco + gpco2 + gpcoinv + gpdd + gpi + gpick + gpoly + gq + gq101 + gq132 + gq201 + gqco + gqnonrat + gr + gr1 + grefcount + gs + gsco + gsco1 + gsco1u + gsco1w + gsco2 + gsco2u + gsco2w + gscou + gsdot + gselect + gsp + gsp0 + gsp000 + gsp1 + gsp100 + gsp101 + gsp102 + gsp110 + gsp111 + gsp112 + gsp120 + gsp122 + gsp130 + gsp2 + gsp221 + gsp222 + gsp231 + gsp320 + gsp321 + gsp322 + gsp331 + gsp400 + gsp410 + gsp412 + gsp420 + gsp421 + gsp422 + gsp431 + gsp432 + gsp520 + gsp520sd + gsp520ss + gsp521 + gsp530i + gsp530l + gsp530n + gsp531 + gsp5x5 + gsp6 + gsp600 + gsp600a + gspi + gspj + gspo + gspr + gspx + gss + gstack + gt + gthrow + gtrain + gtry + gu + gu0 + gunderai + gwhile + gx + gx132 + gxco + gxco1 + gxco2 + gxinf +) + +foreach(test_name IN LISTS test_cases) + file(GENERATE + OUTPUT "$<${is_multi_config}:$/>${test_name}.ijs" + CONTENT "0!:0 <'${CMAKE_CURRENT_SOURCE_DIR}/tsu.ijs' +LIBTSDLL=:'$ ' +exit -.&(0!:3) + ) + add_test( + NAME ${test_name} + COMMAND jconsole "$<${is_multi_config}:$/>${test_name}.ijs" + ) +endforeach() From 4a24ff941fd34f3c807a1a84c586837b1b417547 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Sun, 8 Nov 2020 13:06:15 -0600 Subject: [PATCH 10/17] Disable CRT warnings on all jsrc targets --- jsrc/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jsrc/CMakeLists.txt b/jsrc/CMakeLists.txt index 313e94c9a..68e6861ab 100644 --- a/jsrc/CMakeLists.txt +++ b/jsrc/CMakeLists.txt @@ -1,6 +1,9 @@ +if(WIN32) + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) +endif() + add_library(j) target_compile_definitions(j PRIVATE C_NA=0 C_AVX=1 C_AVX2=1 EMU_AVX=1) -target_compile_definitions(j PRIVATE $<$:_CRT_SECURE_NO_WARNINGS>) target_link_libraries(j PRIVATE ${STANDARD_MATH_LIBRARY}) set_source_files_properties(aes-ni.c PROPERTIES COMPILE_FLAGS -maes) target_sources(j PRIVATE @@ -220,7 +223,6 @@ endif() add_library(linenoise OBJECT EXCLUDE_FROM_ALL) target_compile_definitions(linenoise INTERFACE USE_LINENOISE) -target_compile_definitions(linenoise PUBLIC $<$:_CRT_SECURE_NO_WARNINGS>) target_sources(linenoise PRIVATE linenoise.h linenoise.c From 12ebdde7a2d29211b323f4918fd4ca43ad7a8926 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Sun, 8 Nov 2020 13:07:07 -0600 Subject: [PATCH 11/17] Build jnative --- CMakeLists.txt | 1 + jsrc/CMakeLists.txt | 13 +++++++++++++ jsrc/andjnative.c | 4 ++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df8528975..6e24013c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,7 @@ endif() find_package(StandardMathLibrary REQUIRED) find_package(OpenMP) +find_package(JNI) set(TARGET_ARCHITECTURE "skylake" CACHE STRING "CPU architecture") OptimizeForArchitecture() diff --git a/jsrc/CMakeLists.txt b/jsrc/CMakeLists.txt index 68e6861ab..df82c01f7 100644 --- a/jsrc/CMakeLists.txt +++ b/jsrc/CMakeLists.txt @@ -255,3 +255,16 @@ file(GENERATE BINPATH_z_=: '${J_BINPATH}' 0!:0 -#ifdef MMSC_VER +#ifdef _MSC_VER #pragma warning(disable: 4244) #else #include @@ -283,7 +283,7 @@ JNIEXPORT void JNICALL Java_com_jsoftware_j_JInterface_JSetEnv LOGD("JSetEnv"); const char* key = (*env)->GetStringUTFChars(env, jkey, 0); const char* val = (*env)->GetStringUTFChars(env, jval, 0); -#ifdef MMSC_VER +#ifdef _MSC_VER _putenv_s(key,val); #else setenv(key,val,0); From 47c97c70ed05cc0a7e543ca9ac957a3457a40fc0 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Mon, 8 Feb 2021 23:43:34 +0000 Subject: [PATCH 12/17] Warn for unknown warning options --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e24013c6..8259966dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,6 @@ if("${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC") else() add_compile_options($<$:-Wextra>) endif() -add_compile_options($<$:-Wno-unknown-warning-option>) add_compile_options($<$:-Wno-unused-parameter>) add_compile_options($<$:-Wno-unused-value>) add_compile_options($<$:-Wno-unused-function>) From 8c0b3424cb8bea513513a6379001911f860ad241 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Wed, 10 Feb 2021 07:47:17 +0000 Subject: [PATCH 13/17] Correctly order -Wuninitialized and their siblings --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8259966dc..1f42992e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,12 +66,12 @@ add_compile_options($<$:-Wno-format-overflow>) add_compile_options($<$:-Wno-implicit-fallthrough>) add_compile_options($<$:-Wno-missing-field-initializers>) add_compile_options($<$:-Wno-shift-negative-value>) +add_compile_options($<$:-Wuninitialized>) add_compile_options($<$:-Wno-maybe-uninitialized>) -add_compile_options($<$:-Wno-uninitialized>) add_compile_options($<$:-Wno-type-limits>) +add_compile_options($<$:-Wuninitialized>) add_compile_options($<$:-Wno-sometimes-uninitialized>) add_compile_options($<$:-Wtautological-constant-out-of-range-compare>) -add_compile_options($<$:-Wuninitialized>) add_compile_options($<$:-Wno-char-subscripts>) add_compile_options($<$:-Wno-consumed>) add_compile_options($<$:-Wno-implicit-float-conversion>) From c0acc7b44acae4ad4e6aad5fad35446cc9456ece Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Wed, 10 Feb 2021 04:40:18 +0000 Subject: [PATCH 14/17] Fix always_inline warning in gcc The always_inline attribute does not imply C99 inline in some versions of GCC. See also https://bugzilla.mozilla.org/show_bug.cgi?id=697810 --- sleef/src/common/misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sleef/src/common/misc.h b/sleef/src/common/misc.h index b0c07e88c..9014862c0 100644 --- a/sleef/src/common/misc.h +++ b/sleef/src/common/misc.h @@ -257,7 +257,7 @@ typedef union { #else #define CONST #endif -#define INLINE __attribute__((always_inline)) +#define INLINE __attribute__((always_inline)) inline #if defined(__MINGW32__) || defined(__MINGW64__) || defined(__CYGWIN__) #ifndef SLEEF_STATIC_LIBS From 9e914be122ef8bd8463fd62dbf20ec9eba356b67 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Wed, 10 Feb 2021 04:59:45 +0000 Subject: [PATCH 15/17] Re-enable testcase g18x --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0d3ac8a0c..34b13ba05 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -102,7 +102,7 @@ set(test_cases g132 g13x g15x - # g18x + g18x g1x g1x0 g1x1 From 2f64856562bd0aabafa34b0cc27b11d90f1c6844 Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Wed, 10 Feb 2021 09:58:13 +0000 Subject: [PATCH 16/17] Drop execution bit on a cmake script --- cmake/FindStandardMathLibrary.cmake | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 cmake/FindStandardMathLibrary.cmake diff --git a/cmake/FindStandardMathLibrary.cmake b/cmake/FindStandardMathLibrary.cmake old mode 100755 new mode 100644 From 5497398804d4fff940cae14e2210e5b80914b8ca Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Sun, 14 Feb 2021 07:16:17 +0000 Subject: [PATCH 17/17] Copy libomp.dll only if using VS stock DLL --- CMakeLists.txt | 6 - cmake/FindOpenMP.cmake | 605 ----------------------------------------- jsrc/CMakeLists.txt | 12 +- 3 files changed, 10 insertions(+), 613 deletions(-) delete mode 100644 cmake/FindOpenMP.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f42992e1..447b2ae58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,12 +29,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_VISIBILITY_PRESET hidden) -if("${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC") - get_filename_component(_cl_bin_dir ${CMAKE_C_COMPILER} DIRECTORY) - file(TO_CMAKE_PATH "${_cl_bin_dir}/../lib/libomp.lib" OpenMP_libomp_LIBRARY) - file(TO_CMAKE_PATH "${_cl_bin_dir}/libomp.dll" OpenMP_libomp_DLL) -endif() - find_package(StandardMathLibrary REQUIRED) find_package(OpenMP) find_package(JNI) diff --git a/cmake/FindOpenMP.cmake b/cmake/FindOpenMP.cmake deleted file mode 100644 index f5a7e6679..000000000 --- a/cmake/FindOpenMP.cmake +++ /dev/null @@ -1,605 +0,0 @@ -# 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. - -Variables -^^^^^^^^^ - -The module exposes the components ``C``, ``CXX``, and ``Fortran``. -Each of these controls the various languages to search OpenMP support for. - -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 ```` is one of C, CXX, or Fortran: - -``OpenMP__FOUND`` - Variable indicating if OpenMP support for ```` was detected. -``OpenMP__FLAGS`` - OpenMP compiler flags for ````, separated by spaces. -``OpenMP__INCLUDE_DIRS`` - Directories that must be added to the header search path for ```` - when using OpenMP. - -For linking with OpenMP code written in ````, the following -variables are provided: - -``OpenMP__LIB_NAMES`` - :ref:`;-list ` of libraries for OpenMP programs for ````. -``OpenMP__LIBRARY`` - Location of the individual libraries needed for OpenMP support in ````. -``OpenMP__LIBRARIES`` - A list of libraries needed to link with OpenMP code written in ````. - -Additionally, the module provides :prop_tgt:`IMPORTED` targets: - -``OpenMP::OpenMP_`` - Target for using OpenMP from ````. - -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__SPEC_DATE`` - Date of the OpenMP specification implemented by the ```` compiler. -``OpenMP__VERSION_MAJOR`` - Major version of OpenMP implemented by the ```` compiler. -``OpenMP__VERSION_MINOR`` - Minor version of OpenMP implemented by the ```` compiler. -``OpenMP__VERSION`` - OpenMP version implemented by the ```` 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 ```` 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__INCLUDE_DIR`` cache variable. -Note that this variable is an _input_ control to the module. Project code -should use the ``OpenMP__INCLUDE_DIRS`` _output_ variable if it needs -to know what include directories are needed. -#]=======================================================================] - -cmake_policy(PUSH) -cmake_policy(SET CMP0012 NEW) # if() recognizes numbers and booleans -cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced -cmake_policy(SET CMP0057 NEW) # if IN_LIST - -function(_OPENMP_FLAG_CANDIDATES LANG) - if(NOT OpenMP_${LANG}_FLAG) - unset(OpenMP_FLAG_CANDIDATES) - - set(OMP_FLAG_GNU "-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() - set(OMP_FLAG_MSVC "-openmp") - set(OMP_FLAG_PathScale "-openmp") - set(OMP_FLAG_NAG "-openmp") - set(OMP_FLAG_Absoft "-openmp") - set(OMP_FLAG_PGI "-mp") - set(OMP_FLAG_Flang "-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") - - # If we know the correct flags, use those - if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}) - set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}") - # Fall back to reasonable default tries otherwise - else() - 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 -int main(void) { -#ifdef _OPENMP - omp_get_max_threads(); - return 0; -#elif defined(__HIP_DEVICE_COMPILE__) - return 0; -#else - breaks_on_purpose -#endif -} -") - -# 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 - " -) - -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(CMakeParseImplicitLinkInfo) - -function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) - _OPENMP_FLAG_CANDIDATES("${LANG}") - _OPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenMPTryFlag _OPENMP_TEST_SRC) - - unset(OpenMP_VERBOSE_COMPILE_OPTIONS) - separate_arguments(OpenMP_VERBOSE_OPTIONS NATIVE_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}") - foreach(_VERBOSE_OPTION IN LISTS OpenMP_VERBOSE_OPTIONS) - if(NOT _VERBOSE_OPTION MATCHES "^-Wl,") - list(APPEND OpenMP_VERBOSE_COMPILE_OPTIONS ${_VERBOSE_OPTION}) - endif() - endforeach() - - foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES) - set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}") - if(OpenMP_VERBOSE_COMPILE_OPTIONS) - string(APPEND OPENMP_FLAGS_TEST " ${OpenMP_VERBOSE_COMPILE_OPTIONS}") - endif() - string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}") - try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" - LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} - OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT - ) - - if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}) - 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) - 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 "${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_DEFAULT_PATH - ) - endif() - mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY) - list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB_PLAIN}) - endif() - endforeach() - 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") - - # 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} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" - LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY} - OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT - ) - 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} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" - "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}" - LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY} - OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT - ) - 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} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" - LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY} - OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT - ) - 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() - else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Detecting ${LANG} OpenMP failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n") - endif() - set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE) - set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE) - endforeach() - - unset(OpenMP_VERBOSE_COMPILE_OPTIONS) -endfunction() - -set(OpenMP_C_CXX_CHECK_VERSION_SOURCE -" -#include -#include -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_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC) - - 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} "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}" - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}" ${_includeDirFlags} - COPY_FILE ${BIN_FILE} - OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT) - - 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() - else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Detecting ${LANG} OpenMP version failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n") - endif() -endfunction() - -macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG) - set(OpenMP_SPEC_DATE_MAP - # 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) - 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) - set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}" - CACHE STRING "${LANG} compiler flags for OpenMP parallelization" FORCE) - set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}" - CACHE STRING "${LANG} compiler libraries for OpenMP parallelization" FORCE) - 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() - - 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" "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() - - 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() - set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'") - endif() -endif() - -if(NOT OpenMP_FIND_COMPONENTS) - set(OpenMP_FINDLIST C CXX Fortran) -else() - set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS}) -endif() - -unset(_OpenMP_MIN_VERSION) - -include(FindPackageHandleStandardArgs) - -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) - separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}") - set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY - INTERFACE_COMPILE_OPTIONS "$<$:${_OpenMP_${LANG}_OPTIONS}>") - unset(_OpenMP_${LANG}_OPTIONS) - endif() - if(OpenMP_${LANG}_INCLUDE_DIRS) - set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY - INTERFACE_INCLUDE_DIRECTORIES "$") - 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 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) - -set(OPENMP_FOUND ${OpenMP_FOUND}) - -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_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) diff --git a/jsrc/CMakeLists.txt b/jsrc/CMakeLists.txt index df82c01f7..099cd98c1 100644 --- a/jsrc/CMakeLists.txt +++ b/jsrc/CMakeLists.txt @@ -194,15 +194,23 @@ target_sources(j PRIVATE configure_file(jversion-x.h ${CMAKE_CURRENT_SOURCE_DIR}/jversion.h COPYONLY) +if("${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC") + get_filename_component(_cl_bin_dir ${CMAKE_C_COMPILER} DIRECTORY) + get_filename_component(OpenMP_libomp_LIB + "${_cl_bin_dir}/../lib/libomp.lib" ABSOLUTE) + file(TO_CMAKE_PATH "${_cl_bin_dir}/libomp.dll" OpenMP_libomp_DLL) +endif() + if(OpenMP_C_FOUND) target_link_libraries(j PRIVATE OpenMP::OpenMP_C) - if(DEFINED OpenMP_libomp_DLL) + if(DEFINED OpenMP_libomp_DLL AND + OpenMP_libomp_LIBRARY STREQUAL OpenMP_libomp_LIB) add_custom_command( TARGET j POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${OpenMP_libomp_DLL} - "${CMAKE_CURRENT_BINARY_DIR}$<${is_multi_config}:/$>" + $ ) endif() endif()