blob: b3b6e00f7c0c8ce4c3d35967f10570688448e982 [file] [log] [blame]
Michael Kruseb55f7512025-02-16 14:39:521#===-- 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-exception
6#
7#===------------------------------------------------------------------------===#
8#
9# Build instructions for the flang-rt library. This is file is intended to be
10# 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-rt
18 ")
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_SOURCE
41 "<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_PATH
62 "${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 a
77# 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 install
88# 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 the
92 # build directory of the just-built compiler. This allows using the
93 # just-built compiler without specifying paths to runtime libraries.
94 #
95 # Despite Clang in the name, get_clang_resource_dir does not depend on Clang
96 # 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}/..")
Michał Górnyd254fa82025-02-25 08:47:4799 get_clang_resource_dir(FLANG_RT_INSTALL_RESOURCE_PATH_DEFAULT)
Michael Kruseb55f7512025-02-16 14:39:52100
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 be
104 # read-only and/or shared by multiple runtimes with different build
105 # configurations (e.g. Debug/Release). Use the runtime's own lib dir like any
106 # non-toolchain library.
107 # For the install prefix, still use the resource dir assuming that Flang will
108 # be installed there using the same prefix. This is to not have a difference
109 # between bootstrap and standalone runtimes builds.
110 set(FLANG_RT_OUTPUT_RESOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
Michał Górnyd254fa82025-02-25 08:47:47111 set(FLANG_RT_INSTALL_RESOURCE_PATH_DEFAULT "lib${LLVM_LIBDIR_SUFFIX}/clang/${LLVM_VERSION_MAJOR}")
Michael Kruseb55f7512025-02-16 14:39:52112
113 extend_path(FLANG_RT_OUTPUT_RESOURCE_LIB_DIR "${FLANG_RT_OUTPUT_RESOURCE_DIR}" "lib${LLVM_LIBDIR_SUFFIX}")
114endif ()
Michał Górnyd254fa82025-02-25 08:47:47115set(FLANG_RT_INSTALL_RESOURCE_PATH "${FLANG_RT_INSTALL_RESOURCE_PATH_DEFAULT}"
116 CACHE PATH "Path to install runtime libraries to (default: clang resource dir)")
Michael Kruseb55f7512025-02-16 14:39:52117extend_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)
Michael Kruse4c4fc462025-02-17 11:53:12120# FIXME: For the libflang_rt.so, the toolchain resource lib dir is not a good
121# destination because it is not a ld.so default search path.
122# The machine where the executable is eventually executed may not be the
123# machine where the Flang compiler and its resource dir is installed, so
124# setting RPath by the driver is not an solution. It should belong into
125# /usr/lib/<triple>/libflang_rt.so, like e.g. libgcc_s.so.
126# But the linker as invoked by the Flang driver also requires
127# libflang_rt.so to be found when linking and the resource lib dir is
128# the only reliable location.
Michael Kruseb55f7512025-02-16 14:39:52129cmake_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_". Variables
138# 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
Joseph Huber038cdd22025-03-24 11:05:24142# 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 ()
Michael Kruseb55f7512025-02-16 14:39:52153
Michael Kruse4c4fc462025-02-17 11:53:12154option(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 the
160 # library should be the user's choice anyway.
161 # Currently, the Flang driver adds `-L"libdir" -lflang_rt` as linker
162 # argument, which leaves the choice which library to use to the linker.
163 # Since most linkers prefer the shared library, this would constitute a
164 # 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 library
170 (FLANG_RT_ENABLE_STATIC=ON, FLANG_RT_ENABLE_SHARED=ON, or both)
171 ")
172endif ()
173
174
Michael Kruseb55f7512025-02-16 14:39:52175set(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 STRINGS
177 ""
178 CUDA
179 OpenMP
180 )
181if (NOT FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT)
182 # Support for GPUs disabled
183elseif (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA")
184 # Support for CUDA
185 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 offloading
189 set(FLANG_RT_DEVICE_ARCHITECTURES "all" CACHE STRING
190 "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_architectures
196 "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_architectures
202 "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_architectures
205 "${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
Joseph Huber85974a02025-03-24 13:31:42224# The GPU targets require a few mandatory arguments to make the standard CMake
225# check flags happy.
Joseph Hubera5cdbef2025-04-22 13:08:26226if ("${LLVM_RUNTIMES_TARGET}" MATCHES "^amdgcn")
Joseph Huber85974a02025-03-24 13:31:42227 set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nogpulib")
Joseph Hubera5cdbef2025-04-22 13:08:26228elseif ("${LLVM_RUNTIMES_TARGET}" MATCHES "^nvptx")
Joseph Huber85974a02025-03-24 13:31:42229 set(CMAKE_REQUIRED_FLAGS
230 "${CMAKE_REQUIRED_FLAGS} -flto -c -Wno-unused-command-line-argument")
231endif()
232
Michael Kruseb55f7512025-02-16 14:39:52233include(CheckCXXSymbolExists)
234include(CheckCXXSourceCompiles)
235check_cxx_symbol_exists(strerror_r string.h HAVE_STRERROR_R)
236# Can't use symbol exists here as the function is overloaded in C++
237check_cxx_source_compiles(
238 "#include <string.h>
239 int main() {
240 char buf[4096];
241 return strerror_s(buf, 4096, 0);
242 }
243 "
244 HAVE_DECL_STRERROR_S)
245
Michael Kruseb55f7512025-02-16 14:39:52246# Search for clang_rt.builtins library. Need in addition to msvcrt.
247if (WIN32)
248 find_compiler_rt_library(builtins FLANG_RT_BUILTINS_LIBRARY)
249endif ()
250
Kelvin Li7262a1e2025-02-24 15:03:26251# Build with _XOPEN_SOURCE on AIX to avoid errors caused by _ALL_SOURCE.
252# We need to enable the large-file API as well.
253if (UNIX AND CMAKE_SYSTEM_NAME MATCHES "AIX")
254 add_compile_definitions(_XOPEN_SOURCE=700)
255 add_compile_definitions(_LARGE_FILE_API)
256endif ()
Michael Kruseb55f7512025-02-16 14:39:52257
258# Check whether the compiler can undefine a macro using the "-U" flag.
259# Aternatively, we could use
260# CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU"
261# but some older versions of CMake don't define it for GCC itself.
262check_cxx_compiler_flag("-UTESTFLAG" FLANG_RT_SUPPORTS_UNDEFINE_FLAG)
263
264# Check whether -fno-lto is supported.
265check_cxx_compiler_flag(-fno-lto FLANG_RT_HAS_FNO_LTO_FLAG)
266
Joseph Huber038cdd22025-03-24 11:05:24267# Check whether -nostdlibinc is supported.
268check_cxx_compiler_flag(-nostdlibinc FLANG_RT_HAS_NOSTDLIBINC_FLAG)
269
270# Check whether -nostdlib is supported.
271check_cxx_compiler_flag(-nostdlib FLANG_RT_HAS_NOSTDLIB_FLAG)
272
273# Check whether -stdlib= is supported.
274check_cxx_compiler_flag(-stdlib=platform FLANG_RT_HAS_STDLIB_FLAG)
275
Slava Zakharineeb27332025-03-14 15:26:03276# Check whether -Wl,--as-needed is supported.
277check_linker_flag(C "LINKER:--as-needed" LINKER_SUPPORTS_AS_NEEDED)
278if (LINKER_SUPPORTS_AS_NEEDED)
279 set(LINKER_AS_NEEDED_OPT "LINKER:--as-needed")
280endif()
281
Daniel Chen78631ac2025-03-07 19:13:38282# Different platform may have different name for the POSIX thread library.
283# For example, libpthread.a on AIX. Search for it as it is needed when
284# building the shared flang_rt.runtime.so.
285find_package(Threads)
Michael Kruseb55f7512025-02-16 14:39:52286
287# function checks
288find_package(Backtrace)
289set(HAVE_BACKTRACE ${Backtrace_FOUND})
290set(BACKTRACE_HEADER ${Backtrace_HEADER})
291
292
293#####################
294# Build Preparation #
295#####################
296
Joseph Huber038cdd22025-03-24 11:05:24297include(HandleLibs)
298
Michael Kruseb55f7512025-02-16 14:39:52299if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT AND FLANG_RT_INCLUDE_TESTS)
300 # If Fortran runtime is built as CUDA library, the linking
301 # of targets that link flang-rt must be done
302 # with CUDA_RESOLVE_DEVICE_SYMBOLS.
303 # CUDA language must be enabled for CUDA_RESOLVE_DEVICE_SYMBOLS
304 # to take effect.
305 enable_language(CUDA)
306endif()
307
308
309# C++17 is required for flang-rt; user or other runtimes may override this.
310# GTest included later also requires C++17.
311set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to")
312set(CMAKE_CXX_STANDARD_REQUIRED YES)
313
314
315configure_file(cmake/config.h.cmake.in config.h)
Slava Zakharin613a0772025-03-25 19:08:38316if (FLANG_INCLUDE_QUADMATH_H)
Michael Kruse73417532025-03-11 13:18:06317 configure_file("cmake/quadmath_wrapper.h.in" "${FLANG_RT_BINARY_DIR}/quadmath_wrapper.h")
318endif ()
Michael Kruseb55f7512025-02-16 14:39:52319
320# The bootstrap build will create a phony target with the same as the top-level
321# directory ("flang-rt") and delegate it to the runtimes build dir.
322# AddFlangRT will add all non-EXCLUDE_FROM_ALL targets to it.
323add_custom_target(flang-rt)
324
325
326###################
327# Build Artifacts #
328###################
329
330add_subdirectory(lib)
331
332if (LLVM_INCLUDE_EXAMPLES)
333 add_subdirectory(examples)
334endif ()
335
336if (FLANG_RT_INCLUDE_TESTS)
337 add_subdirectory(unittests)
338 add_subdirectory(test)
339else ()
340 add_custom_target(check-flang-rt)
341endif()