#===-- CMakeLists.txt ------------------------------------------------------===# # # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. # See https://llvm.org/LICENSE.txt for license information. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # #===------------------------------------------------------------------------===# # # Build instructions for the flang-rt library. This is file is intended to be # included using the LLVM_ENABLE_RUNTIMES mechanism. # #===------------------------------------------------------------------------===# if (NOT LLVM_RUNTIMES_BUILD) message(FATAL_ERROR "Use this CMakeLists.txt from LLVM's runtimes build system. Example: cmake /runtimes -DLLVM_ENABLE_RUNTIMES=flang-rt ") endif () set(LLVM_SUBPROJECT_TITLE "Flang-RT") set(FLANG_RT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") set(FLANG_RT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") set(FLANG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../flang") # CMake 3.24 is the first version of CMake that directly recognizes Flang. # LLVM's requirement is only CMake 3.20, teach CMake 3.20-3.23 how to use Flang. if (CMAKE_VERSION VERSION_LESS "3.24") cmake_path(GET CMAKE_Fortran_COMPILER STEM _Fortran_COMPILER_STEM) if (_Fortran_COMPILER_STEM STREQUAL "flang") include(CMakeForceCompiler) CMAKE_FORCE_Fortran_COMPILER("${CMAKE_Fortran_COMPILER}" "LLVMFlang") set(CMAKE_Fortran_COMPILER_ID "LLVMFlang") set(CMAKE_Fortran_COMPILER_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}") set(CMAKE_Fortran_SUBMODULE_SEP "-") set(CMAKE_Fortran_SUBMODULE_EXT ".mod") set(CMAKE_Fortran_PREPROCESS_SOURCE " -cpp -E > ") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form") set(CMAKE_Fortran_MODDIR_FLAG "-module-dir") set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp") set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp") set(CMAKE_Fortran_POSTPROCESS_FLAG "-ffixed-line-length-72") set(CMAKE_Fortran_COMPILE_OPTIONS_TARGET "--target=") set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,") set(CMAKE_Fortran_LINKER_WRAPPER_FLAG_SEP ",") endif () endif () enable_language(Fortran) # Try to include the RPC utilities from the `libc` project for GPU I/O support. include(FindLibcCommonUtils) list(APPEND CMAKE_MODULE_PATH "${FLANG_RT_SOURCE_DIR}/cmake/modules" "${FLANG_SOURCE_DIR}/cmake/modules" ) include(AddFlangRT) include(GetToolchainDirs) include(FlangCommon) include(HandleCompilerRT) include(ExtendPath) ############################ # Build Mode Introspection # ############################ # Path to LLVM development tools (FileCheck, llvm-lit, not, ...) set(LLVM_TOOLS_DIR "${LLVM_BINARY_DIR}/bin") ################# # Build Options # ################# # Important: flang-rt user options must be prefixed with "FLANG_RT_". Variables # with this prefix will be forwarded in bootstrap builds. # Provide an interface to link against the LLVM libc/libc++ projects directly. set(FLANG_RT_SUPPORTED_PROVIDERS system llvm) set(FLANG_RT_LIBC_PROVIDER "system" CACHE STRING "Specify C library to use. Supported values are ${FLANG_RT_SUPPORTED_PROVIDERS}.") if (NOT "${FLANG_RT_LIBC_PROVIDER}" IN_LIST FLANG_RT_SUPPORTED_PROVIDERS) message(FATAL_ERROR "Unsupported library: '${FLANG_RT_RUNTIME_PROVIDER}'. Supported values are ${FLANG_RT_SUPPORTED_PROVIDERS}.") endif () set(FLANG_RT_LIBCXX_PROVIDER "system" CACHE STRING "Specify C++ library to use. Supported values are ${FLANG_RT_SUPPORTED_PROVIDERS}.") if (NOT "${FLANG_RT_LIBCXX_PROVIDER}" IN_LIST FLANG_RT_SUPPORTED_PROVIDERS) message(FATAL_ERROR "Unsupported library: '${FLANG_RT_LIBCXX_PROVIDER}'. Supported values are ${FLANG_RT_SUPPORTED_PROVIDERS}.") endif () option(FLANG_RT_ENABLE_STATIC "Build Flang-RT as a static library." ON) if (WIN32) # Windows DLL currently not implemented. set(FLANG_RT_ENABLE_SHARED OFF) else () # TODO: Enable by default to increase test coverage, and which version of the # library should be the user's choice anyway. # Currently, the Flang driver adds `-L"libdir" -lflang_rt` as linker # argument, which leaves the choice which library to use to the linker. # Since most linkers prefer the shared library, this would constitute a # breaking change unless the driver is changed. option(FLANG_RT_ENABLE_SHARED "Build Flang-RT as a shared library." OFF) endif () # TODO: Support tests for the GPU target. set(FLANG_RT_INCLUDE_TESTS_default ${LLVM_INCLUDE_TESTS}) if ("${LLVM_DEFAULT_TARGET_TRIPLE}" MATCHES "^amdgcn|^nvptx") set(FLANG_RT_INCLUDE_TESTS_default OFF) elseif (NOT FLANG_RT_FORTRAN_MODULES) set(FLANG_RT_INCLUDE_TESTS_default OFF) elseif (NOT FLANG_RT_ENABLE_STATIC AND NOT FLANG_RT_ENABLE_SHARED) set(FLANG_RT_INCLUDE_TESTS_default OFF) endif() option(FLANG_RT_INCLUDE_TESTS "Generate build targets for the flang-rt unit and regression-tests." "${FLANG_RT_INCLUDE_TESTS_default}") if (FLANG_RT_INCLUDE_TESTS AND NOT FLANG_RT_ENABLE_STATIC AND NOT FLANG_RT_ENABLE_SHARED) message(WARNING "FLANG_RT_INCLUDE_TESTS=${FLANG_RT_INCLUDE_TESTS} requires a " "library to be built (FLANG_RT_ENABLE_STATIC=ON or " "FLANG_RT_ENABLE_SHARED=ON).\n" "Tests are disabled: check-flang-rt does nothing") set(FLANG_RT_INCLUDE_TESTS OFF) endif () set(FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT "" CACHE STRING "Compile Flang-RT with GPU support (CUDA)") set_property(CACHE FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT PROPERTY STRINGS "" CUDA ) if (NOT FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT) # Support for GPUs disabled elseif (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA") # Support for CUDA set(FLANG_RT_LIBCUDACXX_PATH "" CACHE PATH "Path to libcu++ package installation") option(FLANG_RT_CUDA_RUNTIME_PTX_WITHOUT_GLOBAL_VARS "Do not compile global variables' definitions when producing PTX library" OFF) else () message(FATAL_ERROR "Invalid value '${FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT}' for FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT; must be empty or 'CUDA'") endif () option(FLANG_RT_INCLUDE_CUF "Build the CUDA Fortran runtime (libflang_rt.cuda.a)" OFF) if (FLANG_RT_INCLUDE_CUF) find_package(CUDAToolkit REQUIRED) endif() # A recently added check in clang emits warnings for feclearexcept and fesetround: # 'fesetround' used without enabling floating-point exception behavior; use # 'pragma STDC FENV_ACCESS ON' or compile with # '-ffp-exception-behavior=maytrap' [-Werror,-Wfenv-access] # This breaks the CI build (because of -Werror). if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") check_cxx_compiler_flag("-Werror -Wno-fenv-access" CXX_SUPPORTS_NO_FENV_ACCESS_FLAG) if (CXX_SUPPORTS_NO_FENV_ACCESS_FLAG) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-fenv-access") endif() endif() # Clang ######################## # System Introspection # ######################## include(CheckCXXSymbolExists) include(CheckCXXSourceCompiles) check_cxx_symbol_exists(strerror_r string.h HAVE_STRERROR_R) # Can't use symbol exists here as the function is overloaded in C++ check_cxx_source_compiles( "#include int main() { char buf[4096]; return strerror_s(buf, 4096, 0); } " HAVE_DECL_STRERROR_S) # Search for clang_rt.builtins library. Need in addition to msvcrt. if (WIN32) find_compiler_rt_library(builtins FLANG_RT_BUILTINS_LIBRARY) endif () # Build with _XOPEN_SOURCE on AIX to avoid errors caused by _ALL_SOURCE. # We need to enable the large-file API as well. if (UNIX AND CMAKE_SYSTEM_NAME MATCHES "AIX") add_compile_definitions(_XOPEN_SOURCE=700) add_compile_definitions(_LARGE_FILE_API) endif () # Indicates REAL(16) support via an external library (e.g. libquadmath). add_compile_definitions(FLANG_RT_SUPPORTS_REAL16=$) # Check whether the compiler can undefine a macro using the "-Wp,-U" flag. # Aternatively, we could use # CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU" # but some older versions of CMake don't define it for GCC itself. check_cxx_compiler_flag("-Wp,-UTESTFLAG" FLANG_RT_SUPPORTS_UNDEFINE_FLAG) # Check whether -fno-lto is supported. check_cxx_compiler_flag(-fno-lto FLANG_RT_HAS_FNO_LTO_FLAG) # Check whether -nostdlibinc is supported. check_cxx_compiler_flag(-nostdlibinc FLANG_RT_HAS_NOSTDLIBINC_FLAG) # Check whether -nostdlib is supported. check_cxx_compiler_flag(-nostdlib FLANG_RT_HAS_NOSTDLIB_FLAG) # Check whether -stdlib= is supported. check_cxx_compiler_flag(-stdlib=platform FLANG_RT_HAS_STDLIB_FLAG) # Check whether -Wl,--as-needed is supported. check_linker_flag(C "LINKER:--as-needed" LINKER_SUPPORTS_AS_NEEDED) if (LINKER_SUPPORTS_AS_NEEDED) set(LINKER_AS_NEEDED_OPT "LINKER:--as-needed") endif() # Different platform may have different name for the POSIX thread library. # For example, libpthread.a on AIX. Search for it as it is needed when # building the shared flang_rt.runtime.so. find_package(Threads) # function checks # FIXME: The NVPTX target will erroneously report it has backtrace support. This # is caused by using "-c -flto" in the required flags to suppress CUDA # tools from being required for the CMake flag checks to succeed. if (NOT "${LLVM_DEFAULT_TARGET_TRIPLE}" MATCHES "^nvptx") find_package(Backtrace) endif() set(HAVE_BACKTRACE ${Backtrace_FOUND}) set(BACKTRACE_HEADER ${Backtrace_HEADER}) ##################### # Build Preparation # ##################### include(HandleLibs) if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT AND FLANG_RT_INCLUDE_TESTS) # If Fortran runtime is built as CUDA library, the linking # of targets that link flang-rt must be done # with CUDA_RESOLVE_DEVICE_SYMBOLS. # CUDA language must be enabled for CUDA_RESOLVE_DEVICE_SYMBOLS # to take effect. enable_language(CUDA) endif() # C++17 is required for flang-rt; user or other runtimes may override this. # GTest included later also requires C++17. set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") set(CMAKE_CXX_STANDARD_REQUIRED YES) configure_file(cmake/config.h.cmake.in config.h) if (FLANG_INCLUDE_QUADMATH_H) configure_file("cmake/quadmath_wrapper.h.in" "${FLANG_RT_BINARY_DIR}/quadmath_wrapper.h") endif () # The bootstrap build will create a phony target with the same as the top-level # directory ("flang-rt") and delegate it to the runtimes build dir. # AddFlangRT will add all non-EXCLUDE_FROM_ALL targets to it. add_custom_target(flang-rt) ################### # Build Artifacts # ################### add_subdirectory(lib) if (LLVM_INCLUDE_EXAMPLES) add_subdirectory(examples) endif () if (FLANG_RT_INCLUDE_TESTS) add_subdirectory(test) if (NOT "${LLVM_RUNTIMES_TARGET}" MATCHES "^amdgcn|^nvptx") add_subdirectory(unittests) endif() else () add_custom_target(check-flang-rt) endif() ################### # Install headers # ################### if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) add_llvm_install_targets(install-flang-rt-headers COMPONENT flang-rt-headers) install(DIRECTORY include/flang-rt/runtime DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang-rt" COMPONENT flang-rt-headers FILES_MATCHING PATTERN "*.h" PATTERN ".git" EXCLUDE PATTERN "CMakeFiles" EXCLUDE) endif()