349 lines · plain
1#===-- CMakeLists.txt ------------------------------------------------------===#2#3# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4# See https://llvm.org/LICENSE.txt for license information.5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6#7#===------------------------------------------------------------------------===#8#9# Build instructions for the flang-rt library. This is file is intended to be10# included using the LLVM_ENABLE_RUNTIMES mechanism.11#12#===------------------------------------------------------------------------===#13 14if (NOT LLVM_RUNTIMES_BUILD)15 message(FATAL_ERROR "Use this CMakeLists.txt from LLVM's runtimes build system.16 Example:17 cmake <llvm-project>/runtimes -DLLVM_ENABLE_RUNTIMES=flang-rt18 ")19endif ()20 21set(LLVM_SUBPROJECT_TITLE "Flang-RT")22set(FLANG_RT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")23set(FLANG_RT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")24set(FLANG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../flang")25 26# CMake 3.24 is the first version of CMake that directly recognizes Flang.27# LLVM's requirement is only CMake 3.20, teach CMake 3.20-3.23 how to use Flang.28if (CMAKE_VERSION VERSION_LESS "3.24")29 cmake_path(GET CMAKE_Fortran_COMPILER STEM _Fortran_COMPILER_STEM)30 if (_Fortran_COMPILER_STEM STREQUAL "flang-new" OR _Fortran_COMPILER_STEM STREQUAL "flang")31 include(CMakeForceCompiler)32 CMAKE_FORCE_Fortran_COMPILER("${CMAKE_Fortran_COMPILER}" "LLVMFlang")33 34 set(CMAKE_Fortran_COMPILER_ID "LLVMFlang")35 set(CMAKE_Fortran_COMPILER_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}")36 37 set(CMAKE_Fortran_SUBMODULE_SEP "-")38 set(CMAKE_Fortran_SUBMODULE_EXT ".mod")39 40 set(CMAKE_Fortran_PREPROCESS_SOURCE41 "<CMAKE_Fortran_COMPILER> -cpp <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")42 43 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form")44 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")45 46 set(CMAKE_Fortran_MODDIR_FLAG "-module-dir")47 48 set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")49 set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp")50 set(CMAKE_Fortran_POSTPROCESS_FLAG "-ffixed-line-length-72")51 52 set(CMAKE_Fortran_COMPILE_OPTIONS_TARGET "--target=")53 54 set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,")55 set(CMAKE_Fortran_LINKER_WRAPPER_FLAG_SEP ",")56 endif ()57endif ()58enable_language(Fortran)59 60 61list(APPEND CMAKE_MODULE_PATH62 "${FLANG_RT_SOURCE_DIR}/cmake/modules"63 "${FLANG_SOURCE_DIR}/cmake/modules"64 )65include(AddFlangRT)66include(GetToolchainDirs)67include(FlangCommon)68include(HandleCompilerRT)69include(ExtendPath)70 71 72############################73# Build Mode Introspection #74############################75 76# Determine whether we are in the runtimes/runtimes-bins directory of a77# bootstrap build.78set(LLVM_TREE_AVAILABLE OFF)79if (LLVM_LIBRARY_OUTPUT_INTDIR AND LLVM_RUNTIME_OUTPUT_INTDIR AND PACKAGE_VERSION)80 set(LLVM_TREE_AVAILABLE ON)81endif()82 83# Path to LLVM development tools (FileCheck, llvm-lit, not, ...)84set(LLVM_TOOLS_DIR "${LLVM_BINARY_DIR}/bin")85 86# Determine build and install paths.87# The build path is absolute, but the install dir is relative, CMake's install88# command has to apply CMAKE_INSTALL_PREFIX itself.89get_toolchain_library_subdir(toolchain_lib_subdir)90if (LLVM_TREE_AVAILABLE)91 # In a bootstrap build emit the libraries into a default search path in the92 # build directory of the just-built compiler. This allows using the93 # just-built compiler without specifying paths to runtime libraries.94 #95 # Despite Clang in the name, get_clang_resource_dir does not depend on Clang96 # being added to the build. Flang uses the same resource dir as clang.97 include(GetClangResourceDir)98 get_clang_resource_dir(FLANG_RT_OUTPUT_RESOURCE_DIR PREFIX "${LLVM_LIBRARY_OUTPUT_INTDIR}/..")99 get_clang_resource_dir(FLANG_RT_INSTALL_RESOURCE_PATH_DEFAULT)100 101 extend_path(FLANG_RT_OUTPUT_RESOURCE_LIB_DIR "${FLANG_RT_OUTPUT_RESOURCE_DIR}" "${toolchain_lib_subdir}")102else ()103 # In a standalone runtimes build, do not write into LLVM_BINARY_DIR. It may be104 # read-only and/or shared by multiple runtimes with different build105 # configurations (e.g. Debug/Release). Use the runtime's own lib dir like any106 # non-toolchain library.107 # For the install prefix, still use the resource dir assuming that Flang will108 # be installed there using the same prefix. This is to not have a difference109 # between bootstrap and standalone runtimes builds.110 set(FLANG_RT_OUTPUT_RESOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}")111 set(FLANG_RT_INSTALL_RESOURCE_PATH_DEFAULT "lib${LLVM_LIBDIR_SUFFIX}/clang/${LLVM_VERSION_MAJOR}")112 113 extend_path(FLANG_RT_OUTPUT_RESOURCE_LIB_DIR "${FLANG_RT_OUTPUT_RESOURCE_DIR}" "lib${LLVM_LIBDIR_SUFFIX}")114endif ()115set(FLANG_RT_INSTALL_RESOURCE_PATH "${FLANG_RT_INSTALL_RESOURCE_PATH_DEFAULT}"116 CACHE PATH "Path to install runtime libraries to (default: clang resource dir)")117extend_path(FLANG_RT_INSTALL_RESOURCE_LIB_PATH "${FLANG_RT_INSTALL_RESOURCE_PATH}" "${toolchain_lib_subdir}")118cmake_path(NORMAL_PATH FLANG_RT_OUTPUT_RESOURCE_DIR)119cmake_path(NORMAL_PATH FLANG_RT_INSTALL_RESOURCE_PATH)120# FIXME: For the libflang_rt.so, the toolchain resource lib dir is not a good121# destination because it is not a ld.so default search path.122# The machine where the executable is eventually executed may not be the123# machine where the Flang compiler and its resource dir is installed, so124# setting RPath by the driver is not an solution. It should belong into125# /usr/lib/<triple>/libflang_rt.so, like e.g. libgcc_s.so.126# But the linker as invoked by the Flang driver also requires127# libflang_rt.so to be found when linking and the resource lib dir is128# the only reliable location.129cmake_path(NORMAL_PATH FLANG_RT_OUTPUT_RESOURCE_LIB_DIR)130cmake_path(NORMAL_PATH FLANG_RT_INSTALL_RESOURCE_LIB_PATH)131 132 133#################134# Build Options #135#################136 137# Important: flang-rt user options must be prefixed with "FLANG_RT_". Variables138# with this prefix will be forwarded in bootstrap builds.139 140option(FLANG_RT_INCLUDE_TESTS "Generate build targets for the flang-rt unit and regression-tests." "${LLVM_INCLUDE_TESTS}")141 142# Provide an interface to link against the LLVM libc/libc++ projects directly.143set(FLANG_RT_SUPPORTED_PROVIDERS system llvm)144set(FLANG_RT_LIBC_PROVIDER "system" CACHE STRING "Specify C library to use. Supported values are ${FLANG_RT_SUPPORTED_PROVIDERS}.")145if (NOT "${FLANG_RT_LIBC_PROVIDER}" IN_LIST FLANG_RT_SUPPORTED_PROVIDERS)146 message(FATAL_ERROR "Unsupported library: '${FLANG_RT_RUNTIME_PROVIDER}'. Supported values are ${FLANG_RT_SUPPORTED_PROVIDERS}.")147endif ()148 149set(FLANG_RT_LIBCXX_PROVIDER "system" CACHE STRING "Specify C++ library to use. Supported values are ${FLANG_RT_SUPPORTED_PROVIDERS}.")150if (NOT "${FLANG_RT_LIBCXX_PROVIDER}" IN_LIST FLANG_RT_SUPPORTED_PROVIDERS)151 message(FATAL_ERROR "Unsupported library: '${FLANG_RT_LIBCXX_PROVIDER}'. Supported values are ${FLANG_RT_SUPPORTED_PROVIDERS}.")152endif ()153 154option(FLANG_RT_ENABLE_STATIC "Build Flang-RT as a static library." ON)155if (WIN32)156 # Windows DLL currently not implemented.157 set(FLANG_RT_ENABLE_SHARED OFF)158else ()159 # TODO: Enable by default to increase test coverage, and which version of the160 # library should be the user's choice anyway.161 # Currently, the Flang driver adds `-L"libdir" -lflang_rt` as linker162 # argument, which leaves the choice which library to use to the linker.163 # Since most linkers prefer the shared library, this would constitute a164 # breaking change unless the driver is changed.165 option(FLANG_RT_ENABLE_SHARED "Build Flang-RT as a shared library." OFF)166endif ()167if (NOT FLANG_RT_ENABLE_STATIC AND NOT FLANG_RT_ENABLE_SHARED)168 message(FATAL_ERROR "169 Must build at least one type of library170 (FLANG_RT_ENABLE_STATIC=ON, FLANG_RT_ENABLE_SHARED=ON, or both)171 ")172endif ()173 174 175set(FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT "" CACHE STRING "Compile Flang-RT with GPU support (CUDA or OpenMP)")176set_property(CACHE FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT PROPERTY STRINGS177 ""178 CUDA179 OpenMP180 )181if (NOT FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT)182 # Support for GPUs disabled183elseif (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA")184 # Support for CUDA185 set(FLANG_RT_LIBCUDACXX_PATH "" CACHE PATH "Path to libcu++ package installation")186 option(FLANG_RT_CUDA_RUNTIME_PTX_WITHOUT_GLOBAL_VARS "Do not compile global variables' definitions when producing PTX library" OFF)187elseif (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "OpenMP")188 # Support for OpenMP offloading189 set(FLANG_RT_DEVICE_ARCHITECTURES "all" CACHE STRING190 "List of OpenMP device architectures to be used to compile the Fortran runtime (e.g. 'gfx1103;sm_90')"191 )192 193 if (FLANG_RT_DEVICE_ARCHITECTURES STREQUAL "all")194 # TODO: support auto detection on the build system.195 set(all_amdgpu_architectures196 "gfx700;gfx701;gfx801;gfx803;gfx900;gfx902;gfx906"197 "gfx908;gfx90a;gfx90c;gfx940;gfx1010;gfx1030"198 "gfx1031;gfx1032;gfx1033;gfx1034;gfx1035;gfx1036"199 "gfx1100;gfx1101;gfx1102;gfx1103;gfx1150;gfx1151"200 "gfx1152;gfx1153")201 set(all_nvptx_architectures202 "sm_35;sm_37;sm_50;sm_52;sm_53;sm_60;sm_61;sm_62"203 "sm_70;sm_72;sm_75;sm_80;sm_86;sm_89;sm_90")204 set(all_gpu_architectures205 "${all_amdgpu_architectures};${all_nvptx_architectures}")206 set(FLANG_RT_DEVICE_ARCHITECTURES ${all_gpu_architectures})207 endif()208 list(REMOVE_DUPLICATES FLANG_RT_DEVICE_ARCHITECTURES)209else ()210 message(FATAL_ERROR "Invalid value '${FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT}' for FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT; must be empty, 'CUDA', or 'OpenMP'")211endif ()212 213 214option(FLANG_RT_INCLUDE_CUF "Build the CUDA Fortran runtime (libflang_rt.cuda.a)" OFF)215if (FLANG_RT_INCLUDE_CUF)216 find_package(CUDAToolkit REQUIRED)217endif()218 219 220########################221# System Introspection #222########################223 224include(CheckCXXSymbolExists)225include(CheckCXXSourceCompiles)226check_cxx_symbol_exists(strerror_r string.h HAVE_STRERROR_R)227# Can't use symbol exists here as the function is overloaded in C++228check_cxx_source_compiles(229 "#include <string.h>230 int main() {231 char buf[4096];232 return strerror_s(buf, 4096, 0);233 }234 "235 HAVE_DECL_STRERROR_S)236 237# Search for clang_rt.builtins library. Need in addition to msvcrt.238if (WIN32)239 find_compiler_rt_library(builtins FLANG_RT_BUILTINS_LIBRARY)240endif ()241 242# Build with _XOPEN_SOURCE on AIX to avoid errors caused by _ALL_SOURCE.243# We need to enable the large-file API as well.244if (UNIX AND CMAKE_SYSTEM_NAME MATCHES "AIX")245 add_compile_definitions(_XOPEN_SOURCE=700)246 add_compile_definitions(_LARGE_FILE_API)247endif ()248 249# Check whether the compiler can undefine a macro using the "-Wp,-U" flag.250# Aternatively, we could use251# CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU"252# but some older versions of CMake don't define it for GCC itself.253check_cxx_compiler_flag("-Wp,-UTESTFLAG" FLANG_RT_SUPPORTS_UNDEFINE_FLAG)254 255# Check whether -fno-lto is supported.256check_cxx_compiler_flag(-fno-lto FLANG_RT_HAS_FNO_LTO_FLAG)257 258# Check whether -nostdlibinc is supported.259check_cxx_compiler_flag(-nostdlibinc FLANG_RT_HAS_NOSTDLIBINC_FLAG)260 261# Check whether -nostdlib is supported.262check_cxx_compiler_flag(-nostdlib FLANG_RT_HAS_NOSTDLIB_FLAG)263 264# Check whether -stdlib= is supported.265check_cxx_compiler_flag(-stdlib=platform FLANG_RT_HAS_STDLIB_FLAG)266 267# Check whether -Wl,--as-needed is supported.268check_linker_flag(C "LINKER:--as-needed" LINKER_SUPPORTS_AS_NEEDED)269if (LINKER_SUPPORTS_AS_NEEDED)270 set(LINKER_AS_NEEDED_OPT "LINKER:--as-needed")271endif()272 273# Different platform may have different name for the POSIX thread library.274# For example, libpthread.a on AIX. Search for it as it is needed when275# building the shared flang_rt.runtime.so.276find_package(Threads)277 278# function checks279find_package(Backtrace)280set(HAVE_BACKTRACE ${Backtrace_FOUND})281set(BACKTRACE_HEADER ${Backtrace_HEADER})282 283 284#####################285# Build Preparation #286#####################287 288include(HandleLibs)289 290if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT AND FLANG_RT_INCLUDE_TESTS)291 # If Fortran runtime is built as CUDA library, the linking292 # of targets that link flang-rt must be done293 # with CUDA_RESOLVE_DEVICE_SYMBOLS.294 # CUDA language must be enabled for CUDA_RESOLVE_DEVICE_SYMBOLS295 # to take effect.296 enable_language(CUDA)297endif()298 299 300# C++17 is required for flang-rt; user or other runtimes may override this.301# GTest included later also requires C++17.302set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to")303set(CMAKE_CXX_STANDARD_REQUIRED YES)304 305 306configure_file(cmake/config.h.cmake.in config.h)307if (FLANG_INCLUDE_QUADMATH_H)308 configure_file("cmake/quadmath_wrapper.h.in" "${FLANG_RT_BINARY_DIR}/quadmath_wrapper.h")309endif ()310 311# The bootstrap build will create a phony target with the same as the top-level312# directory ("flang-rt") and delegate it to the runtimes build dir.313# AddFlangRT will add all non-EXCLUDE_FROM_ALL targets to it.314add_custom_target(flang-rt)315 316 317###################318# Build Artifacts #319###################320 321add_subdirectory(lib)322 323if (LLVM_INCLUDE_EXAMPLES)324 add_subdirectory(examples)325endif ()326 327if (FLANG_RT_INCLUDE_TESTS)328 add_subdirectory(test)329 add_subdirectory(unittests)330else ()331 add_custom_target(check-flang-rt)332endif()333 334###################335# Install headers #336###################337 338if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)339 add_llvm_install_targets(install-flang-rt-headers COMPONENT flang-rt-headers)340 341 install(DIRECTORY include/flang-rt/runtime342 DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang-rt"343 COMPONENT flang-rt-headers344 FILES_MATCHING345 PATTERN "*.h"346 PATTERN ".git" EXCLUDE347 PATTERN "CMakeFiles" EXCLUDE)348endif()349