361 lines · plain
1#2#//===----------------------------------------------------------------------===//3#//4#// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5#// See https://llvm.org/LICENSE.txt for license information.6#// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7#//8#//===----------------------------------------------------------------------===//9#10 11include(CheckCCompilerFlag)12include(CheckCSourceCompiles)13include(CheckCXXSourceCompiles)14include(CheckCXXCompilerFlag)15include(CheckIncludeFile)16include(CheckLibraryExists)17include(CheckIncludeFiles)18include(CheckSymbolExists)19include(LibompCheckFortranFlag)20include(LLVMCheckCompilerLinkerFlag)21 22# Check for versioned symbols23function(libomp_check_version_symbols retval)24 set(source_code25 "#include <stdio.h>26 void func1() { printf(\"Hello\"); }27 void func2() { printf(\"World\"); }28 __asm__(\".symver func1, func@VER1\");29 __asm__(\".symver func2, func@VER2\");30 int main(void) {31 func1();32 func2();33 return 0;34 }")35 set(version_script_source "VER1 { }; VER2 { } VER1;")36 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/__version_script.txt "${version_script_source}")37 set(CMAKE_REQUIRED_FLAGS -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/__version_script.txt)38 check_c_source_compiles("${source_code}" ${retval})39 set(${retval} ${${retval}} PARENT_SCOPE)40 file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/__version_script.txt)41endfunction()42 43# Includes the architecture flag in both compile and link phase44function(libomp_check_architecture_flag flag retval)45 set(CMAKE_REQUIRED_FLAGS "${flag}")46 check_c_compiler_flag("${flag}" ${retval})47 set(${retval} ${${retval}} PARENT_SCOPE)48endfunction()49 50# Checking CXX, Linker Flags51 52# GCC silently accepts any -Wno-<foo> option, but warns about those options53# being unrecognized only if the compilation triggers other warnings to be54# printed. Therefore, check for whether the compiler supports options in the55# form -W<foo>, and if supported, add the corresponding -Wno-<foo> option.56 57check_cxx_compiler_flag(-fno-exceptions LIBOMP_HAVE_FNO_EXCEPTIONS_FLAG)58check_cxx_compiler_flag(-fno-rtti LIBOMP_HAVE_FNO_RTTI_FLAG)59check_cxx_compiler_flag(-Wclass-memaccess LIBOMP_HAVE_WCLASS_MEMACCESS_FLAG)60check_cxx_compiler_flag(-Wcovered-switch-default LIBOMP_HAVE_WCOVERED_SWITCH_DEFAULT_FLAG)61check_cxx_compiler_flag(-Wframe-address LIBOMP_HAVE_WFRAME_ADDRESS_FLAG)62check_cxx_compiler_flag(-Wstrict-aliasing LIBOMP_HAVE_WSTRICT_ALIASING_FLAG)63check_cxx_compiler_flag(-Wstringop-overflow=0 LIBOMP_HAVE_WSTRINGOP_OVERFLOW_FLAG)64check_cxx_compiler_flag(-Wstringop-truncation LIBOMP_HAVE_WSTRINGOP_TRUNCATION_FLAG)65check_cxx_compiler_flag(-Wswitch LIBOMP_HAVE_WSWITCH_FLAG)66check_cxx_compiler_flag(-Wuninitialized LIBOMP_HAVE_WUNINITIALIZED_FLAG)67check_cxx_compiler_flag(-Wreturn-type-c-linkage LIBOMP_HAVE_WRETURN_TYPE_C_LINKAGE_FLAG)68check_cxx_compiler_flag(-Wcast-qual LIBOMP_HAVE_WCAST_QUAL_FLAG)69check_cxx_compiler_flag(-Wint-to-void-pointer-cast LIBOMP_HAVE_WINT_TO_VOID_POINTER_CAST_FLAG)70# check_cxx_compiler_flag(-Wconversion LIBOMP_HAVE_WCONVERSION_FLAG)71check_cxx_compiler_flag(-msse2 LIBOMP_HAVE_MSSE2_FLAG)72check_cxx_compiler_flag(-ftls-model=initial-exec LIBOMP_HAVE_FTLS_MODEL_FLAG)73libomp_check_architecture_flag(-mmic LIBOMP_HAVE_MMIC_FLAG)74libomp_check_architecture_flag(-m32 LIBOMP_HAVE_M32_FLAG)75if(WIN32)76 if(MSVC)77 # Check Windows MSVC style flags.78 check_cxx_compiler_flag(/EHsc LIBOMP_HAVE_EHSC_FLAG)79 check_cxx_compiler_flag(/GS LIBOMP_HAVE_GS_FLAG)80 check_cxx_compiler_flag(/Oy- LIBOMP_HAVE_Oy__FLAG)81 check_cxx_compiler_flag(/arch:SSE2 LIBOMP_HAVE_ARCH_SSE2_FLAG)82 check_cxx_compiler_flag(/Qsafeseh LIBOMP_HAVE_QSAFESEH_FLAG)83 endif()84 check_cxx_compiler_flag(-mrtm LIBOMP_HAVE_MRTM_FLAG)85 # It is difficult to create a dummy masm assembly file86 # and then check the MASM assembler to see if these flags exist and work,87 # so we assume they do for Windows.88 set(LIBOMP_HAVE_SAFESEH_MASM_FLAG TRUE)89 set(LIBOMP_HAVE_COFF_MASM_FLAG TRUE)90 # Change Windows flags /MDx to /MTx91 foreach(libomp_lang IN ITEMS C CXX)92 foreach(libomp_btype IN ITEMS DEBUG RELWITHDEBINFO RELEASE MINSIZEREL)93 string(REPLACE "/MD" "/MT"94 CMAKE_${libomp_lang}_FLAGS_${libomp_btype}95 "${CMAKE_${libomp_lang}_FLAGS_${libomp_btype}}"96 )97 endforeach()98 endforeach()99endif()100if(${LIBOMP_FORTRAN_MODULES})101 libomp_check_fortran_flag(-m32 LIBOMP_HAVE_M32_FORTRAN_FLAG)102endif()103 104# Check non-posix pthread API here before CMAKE_REQUIRED_DEFINITIONS gets messed up105check_symbol_exists(pthread_setname_np "pthread.h" LIBOMP_HAVE_PTHREAD_SETNAME_NP)106check_symbol_exists(pthread_set_name_np "pthread.h;pthread_np.h" LIBOMP_HAVE_PTHREAD_SET_NAME_NP)107 108# Check for Unix shared memory109check_symbol_exists(shm_open "sys/mman.h" LIBOMP_HAVE_SHM_OPEN_NO_LRT)110if (NOT LIBOMP_HAVE_SHM_OPEN_NO_LRT)111 set(CMAKE_REQUIRED_LIBRARIES -lrt)112 check_symbol_exists(shm_open "sys/mman.h" LIBOMP_HAVE_SHM_OPEN_WITH_LRT)113 set(CMAKE_REQUIRED_LIBRARIES)114endif()115 116# Check for aligned memory allocator function117check_include_file(xmmintrin.h LIBOMP_HAVE_XMMINTRIN_H)118set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})119if (LIBOMP_HAVE_XMMINTRIN_H)120 set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -DLIBOMP_HAVE_XMMINTRIN_H")121endif()122set(source_code "// check for _mm_malloc123 #ifdef LIBOMP_HAVE_XMMINTRIN_H124 #include <xmmintrin.h>125 #endif126 int main() { void *ptr = _mm_malloc(sizeof(int) * 1000, 64); _mm_free(ptr); return 0; }")127check_cxx_source_compiles("${source_code}" LIBOMP_HAVE__MM_MALLOC)128set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})129check_symbol_exists(aligned_alloc "stdlib.h" LIBOMP_HAVE_ALIGNED_ALLOC)130check_symbol_exists(posix_memalign "stdlib.h" LIBOMP_HAVE_POSIX_MEMALIGN)131check_symbol_exists(_aligned_malloc "malloc.h" LIBOMP_HAVE__ALIGNED_MALLOC)132 133# Check linker flags134if(WIN32)135 llvm_check_compiler_linker_flag(C /SAFESEH LIBOMP_HAVE_SAFESEH_FLAG)136elseif(NOT APPLE)137 llvm_check_compiler_linker_flag(C -Wl,-x LIBOMP_HAVE_X_FLAG)138 llvm_check_compiler_linker_flag(C -Wl,--as-needed LIBOMP_HAVE_AS_NEEDED_FLAG)139 llvm_check_compiler_linker_flag(C "-Wl,--version-script=${LIBOMP_SRC_DIR}/exports_test_so.txt" LIBOMP_HAVE_VERSION_SCRIPT_FLAG)140 llvm_check_compiler_linker_flag(C -static-libgcc LIBOMP_HAVE_STATIC_LIBGCC_FLAG)141 llvm_check_compiler_linker_flag(C -Wl,-z,noexecstack LIBOMP_HAVE_Z_NOEXECSTACK_FLAG)142endif()143 144# Check Intel(R) C Compiler specific flags145if(CMAKE_C_COMPILER_ID STREQUAL "Intel" OR CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM")146 check_cxx_compiler_flag(/Qlong_double LIBOMP_HAVE_LONG_DOUBLE_FLAG)147 check_cxx_compiler_flag(/Qdiag-disable:177 LIBOMP_HAVE_DIAG_DISABLE_177_FLAG)148 check_cxx_compiler_flag(/Qinline-min-size=1 LIBOMP_HAVE_INLINE_MIN_SIZE_FLAG)149 check_cxx_compiler_flag(-Qoption,cpp,--extended_float_types LIBOMP_HAVE_EXTENDED_FLOAT_TYPES_FLAG)150 check_cxx_compiler_flag(-falign-stack=maintain-16-byte LIBOMP_HAVE_FALIGN_STACK_FLAG)151 check_cxx_compiler_flag("-opt-streaming-stores never" LIBOMP_HAVE_OPT_STREAMING_STORES_FLAG)152 llvm_check_compiler_linker_flag(C -static-intel LIBOMP_HAVE_STATIC_INTEL_FLAG)153 llvm_check_compiler_linker_flag(C -no-intel-extensions LIBOMP_HAVE_NO_INTEL_EXTENSIONS_FLAG)154 check_library_exists(irc_pic _intel_fast_memcpy "" LIBOMP_HAVE_IRC_PIC_LIBRARY)155endif()156 157# Checking threading requirements. Note that compiling to WebAssembly threads158# with either the Emscripten or wasi-threads flavor ends up using the pthreads159# interface in a WebAssembly-compiled libc; CMake does not yet know how to160# detect this.161if (NOT WASM)162 find_package(Threads REQUIRED)163 if(WIN32)164 if(NOT CMAKE_USE_WIN32_THREADS_INIT)165 libomp_error_say("Need Win32 thread interface on Windows.")166 endif()167 else()168 if(NOT CMAKE_USE_PTHREADS_INIT)169 libomp_error_say("Need pthread interface on Unix-like systems.")170 endif()171 endif()172endif()173 174# Checking for x86-specific waitpkg and rtm attribute and intrinsics175if (IA32 OR INTEL64)176 check_include_file(immintrin.h LIBOMP_HAVE_IMMINTRIN_H)177 if (NOT LIBOMP_HAVE_IMMINTRIN_H)178 check_include_file(intrin.h LIBOMP_HAVE_INTRIN_H)179 endif()180 check_cxx_source_compiles("__attribute__((target(\"rtm\")))181 int main() {return 0;}" LIBOMP_HAVE_ATTRIBUTE_RTM)182 check_cxx_source_compiles("__attribute__((target(\"waitpkg\")))183 int main() {return 0;}" LIBOMP_HAVE_ATTRIBUTE_WAITPKG)184 libomp_append(CMAKE_REQUIRED_DEFINITIONS -DIMMINTRIN_H LIBOMP_HAVE_IMMINTRIN_H)185 libomp_append(CMAKE_REQUIRED_DEFINITIONS -DINTRIN_H LIBOMP_HAVE_INTRIN_H)186 libomp_append(CMAKE_REQUIRED_DEFINITIONS -DATTRIBUTE_WAITPKG LIBOMP_HAVE_ATTRIBUTE_WAITPKG)187 libomp_append(CMAKE_REQUIRED_DEFINITIONS -DATTRIBUTE_RTM LIBOMP_HAVE_ATTRIBUTE_RTM)188 set(source_code "// check for attribute and wait pkg intrinsics189 #ifdef IMMINTRIN_H190 #include <immintrin.h>191 #endif192 #ifdef INTRIN_H193 #include <intrin.h>194 #endif195 #ifdef ATTRIBUTE_WAITPKG196 __attribute__((target(\"waitpkg\")))197 #endif198 static inline int __kmp_umwait(unsigned hint, unsigned long long counter) {199 return _umwait(hint, counter);200 }201 int main() { int a = __kmp_umwait(0, 1000); return a; }")202 check_cxx_source_compiles("${source_code}" LIBOMP_HAVE_WAITPKG_INTRINSICS)203 set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})204 if (LIBOMP_HAVE_MRTM_FLAG)205 set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -mrtm")206 endif()207 set(source_code "// check for attribute rtm and rtm intrinsics208 #ifdef IMMINTRIN_H209 #include <immintrin.h>210 #endif211 #ifdef INTRIN_H212 #include <intrin.h>213 #endif214 #ifdef ATTRIBUTE_RTM215 __attribute__((target(\"rtm\")))216 #endif217 static inline int __kmp_xbegin() {218 return _xbegin();219 }220 int main() { int a = __kmp_xbegin(); return a; }")221 check_cxx_source_compiles("${source_code}" LIBOMP_HAVE_RTM_INTRINSICS)222 set(CMAKE_REQUIRED_DEFINITIONS)223 set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})224endif()225 226# Find python3 executable227# Python3 is used to create kmp_i18n_id.inc and228# kmp_i18n_default.inc and for Windows the *.def files.229find_package(Python3 REQUIRED COMPONENTS Interpreter)230 231# Checking features232# Check if version symbol assembler directives are supported233if (LIBOMP_HAVE_VERSION_SCRIPT_FLAG)234 libomp_check_version_symbols(LIBOMP_HAVE_VERSION_SYMBOLS)235else()236 set(LIBOMP_HAVE_VERSION_SYMBOLS FALSE)237endif()238 239# Check if quad precision types are available240if(CMAKE_C_COMPILER_ID STREQUAL "GNU")241 set(LIBOMP_HAVE_QUAD_PRECISION TRUE)242elseif(CMAKE_C_COMPILER_ID STREQUAL "Intel" OR CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM")243 if(LIBOMP_HAVE_EXTENDED_FLOAT_TYPES_FLAG)244 set(LIBOMP_HAVE_QUAD_PRECISION TRUE)245 else()246 set(LIBOMP_HAVE_QUAD_PRECISION TRUE)247 endif()248else()249 set(LIBOMP_HAVE_QUAD_PRECISION FALSE)250endif()251 252# Check if adaptive locks are available253if((${IA32} OR ${INTEL64}) AND NOT MSVC)254 set(LIBOMP_HAVE_ADAPTIVE_LOCKS TRUE)255else()256 set(LIBOMP_HAVE_ADAPTIVE_LOCKS FALSE)257endif()258 259# Check if stats-gathering is available260if(${LIBOMP_STATS})261 check_c_source_compiles(262 "__thread int x;263 int main(int argc, char** argv)264 { x = argc; return x; }"265 LIBOMP_HAVE___THREAD)266 check_c_source_compiles(267 "int main(int argc, char** argv)268 { unsigned long long t = __builtin_readcyclecounter(); return 0; }"269 LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER)270 if(NOT LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER)271 if(${IA32} OR ${INTEL64} OR ${MIC})272 check_include_file(x86intrin.h LIBOMP_HAVE_X86INTRIN_H)273 libomp_append(CMAKE_REQUIRED_DEFINITIONS -DLIBOMP_HAVE_X86INTRIN_H LIBOMP_HAVE_X86INTRIN_H)274 check_c_source_compiles(275 "#ifdef LIBOMP_HAVE_X86INTRIN_H276 # include <x86intrin.h>277 #endif278 int main(int argc, char** argv) { unsigned long long t = __rdtsc(); return 0; }" LIBOMP_HAVE___RDTSC)279 set(CMAKE_REQUIRED_DEFINITIONS)280 endif()281 endif()282 if(LIBOMP_HAVE___THREAD AND (LIBOMP_HAVE___RDTSC OR LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER))283 set(LIBOMP_HAVE_STATS TRUE)284 else()285 set(LIBOMP_HAVE_STATS FALSE)286 endif()287endif()288 289# Check if OMPT support is available290# Currently, __builtin_frame_address() is required for OMPT291# Weak attribute is required for Unices (except Darwin), LIBPSAPI is used for Windows292check_c_source_compiles("int main(int argc, char** argv) {293 void* p = __builtin_frame_address(0);294 return 0;}" LIBOMP_HAVE___BUILTIN_FRAME_ADDRESS)295check_c_source_compiles("__attribute__ ((weak)) int foo(int a) { return a*a; }296 int main(int argc, char** argv) {297 return foo(argc);}" LIBOMP_HAVE_WEAK_ATTRIBUTE)298set(CMAKE_REQUIRED_LIBRARIES psapi)299check_c_source_compiles("#include <windows.h>300 #include <psapi.h>301 int main(int artc, char** argv) {302 return EnumProcessModules(NULL, NULL, 0, NULL);303 }" LIBOMP_HAVE_PSAPI)304set(CMAKE_REQUIRED_LIBRARIES)305if(NOT LIBOMP_HAVE___BUILTIN_FRAME_ADDRESS)306 set(LIBOMP_HAVE_OMPT_SUPPORT FALSE)307else()308 if( # hardware architecture supported?309 ((LIBOMP_ARCH STREQUAL x86_64) OR310 (LIBOMP_ARCH STREQUAL i386) OR311# (LIBOMP_ARCH STREQUAL arm) OR312 (LIBOMP_ARCH STREQUAL aarch64) OR313 (LIBOMP_ARCH STREQUAL aarch64_32) OR314 (LIBOMP_ARCH STREQUAL aarch64_a64fx) OR315 (LIBOMP_ARCH STREQUAL ppc64le) OR316 (LIBOMP_ARCH STREQUAL ppc64) OR317 (LIBOMP_ARCH STREQUAL riscv64) OR318 (LIBOMP_ARCH STREQUAL loongarch64) OR319 (LIBOMP_ARCH STREQUAL s390x) OR320 (LIBOMP_ARCH STREQUAL sparc) OR321 (LIBOMP_ARCH STREQUAL sparcv9))322 AND # OS supported?323 ((WIN32 AND LIBOMP_HAVE_PSAPI) OR APPLE OR324 (NOT (WIN32 OR "${CMAKE_SYSTEM_NAME}" MATCHES "AIX") AND LIBOMP_HAVE_WEAK_ATTRIBUTE)))325 set(LIBOMP_HAVE_OMPT_SUPPORT TRUE)326 else()327 set(LIBOMP_HAVE_OMPT_SUPPORT FALSE)328 endif()329endif()330 331set(LIBOMP_HAVE_OMPT_SUPPORT ${LIBOMP_HAVE_OMPT_SUPPORT} PARENT_SCOPE)332 333# Check if HWLOC support is available334if(${LIBOMP_USE_HWLOC})335 find_path(LIBOMP_HWLOC_INCLUDE_DIR NAMES hwloc.h HINTS ${LIBOMP_HWLOC_INSTALL_DIR} PATH_SUFFIXES include)336 set(CMAKE_REQUIRED_INCLUDES ${LIBOMP_HWLOC_INCLUDE_DIR})337 check_include_file(hwloc.h LIBOMP_HAVE_HWLOC_H)338 set(CMAKE_REQUIRED_INCLUDES)339 find_library(LIBOMP_HWLOC_LIBRARY340 NAMES hwloc libhwloc341 HINTS ${LIBOMP_HWLOC_INSTALL_DIR}/lib)342 if(LIBOMP_HWLOC_LIBRARY)343 check_library_exists(${LIBOMP_HWLOC_LIBRARY} hwloc_topology_init344 ${LIBOMP_HWLOC_INSTALL_DIR}/lib LIBOMP_HAVE_LIBHWLOC)345 get_filename_component(LIBOMP_HWLOC_LIBRARY_DIR ${LIBOMP_HWLOC_LIBRARY} PATH)346 endif()347 if(LIBOMP_HAVE_HWLOC_H AND LIBOMP_HAVE_LIBHWLOC AND LIBOMP_HWLOC_LIBRARY)348 set(LIBOMP_HAVE_HWLOC TRUE)349 else()350 set(LIBOMP_HAVE_HWLOC FALSE)351 libomp_say("Could not find hwloc")352 endif()353endif()354 355# Check if ThreadSanitizer support is available356if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux" AND ${INTEL64})357 set(LIBOMP_HAVE_TSAN_SUPPORT TRUE)358else()359 set(LIBOMP_HAVE_TSAN_SUPPORT FALSE)360endif()361