0
0
mirror of https://github.com/llvm/llvm-project.git synced 2025-04-21 19:57:00 +00:00

[Flang] LLVM_ENABLE_RUNTIMES=flang-rt ()

Extract Flang's runtime library to use the LLVM_ENABLE_RUNTIME
mechanism. It will only become active when
`LLVM_ENABLE_RUNTIMES=flang-rt` is used, which also changes the
`FLANG_INCLUDE_RUNTIME` to `OFF` so the old runtime build rules do not
conflict. This also means that unless `LLVM_ENABLE_RUNTIMES=flang-rt` is
passed, nothing changes with the current build process.

Motivation:
* Consistency with LLVM's other runtime libraries (compiler-rt, libc,
libcxx, openmp offload, ...)
* Allows compiling the runtime for multiple targets at once using the
LLVM_RUNTIME_TARGETS configuration options
* Installs the runtime into the compiler's per-target resource directory
so it can be automatically found even when cross-compiling

Also see RFC discussion at
https://discourse.llvm.org/t/rfc-use-llvm-enable-runtimes-for-flangs-runtime/80826
This commit is contained in:
Michael Kruse 2025-02-16 15:39:52 +01:00 committed by GitHub
parent 17d508f30d
commit b55f7512a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
41 changed files with 2207 additions and 140 deletions

2
flang-rt/.clang-tidy Normal file

@ -0,0 +1,2 @@
Checks: '-llvm-include-order,readability-braces-around-statements,-readability-identifier-naming,-clang-diagnostic-*'
InheritParentConfig: true

261
flang-rt/CMakeLists.txt Normal file

@ -0,0 +1,261 @@
#===-- 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 <llvm-project>/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-new" OR _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
"<CMAKE_Fortran_COMPILER> -cpp <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
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)
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 #
############################
# Determine whether we are in the runtimes/runtimes-bins directory of a
# bootstrap build.
set(LLVM_TREE_AVAILABLE OFF)
if (LLVM_LIBRARY_OUTPUT_INTDIR AND LLVM_RUNTIME_OUTPUT_INTDIR AND PACKAGE_VERSION)
set(LLVM_TREE_AVAILABLE ON)
endif()
# Path to LLVM development tools (FileCheck, llvm-lit, not, ...)
set(LLVM_TOOLS_DIR "${LLVM_BINARY_DIR}/bin")
# Determine build and install paths.
# The build path is absolute, but the install dir is relative, CMake's install
# command has to apply CMAKE_INSTALL_PREFIX itself.
get_toolchain_library_subdir(toolchain_lib_subdir)
if (LLVM_TREE_AVAILABLE)
# In a bootstrap build emit the libraries into a default search path in the
# build directory of the just-built compiler. This allows using the
# just-built compiler without specifying paths to runtime libraries.
#
# Despite Clang in the name, get_clang_resource_dir does not depend on Clang
# being added to the build. Flang uses the same resource dir as clang.
include(GetClangResourceDir)
get_clang_resource_dir(FLANG_RT_OUTPUT_RESOURCE_DIR PREFIX "${LLVM_LIBRARY_OUTPUT_INTDIR}/..")
get_clang_resource_dir(FLANG_RT_INSTALL_RESOURCE_PATH)
extend_path(FLANG_RT_OUTPUT_RESOURCE_LIB_DIR "${FLANG_RT_OUTPUT_RESOURCE_DIR}" "${toolchain_lib_subdir}")
else ()
# In a standalone runtimes build, do not write into LLVM_BINARY_DIR. It may be
# read-only and/or shared by multiple runtimes with different build
# configurations (e.g. Debug/Release). Use the runtime's own lib dir like any
# non-toolchain library.
# For the install prefix, still use the resource dir assuming that Flang will
# be installed there using the same prefix. This is to not have a difference
# between bootstrap and standalone runtimes builds.
set(FLANG_RT_OUTPUT_RESOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
set(FLANG_RT_INSTALL_RESOURCE_PATH "lib${LLVM_LIBDIR_SUFFIX}/clang/${LLVM_VERSION_MAJOR}")
extend_path(FLANG_RT_OUTPUT_RESOURCE_LIB_DIR "${FLANG_RT_OUTPUT_RESOURCE_DIR}" "lib${LLVM_LIBDIR_SUFFIX}")
endif ()
extend_path(FLANG_RT_INSTALL_RESOURCE_LIB_PATH "${FLANG_RT_INSTALL_RESOURCE_PATH}" "${toolchain_lib_subdir}")
cmake_path(NORMAL_PATH FLANG_RT_OUTPUT_RESOURCE_DIR)
cmake_path(NORMAL_PATH FLANG_RT_INSTALL_RESOURCE_PATH)
cmake_path(NORMAL_PATH FLANG_RT_OUTPUT_RESOURCE_LIB_DIR)
cmake_path(NORMAL_PATH FLANG_RT_INSTALL_RESOURCE_LIB_PATH)
#################
# Build Options #
#################
# Important: flang-rt user options must be prefixed with "FLANG_RT_". Variables
# with this prefix will be forwarded in bootstrap builds.
option(FLANG_RT_INCLUDE_TESTS "Generate build targets for the flang-rt unit and regression-tests." "${LLVM_INCLUDE_TESTS}")
set(FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT "" CACHE STRING "Compile Flang-RT with GPU support (CUDA or OpenMP)")
set_property(CACHE FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT PROPERTY STRINGS
""
CUDA
OpenMP
)
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)
elseif (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "OpenMP")
# Support for OpenMP offloading
set(FLANG_RT_DEVICE_ARCHITECTURES "all" CACHE STRING
"List of OpenMP device architectures to be used to compile the Fortran runtime (e.g. 'gfx1103;sm_90')"
)
if (FLANG_RT_DEVICE_ARCHITECTURES STREQUAL "all")
# TODO: support auto detection on the build system.
set(all_amdgpu_architectures
"gfx700;gfx701;gfx801;gfx803;gfx900;gfx902;gfx906"
"gfx908;gfx90a;gfx90c;gfx940;gfx1010;gfx1030"
"gfx1031;gfx1032;gfx1033;gfx1034;gfx1035;gfx1036"
"gfx1100;gfx1101;gfx1102;gfx1103;gfx1150;gfx1151"
"gfx1152;gfx1153")
set(all_nvptx_architectures
"sm_35;sm_37;sm_50;sm_52;sm_53;sm_60;sm_61;sm_62"
"sm_70;sm_72;sm_75;sm_80;sm_86;sm_89;sm_90")
set(all_gpu_architectures
"${all_amdgpu_architectures};${all_nvptx_architectures}")
set(FLANG_RT_DEVICE_ARCHITECTURES ${all_gpu_architectures})
endif()
list(REMOVE_DUPLICATES FLANG_RT_DEVICE_ARCHITECTURES)
else ()
message(FATAL_ERROR "Invalid value '${FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT}' for FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT; must be empty, 'CUDA', or 'OpenMP'")
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()
########################
# 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 <string.h>
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 ()
# Check whether the compiler can undefine a macro using the "-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("-UTESTFLAG" FLANG_RT_SUPPORTS_UNDEFINE_FLAG)
# Check whether -fno-lto is supported.
check_cxx_compiler_flag(-fno-lto FLANG_RT_HAS_FNO_LTO_FLAG)
# function checks
find_package(Backtrace)
set(HAVE_BACKTRACE ${Backtrace_FOUND})
set(BACKTRACE_HEADER ${Backtrace_HEADER})
#####################
# Build Preparation #
#####################
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)
# 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(unittests)
add_subdirectory(test)
else ()
add_custom_target(check-flang-rt)
endif()

14
flang-rt/CODE_OWNERS.TXT Normal file

@ -0,0 +1,14 @@
This file is a list of the people responsible for ensuring that patches for a
particular part of Flang are reviewed, either by themself or by someone else.
They are also the gatekeepers for their part of Flang, with the final word on
what goes in or not.
The list is sorted by surname and formatted to allow easy grepping and
beautification by scripts. The fields are: name (N), email (E), web-address
(W), PGP key ID and fingerprint (P), description (D), snail-mail address
(S) and (I) IRC handle. Each entry should contain at least the (N), (E) and
(D) fields.
N: Steve Scalpone
E: sscalpone@nvidia.com
D: Anything not covered by others

234
flang-rt/LICENSE.TXT Normal file

@ -0,0 +1,234 @@
==============================================================================
The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
==============================================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
---- LLVM Exceptions to the Apache 2.0 License ----
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into an Object form of such source code, you
may redistribute such embedded portions in such Object form without complying
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
In addition, if you combine or link compiled forms of this Software with
software that is licensed under the GPLv2 ("Combined Software") and if a
court of competent jurisdiction determines that the patent provision (Section
3), the indemnity provision (Section 9) or other Section of the License
conflicts with the conditions of the GPLv2, you may retroactively and
prospectively choose to deem waived or otherwise exclude such Section(s) of
the License, but only in their entirety and only with respect to the Combined
Software.
==============================================================================
Software from third parties included in the LLVM Project:
==============================================================================
The LLVM Project contains third party software which is under different license
terms. All such code will be identified clearly using at least one of two
mechanisms:
1) It will be in a separate directory tree with its own `LICENSE.txt` or
`LICENSE` file at the top containing the specific license and restrictions
which apply to that software, or
2) It will contain specific license and restriction terms at the top of every
file.

188
flang-rt/README.md Normal file

@ -0,0 +1,188 @@
<!--===- README.md
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
-->
# Fortran Runtime (Flang-RT)
Flang-RT is the runtime library for code emitted by the Flang compiler
(https://flang.llvm.org).
## Getting Started
There are two build modes for the Flang-RT. The bootstrap build, also
called the in-tree build, and the runtime-only build, also called the
out-of-tree build.
Not to be confused with the terms
[in-source and out-of-source](https://cmake.org/cmake/help/latest/manual/cmake.1.html#introduction-to-cmake-buildsystems)
builds as defined by CMake. In an in-source build, the source directory and the
build directory are identical, whereas with an out-of-source build the
build artifacts are stored somewhere else, possibly in a subdirectory of the
source directory. LLVM does not support in-source builds.
### Requirements
Requirements:
* [Same as LLVM](https://llvm.org/docs/GettingStarted.html#requirements).
### Bootstrapping Runtimes Build
The bootstrapping build will first build Clang and Flang, then use these
compilers to compile Flang-RT. CMake will create a secondary build tree
configured to use these just-built compilers. The secondary build will reuse
the same build options (Flags, Debug/Release, ...) as the primary build.
It will also ensure that once built, Flang-RT is found by Flang from either
the build- or install-prefix. To enable, add `flang-rt` to
`LLVM_ENABLE_RUNTIMES`:
```bash
cmake -S <path-to-llvm-project-source>/llvm \
-GNinja \
-DLLVM_ENABLE_PROJECTS="clang;flang" \
-DLLVM_ENABLE_RUNTIMES=flang-rt \
...
```
It is recommended to enable building OpenMP alongside Flang and Flang-RT
as well. This will build `omp_lib.mod` required to use OpenMP from Fortran.
Building Compiler-RT may also be required, particularly on platforms that do
not provide all C-ABI functionality (such as Windows).
```bash
cmake -S <path-to-llvm-project-source>/llvm \
-GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="clang;flang;openmp" \
-DLLVM_ENABLE_RUNTIMES="compiler-rt;flang-rt" \
...
```
By default, the enabled runtimes will only be built for the host platform
(`-DLLVM_RUNTIME_TARGETS=default`). To add additional targets to support
cross-compilation via `flang --target=<target-triple>`, add more triples to
`LLVM_RUNTIME_TARGETS`, such as
`-DLLVM_RUNTIME_TARGETS="default;aarch64-linux-gnu"`.
After configuration, build, test, and install the runtime(s) via
```shell
$ ninja flang-rt
$ ninja check-flang-rt
$ ninja install
```
### Standalone Runtimes Build
Instead of building Clang and Flang from scratch, the standalone Runtime build
uses CMake's environment introspection to find a C, C++, and Fortran compiler.
The compiler to be used can be controlled using CMake's standard mechanisms such
as `CMAKE_CXX_COMPILER`, `CMAKE_CXX_COMPILER`, and `CMAKE_Fortran_COMPILER`.
`CMAKE_Fortran_COMPILER` must be `flang` built from the same Git commit as
Flang-RT to ensure they are using the same ABI. The C and C++ compiler
can be any compiler supporting the same ABI.
In addition to the compiler, the build be able to find LLVM development tools
such as `lit` and `FileCheck` that are not found in an LLVM's install
directory. Use `CMAKE_BINARY_DIR` to point to directory where LLVM has
been built. A simple build configuration might look like the following:
```bash
cmake -S <path-to-llvm-project-source>/runtimes \
-GNinja \
-DLLVM_BINARY_DIR=<path-to-llvm-builddir> \
-DCMAKE_Fortran_COMPILER=<path-to-llvm-builddir>/bin/flang \
-DCMAKE_Fortran_COMPILER_WORKS=yes \
-DLLVM_ENABLE_RUNTIMES=flang-rt \
...
```
The `CMAKE_Fortran_COMPILER_WORKS` parameter must be set because otherwise CMake
will test whether the Fortran compiler can compile and link programs which will
obviously fail without a runtime library available yet.
Building Flang-RT for cross-compilation triple, the target triple can
be selected using `LLVM_DEFAULT_TARGET_TRIPLE` AND `LLVM_RUNTIMES_TARGET`.
Of course, Flang-RT can be built multiple times with different build
configurations, but have to be located manually when using with the Flang
driver using the `-L` option.
After configuration, build, test, and install the runtime via
```shell
$ ninja
$ ninja check-flang-rt
$ ninja install
```
## Configuration Option Reference
Flang-RT has the followign configuration options. This is in
addition to the build options the LLVM_ENABLE_RUNTIMES mechanism and
CMake itself provide.
* `FLANG_RT_INCLUDE_TESTS` (boolean; default: `ON`)
When `OFF`, does not add any tests and unittests. The `check-flang-rt`
build target will do nothing.
* `FLANG_RUNTIME_F128_MATH_LIB` (default: `""`)
Determines the implementation of `REAL(16)` math functions. If set to
`libquadmath`, uses `quadmath.h` and `-lquadmath` typically distributed with
gcc. If empty, disables `REAL(16)` support. For any other value, introspects
the compiler for `__float128` or 128-bit `long double` support.
[More details](docs/Real16MathSupport.md).
* `FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT` (values: `"CUDA"`,`"OpenMP"`, `""` default: `""`)
When set to `CUDA`, builds Flang-RT with experimental support for GPU
accelerators using CUDA. `CMAKE_CUDA_COMPILER` must be set if not
automatically detected by CMake. `nvcc` as well as `clang` are supported.
When set to `OpenMP`, builds Flang-RT with experimental support for
GPU accelerators using OpenMP offloading. Only Clang is supported for
`CMAKE_C_COMPILER` and `CMAKE_CXX_COMPILER`.
* `FLANG_RT_INCLUDE_CUF` (bool, default: `OFF`)
Compiles the `libflang_rt.cuda_<CUDA-version>.a/.so` library. This is
independent of `FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA` and only
requires a
[CUDA Toolkit installation](https://cmake.org/cmake/help/latest/module/FindCUDAToolkit.html)
(no `CMAKE_CUDA_COMPILER`).
### Experimental CUDA Support
With `-DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA`, the following
additional configuration options become available.
* `FLANG_RT_LIBCUDACXX_PATH` (path, default: `""`)
Path to libcu++ package installation.
* `FLANG_RT_CUDA_RUNTIME_PTX_WITHOUT_GLOBAL_VARS` (boolean, default: `OFF`)
Do not compile global variables' definitions when producing PTX library.
Default is `OFF`, meaning global variable definitions are compiled by
default.
### Experimental OpenMP Offload Support
With `-DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=OpenMP`, the following
additional configuration options become available.
* `FLANG_RT_DEVICE_ARCHITECTURES` (default: `"all"`)
A list of device architectures that Flang-RT is going to support.
If `"all"` uses a pre-defined list of architectures. Same purpose as
`LIBOMPTARGET_DEVICE_ARCHITECTURES` from liboffload.

@ -16,4 +16,9 @@
don't. */
#cmakedefine01 HAVE_DECL_STRERROR_S
/* Define to 1 if you have the `backtrace' function. */
#cmakedefine HAVE_BACKTRACE ${HAVE_BACKTRACE}
#define BACKTRACE_HEADER <${BACKTRACE_HEADER}>
#endif

@ -0,0 +1,199 @@
#===-- cmake/modules/AddFlangRT.cmake --------------------------------------===#
#
# 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
#
#===------------------------------------------------------------------------===#
# Builds a library with common options for Flang-RT.
#
# Usage:
#
# add_flangrt_library(name sources ...
# SHARED
# Build a dynamic (.so/.dll) library
# STATIC
# Build a static (.a/.lib) library
# OBJECT
# Create only object files without static/dynamic library
# INSTALL_WITH_TOOLCHAIN
# Install library into Clang's resource directory so it can be found by the
# Flang driver during compilation, including tests
# EXCLUDE_FROM_ALL
# Do not build library by default; typically used for libraries needed for
# testing only, no install
# LINK_TO_LLVM
# Library requires include path and linking to LLVM's Support component
# ADDITIONAL_HEADERS
# May specify header files for IDE generators.
# INCLUDE_DIRECTORIES
# Additional target_include_directories for all added targets
# LINK_LIBRARIES
# Additional target_link_libraries for all added targets
# TARGET_PROPERTIES
# Set target properties of all added targets
# )
function (add_flangrt_library name)
set(options STATIC SHARED OBJECT INSTALL_WITH_TOOLCHAIN EXCLUDE_FROM_ALL LINK_TO_LLVM)
set(multiValueArgs ADDITIONAL_HEADERS INCLUDE_DIRECTORIES LINK_LIBRARIES TARGET_PROPERTIES)
cmake_parse_arguments(ARG
"${options}"
""
"${multiValueArgs}"
${ARGN})
if (ARG_INSTALL_WITH_TOOLCHAIN AND ARG_EXCLUDE_FROM_ALL)
message(SEND_ERROR "add_flangrt_library(${name} ...):
INSTALL_WITH_TOOLCHAIN and EXCLUDE_FROM_ALL are in conflict. When
installing an artifact it must have been built first in the 'all' target.
")
endif ()
# Forward libtype to add_library
set(extra_args "")
if (ARG_SHARED)
list(APPEND extra_args SHARED)
endif ()
if (ARG_STATIC)
list(APPEND extra_args STATIC)
endif ()
if (ARG_OBJECT)
list(APPEND extra_args OBJECT)
endif ()
if (ARG_EXCLUDE_FROM_ALL)
list(APPEND extra_args EXCLUDE_FROM_ALL)
endif ()
# Also add header files to IDEs to list as part of the library.
set_source_files_properties(${ARG_ADDITIONAL_HEADERS} PROPERTIES HEADER_FILE_ONLY ON)
add_library(${name} ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})
if (ARG_INSTALL_WITH_TOOLCHAIN)
set_target_properties(${name} PROPERTIES FOLDER "Flang-RT/Toolchain Libraries")
elseif (ARG_OBJECT)
set_target_properties(${name} PROPERTIES FOLDER "Flang-RT/Object Libraries")
else ()
set_target_properties(${name} PROPERTIES FOLDER "Flang-RT/Libraries")
endif ()
# Minimum required C++ version for Flang-RT, even if CMAKE_CXX_STANDARD is defined to something else.
target_compile_features(${name} PRIVATE cxx_std_17)
# Use compiler-specific options to disable exceptions and RTTI.
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
target_compile_options(${name} PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
)
elseif (MSVC)
target_compile_options(${name} PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:/EHs-c- /GR->
)
elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
target_compile_options(${name} PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-qnoeh -qnortti>
)
endif ()
# Also for CUDA source when compiling with FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA
if (CMAKE_CUDA_COMPILER_ID MATCHES "NVIDIA")
# Assuming gcc as host compiler.
target_compile_options(${name} PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:--no-exceptions -Xcompiler -fno-rtti -Xcompiler -fno-unwind-tables -Xcompiler -fno-asynchronous-unwind-tables>
)
else ()
# Assuming a clang-compatible CUDA compiler.
target_compile_options(${name} PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
)
endif ()
# Flang-RT's public headers
target_include_directories(${name} PUBLIC "${FLANG_RT_SOURCE_DIR}/include")
# For ISO_Fortran_binding.h to be found by the runtime itself (Accessed as #include "flang/ISO_Fortran_binding.h")
# User applications can use #include <ISO_Fortran_binding.h>
target_include_directories(${name} PUBLIC "${FLANG_SOURCE_DIR}/include")
# For Flang-RT's configured config.h to be found
target_include_directories(${name} PRIVATE "${FLANG_RT_BINARY_DIR}")
# Disable libstdc++/libc++ assertions, even in an LLVM_ENABLE_ASSERTIONS
# build, to avoid an unwanted dependency on libstdc++/libc++.so.
if (FLANG_RT_SUPPORTS_UNDEFINE_FLAG)
target_compile_options(${name} PUBLIC -U_GLIBCXX_ASSERTIONS)
target_compile_options(${name} PUBLIC -U_LIBCPP_ENABLE_ASSERTIONS)
endif ()
# When building the flang runtime if LTO is enabled the archive file
# contains LLVM IR rather than object code. Currently flang is not
# LTO aware so cannot link this file to compiled Fortran code.
if (FLANG_RT_HAS_FNO_LTO_FLAG)
target_compile_options(${name} PRIVATE -fno-lto)
endif ()
# Flang/Clang (including clang-cl) -compiled programs targeting the MSVC ABI
# should only depend on msvcrt/ucrt. LLVM still emits libgcc/compiler-rt
# functions in some cases like 128-bit integer math (__udivti3, __modti3,
# __fixsfti, __floattidf, ...) that msvc does not support. We are injecting a
# dependency to Compiler-RT's builtin library where these are implemented.
if (MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if (FLANG_RT_BUILTINS_LIBRARY)
target_compile_options(${name} PRIVATE "$<$<COMPILE_LANGUAGE:CXX,C>:-Xclang>" "$<$<COMPILE_LANGUAGE:CXX,C>:--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}>")
endif ()
endif ()
if (MSVC AND CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
if (FLANG_RT_BUILTINS_LIBRARY)
target_compile_options(${name} PRIVATE "$<$<COMPILE_LANGUAGE:Fortran>:-Xflang>" "$<$<COMPILE_LANGUAGE:Fortran>:--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}>")
else ()
message(WARNING "Did not find libclang_rt.builtins.lib.
LLVM may emit builtins that are not implemented in msvcrt/ucrt and
instead falls back to builtins from Compiler-RT. Linking with ${name}
may result in a linker error.")
endif ()
endif ()
# Non-GTest unittests depend on LLVMSupport
if (ARG_LINK_TO_LLVM)
if (LLVM_LINK_LLVM_DYLIB)
set(llvm_libs LLVM)
else()
llvm_map_components_to_libnames(llvm_libs Support)
endif()
target_link_libraries(${name} PUBLIC ${llvm_libs})
target_include_directories(${name} PUBLIC ${LLVM_INCLUDE_DIRS})
endif ()
if (ARG_INCLUDE_DIRECTORIES)
target_include_directories(${name} ${ARG_INCLUDE_DIRECTORIES})
endif ()
if (ARG_LINK_LIBRARIES)
target_link_libraries(${name} PUBLIC ${ARG_LINK_LIBRARIES})
endif ()
# If this is part of the toolchain, put it into the compiler's resource
# directory. Otherwise it is part of testing and is not installed at all.
# TODO: Consider multi-configuration builds (MSVC_IDE, "Ninja Multi-Config")
if (ARG_INSTALL_WITH_TOOLCHAIN)
set_target_properties(${name}
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${FLANG_RT_OUTPUT_RESOURCE_LIB_DIR}"
)
install(TARGETS ${name}
ARCHIVE DESTINATION "${FLANG_RT_INSTALL_RESOURCE_LIB_PATH}"
)
endif ()
if (ARG_TARGET_PROPERTIES)
set_target_properties(${name} PROPERTIES ${ARG_TARGET_PROPERTIES})
endif ()
# flang-rt should build all the Flang-RT targets that are built in an
# 'all' build.
if (NOT ARG_EXCLUDE_FROM_ALL)
add_dependencies(flang-rt ${name})
endif ()
endfunction (add_flangrt_library)

@ -0,0 +1,100 @@
#===-- cmake/modules/AddFlangRTOffload.cmake -------------------------------===#
#
# 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
#
#===------------------------------------------------------------------------===#
macro(enable_cuda_compilation name files)
if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA")
enable_language(CUDA)
set_target_properties(${name}
PROPERTIES
CUDA_SEPARABLE_COMPILATION ON
)
# Treat all supported sources as CUDA files.
set_source_files_properties(${files} PROPERTIES LANGUAGE CUDA)
set(CUDA_COMPILE_OPTIONS)
if ("${CMAKE_CUDA_COMPILER_ID}" MATCHES "Clang")
# Allow varargs.
set(CUDA_COMPILE_OPTIONS
-Xclang -fcuda-allow-variadic-functions
)
endif()
if ("${CMAKE_CUDA_COMPILER_ID}" MATCHES "NVIDIA")
set(CUDA_COMPILE_OPTIONS
--expt-relaxed-constexpr
# Disable these warnings:
# 'long double' is treated as 'double' in device code
-Xcudafe --diag_suppress=20208
-Xcudafe --display_error_number
)
endif()
set_source_files_properties(${files} PROPERTIES COMPILE_OPTIONS
"${CUDA_COMPILE_OPTIONS}")
# Create a .a library consisting of CUDA PTX.
# This is different from a regular static library. The CUDA_PTX_COMPILATION
# property can only be applied to object libraries and create *.ptx files
# instead of *.o files. The .a will consist of those *.ptx files only.
add_flangrt_library(obj.${name}PTX OBJECT ${files})
set_property(TARGET obj.${name}PTX PROPERTY CUDA_PTX_COMPILATION ON)
add_flangrt_library(${name}PTX STATIC "$<TARGET_OBJECTS:obj.${name}PTX>")
# Apply configuration options
if (FLANG_RT_CUDA_RUNTIME_PTX_WITHOUT_GLOBAL_VARS)
target_compile_definitions(obj.${name}PTX
PRIVATE FLANG_RUNTIME_NO_GLOBAL_VAR_DEFS
)
endif()
# When using libcudacxx headers files, we have to use them
# for all files of Flang-RT.
if (EXISTS "${FLANG_RT_LIBCUDACXX_PATH}/include")
foreach (tgt IN ITEMS "${name}" "obj.${name}PTX")
target_include_directories(${tgt} AFTER PRIVATE "${FLANG_RT_LIBCUDACXX_PATH}/include")
target_compile_definitions(${tgt} PRIVATE RT_USE_LIBCUDACXX=1)
endforeach ()
endif ()
endif()
endmacro()
macro(enable_omp_offload_compilation name files)
if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "OpenMP")
# OpenMP offload build only works with Clang compiler currently.
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND
"${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
string(REPLACE ";" "," compile_for_architectures
"${FLANG_RT_DEVICE_ARCHITECTURES}"
)
set(OMP_COMPILE_OPTIONS
-fopenmp
-fvisibility=hidden
-fopenmp-cuda-mode
--offload-arch=${compile_for_architectures}
# Force LTO for the device part.
-foffload-lto
)
set_source_files_properties(${files} PROPERTIES COMPILE_OPTIONS
"${OMP_COMPILE_OPTIONS}"
)
target_link_options(${name} PUBLIC ${OMP_COMPILE_OPTIONS})
# Enable "declare target" in the source code.
set_source_files_properties(${files}
PROPERTIES COMPILE_DEFINITIONS OMP_OFFLOAD_BUILD
)
else()
message(FATAL_ERROR
"Flang-rt build with OpenMP offload is not supported for these compilers:\n"
"CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}\n"
"CMAKE_C_COMPILER_ID: ${CMAKE_C_COMPILER_ID}")
endif()
endif()
endmacro()

@ -0,0 +1,125 @@
#===-- cmake/modules/GetToolchainDirs.cmake --------------------------------===#
#
# 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
#
#===------------------------------------------------------------------------===#
# Determine the subdirectory relative to Clang's resource dir/sysroot where to
# install target-specific libraries, to be found by Clang/Flang driver. This was
# adapted from Compiler-RT's mechanism to find the path for
# libclang_rt.builtins.a.
#
# Compiler-RT has two mechanisms for the path (simplified):
#
# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=1: lib/${oslibname}/libclang_rt.builtins-${arch}.a
# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=0: lib/${triple}/libclang_rt.builtins.a
#
# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON is the newer scheme, but the old one is
# currently still used for some platforms such as Windows. Clang looks for which
# of the files exist before passing the path to the linker. Hence, the
# directories have to match what Clang is looking for, which is done in
# ToolChain::getArchSpecificLibPaths(..), ToolChain::getRuntimePath(),
# ToolChain::getCompilerRTPath(), and ToolChain::getCompilerRT(..), not entirely
# consistent between these functions, Compiler-RT's CMake code, and overrides
# in different toolchains.
#
# For Fortran, Flang always assumes the library name libflang_rt.a without
# architecture suffix. Hence, we always use the second scheme even as if
# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON, even if it actually set to OFF. It as
# added unconditionally to the library search path by
# ToolChain::getArchSpecificLibPaths(...).
function (get_toolchain_library_subdir outvar)
if (NOT APPLE)
set(outval "lib")
else ()
# Required to be "darwin" for MachO toolchain.
get_toolchain_os_dirname(os_dirname)
set(outval "lib/${os_dirname}")
endif ()
get_toolchain_arch_dirname(arch_dirname)
set(outval "lib/${arch_dirname}")
set(${outvar} "${outval}" PARENT_SCOPE)
endfunction ()
# Corresponds to Clang's ToolChain::getOSLibName(). Adapted from Compiler-RT.
function (get_toolchain_os_dirname outvar)
if (ANDROID)
# The CMAKE_SYSTEM_NAME for Android is "Android", but the OS is Linux and the
# driver will search for libraries in the "linux" directory.
set(outval "linux")
else ()
string(TOLOWER "${CMAKE_SYSTEM_NAME}" outval)
endif ()
set(${outvar} "${outval}" PARENT_SCOPE)
endfunction ()
# Corresponds to Clang's ToolChain::getRuntimePath(). Adapted from Compiler-RT.
function (get_toolchain_arch_dirname outvar)
string(REPLACE "-" ";" triple_list ${LLVM_TARGET_TRIPLE})
list(GET triple_list 0 arch)
if("${arch}" MATCHES "^i.86$")
# Android uses i686, but that's remapped at a later stage.
set(arch "i386")
endif()
string(FIND ${LLVM_TARGET_TRIPLE} "-" dash_index)
string(SUBSTRING ${LLVM_TARGET_TRIPLE} ${dash_index} -1 triple_suffix)
string(SUBSTRING ${LLVM_TARGET_TRIPLE} 0 ${dash_index} triple_cpu)
set(arch "${triple_cpu}")
if("${arch}" MATCHES "^i.86$")
# Android uses i686, but that's remapped at a later stage.
set(arch "i386")
endif()
if(ANDROID AND ${arch} STREQUAL "i386")
set(target "i686${triple_suffix}")
elseif(${arch} STREQUAL "amd64")
set(target "x86_64${triple_suffix}")
elseif(${arch} STREQUAL "sparc64")
set(target "sparcv9${triple_suffix}")
elseif("${arch}" MATCHES "mips64|mips64el")
string(REGEX REPLACE "-gnu.*" "-gnuabi64" triple_suffix_gnu "${triple_suffix}")
string(REGEX REPLACE "mipsisa32" "mipsisa64" triple_cpu_mips "${triple_cpu}")
string(REGEX REPLACE "^mips$" "mips64" triple_cpu_mips "${triple_cpu_mips}")
string(REGEX REPLACE "^mipsel$" "mips64el" triple_cpu_mips "${triple_cpu_mips}")
set(target "${triple_cpu_mips}${triple_suffix_gnu}")
elseif("${arch}" MATCHES "mips|mipsel")
string(REGEX REPLACE "-gnuabi.*" "-gnu" triple_suffix_gnu "${triple_suffix}")
string(REGEX REPLACE "mipsisa64" "mipsisa32" triple_cpu_mips "${triple_cpu}")
string(REGEX REPLACE "mips64" "mips" triple_cpu_mips "${triple_cpu_mips}")
set(target "${triple_cpu_mips}${triple_suffix_gnu}")
elseif("${arch}" MATCHES "^arm")
# FIXME: Handle arch other than arm, armhf, armv6m
if (${arch} STREQUAL "armhf")
# If we are building for hard float but our ABI is soft float.
if ("${triple_suffix}" MATCHES ".*eabi$")
# Change "eabi" -> "eabihf"
set(triple_suffix "${triple_suffix}hf")
endif()
# ABI is already set in the triple, don't repeat it in the architecture.
set(arch "arm")
else ()
# If we are building for soft float, but the triple's ABI is hard float.
if ("${triple_suffix}" MATCHES ".*eabihf$")
# Change "eabihf" -> "eabi"
string(REGEX REPLACE "hf$" "" triple_suffix "${triple_suffix}")
endif()
endif()
set(target "${arch}${triple_suffix}")
elseif("${arch}" MATCHES "^amdgcn")
set(target "amdgcn-amd-amdhsa")
elseif("${arch}" MATCHES "^nvptx")
set(target "nvptx64-nvidia-cuda")
else()
set(target "${arch}${triple_suffix}")
endif()
set(${outvar} "${target}" PARENT_SCOPE)
endfunction()

@ -0,0 +1,9 @@
#===-- examples/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
#
#===------------------------------------------------------------------------===#
add_subdirectory(ExternalHelloWorld)

@ -0,0 +1,17 @@
#===-- examples/ExternalHelloWorld/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
#
#===------------------------------------------------------------------------===#
# This test is not run by default as it requires input.
add_llvm_example(external-hello-world
external-hello.cpp
)
target_link_libraries(external-hello-world
PRIVATE
flang_rt.runtime
)

@ -0,0 +1,17 @@
#===-- lib/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
#
#===------------------------------------------------------------------------===#
add_subdirectory(quadmath)
add_subdirectory(runtime)
if (FLANG_RT_INCLUDE_CUF)
add_subdirectory(cuda)
endif()
if (FLANG_RT_INCLUDE_TESTS)
add_subdirectory(Testing)
endif ()

@ -0,0 +1,20 @@
#===-- lib/Testing/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
#
#===------------------------------------------------------------------------===#
set(public_headers "")
file(GLOB_RECURSE public_headers
"${FLANG_SOURCE_DIR}/lib/Testing/*.h"
)
add_flangrt_library(NonGTestTesting EXCLUDE_FROM_ALL LINK_TO_LLVM
${FLANG_SOURCE_DIR}/lib/Testing/testing.cpp
${FLANG_SOURCE_DIR}/lib/Testing/fp-testing.cpp
ADDITIONAL_HEADERS
${public_headers}
)

@ -0,0 +1,34 @@
#===-- lib/cuda/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
#
#===------------------------------------------------------------------------===#
add_flangrt_library(flang_rt.cuda STATIC
allocatable.cpp
allocator.cpp
descriptor.cpp
init.cpp
kernel.cpp
memmove-function.cpp
memory.cpp
registration.cpp
# libflang_rt.runtime depends on a certain version of CUDA. To be able to have
# multiple build of this library with different CUDA version, the version is
# added to the library name.
TARGET_PROPERTIES
OUTPUT_NAME "flang_rt.cuda_${CUDAToolkit_VERSION_MAJOR}"
INCLUDE_DIRECTORIES
PRIVATE ${CUDAToolkit_INCLUDE_DIRS}
)
target_link_libraries(flang_rt.cuda
PUBLIC
flang_rt.runtime
CUDA::cudart_static
)

@ -0,0 +1,136 @@
#===-- lib/quadmath/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
#
#===------------------------------------------------------------------------===#
# FortranFloat128 implements IEEE-754 128-bit float math functions.
# It is a thin wapper and it currently relies on third-party
# libraries available for the target.
# It is distributed as a static library only.
# Fortran programs/libraries that end up linking any of the provided
# will have a dependency on the third-party library that is being
# used for building this libflang_rt.quadmath library.
include(CheckLibraryExists)
include(CheckIncludeFile)
set(sources
acos.cpp
acosh.cpp
asin.cpp
asinh.cpp
atan.cpp
atan2.cpp
atanh.cpp
ceil.cpp
complex-math.c
cos.cpp
cosh.cpp
erf.cpp
erfc.cpp
exp.cpp
exponent.cpp
floor.cpp
fma.cpp
fraction.cpp
hypot.cpp
j0.cpp
j1.cpp
jn.cpp
lgamma.cpp
llround.cpp
log.cpp
log10.cpp
lround.cpp
mod-real.cpp
modulo-real.cpp
nearest.cpp
nearbyint.cpp
norm2.cpp
pow.cpp
random.cpp
remainder.cpp
round.cpp
rrspacing.cpp
scale.cpp
set-exponent.cpp
sin.cpp
sinh.cpp
spacing.cpp
sqrt.cpp
tan.cpp
tanh.cpp
tgamma.cpp
trunc.cpp
y0.cpp
y1.cpp
yn.cpp
)
include_directories(AFTER "${CMAKE_CURRENT_SOURCE_DIR}/..")
add_library(FortranFloat128MathILib INTERFACE)
target_include_directories(FortranFloat128MathILib INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
)
if (FLANG_RUNTIME_F128_MATH_LIB)
if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath")
check_include_file(quadmath.h FOUND_QUADMATH_HEADER)
if(FOUND_QUADMATH_HEADER)
add_compile_definitions(HAS_QUADMATHLIB)
else()
message(FATAL_ERROR
"FLANG_RUNTIME_F128_MATH_LIB setting requires quadmath.h "
"to be available: ${FLANG_RUNTIME_F128_MATH_LIB}"
)
endif()
else()
message(FATAL_ERROR
"Unsupported third-party library for Fortran F128 math runtime: "
"${FLANG_RUNTIME_F128_MATH_LIB}"
)
endif()
if (WIN32)
# Do not create a flang_rt.quadmath library under Windows, the Flang
# driver never links it. Instead, add the sources to flang_rt.runtime.
target_sources(FortranFloat128MathILib INTERFACE ${sources})
target_compile_definitions(FortranFloat128MathILib INTERFACE HAS_QUADMATHLIB)
else ()
add_flangrt_library(flang_rt.quadmath STATIC INSTALL_WITH_TOOLCHAIN
${sources})
target_include_directories(flang_rt.quadmath PRIVATE
"${FLANG_RT_SOURCE_DIR}/lib/flang_rt"
)
endif ()
elseif (HAVE_LDBL_MANT_DIG_113)
# We can use 'long double' versions from libc.
check_library_exists(m sinl "" FOUND_LIBM)
if (FOUND_LIBM)
target_compile_definitions(FortranFloat128MathILib INTERFACE
HAS_LIBM
)
target_include_directories(FortranFloat128MathILib INTERFACE
"${FLANG_RT_SOURCE_DIR}/lib/flang_rt"
)
target_sources(FortranFloat128MathILib INTERFACE ${sources})
else()
message(FATAL_ERROR "Flang-RT cannot build without libm")
endif()
else()
# We can use '__float128' version from libc, if it has them.
check_library_exists(m sinf128 "" FOUND_LIBMF128)
if (FOUND_LIBMF128)
target_compile_definitions(FortranFloat128MathILib INTERFACE
HAS_LIBMF128
)
target_include_directories(FortranFloat128MathILib INTERFACE
"${FLANG_RT_SOURCE_DIR}/lib/flang_rt"
)
# Enable this, when math-entries.h and complex-math.h is ready.
# target_sources(FortranFloat128MathILib INTERFACE ${sources})
endif()
endif()

@ -0,0 +1,215 @@
#===-- lib/runtime/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
#
#===------------------------------------------------------------------------===#
include(AddFlangRTOffload)
# function checks
find_package(Backtrace)
set(HAVE_BACKTRACE ${Backtrace_FOUND})
set(BACKTRACE_HEADER ${Backtrace_HEADER})
# List of files that are buildable for all devices.
set(supported_sources
${FLANG_SOURCE_DIR}/lib/Decimal/binary-to-decimal.cpp
${FLANG_SOURCE_DIR}/lib/Decimal/decimal-to-binary.cpp
ISO_Fortran_binding.cpp
allocator-registry.cpp
allocatable.cpp
array-constructor.cpp
assign.cpp
buffer.cpp
character.cpp
connection.cpp
copy.cpp
derived-api.cpp
derived.cpp
descriptor-io.cpp
descriptor.cpp
dot-product.cpp
edit-input.cpp
edit-output.cpp
environment.cpp
external-unit.cpp
extrema.cpp
file.cpp
findloc.cpp
format.cpp
inquiry.cpp
internal-unit.cpp
io-api.cpp
io-api-minimal.cpp
io-error.cpp
io-stmt.cpp
iostat.cpp
matmul-transpose.cpp
matmul.cpp
memory.cpp
misc-intrinsic.cpp
namelist.cpp
non-tbp-dio.cpp
numeric.cpp
pointer.cpp
product.cpp
pseudo-unit.cpp
ragged.cpp
stat.cpp
sum.cpp
support.cpp
terminator.cpp
tools.cpp
transformational.cpp
type-code.cpp
type-info.cpp
unit.cpp
unit-map.cpp
utf.cpp
)
# List of source not used for GPU offloading.
set(host_sources
${FLANG_SOURCE_DIR}/module/iso_fortran_env_impl.f90
command.cpp
complex-powi.cpp
complex-reduction.c
exceptions.cpp
execute.cpp
extensions.cpp
main.cpp
random.cpp
reduce.cpp
reduction.cpp
stop.cpp
temporary-stack.cpp
time-intrinsic.cpp
)
file(GLOB_RECURSE public_headers
"${FLANG_RT_SOURCE_DIR}/include/flang_rt/*.h"
"${FLANG_SOURCE_DIR}/include/flang/Common/*.h"
)
file(GLOB_RECURSE private_headers
"${FLANG_RT_SOURCE_DIR}/lib/flang_rt/*.h"
"${FLANG_SOURCE_DIR}/lib/Common/*.h"
)
# Import changes from flang_rt.quadmath
get_target_property(f128_sources
FortranFloat128MathILib INTERFACE_SOURCES
)
if (f128_sources)
# The interface may define special macros for Float128Math files,
# so we need to propagate them.
get_target_property(f128_defs
FortranFloat128MathILib INTERFACE_COMPILE_DEFINITIONS
)
set_property(SOURCE ${f128_sources}
APPEND PROPERTY COMPILE_DEFINITIONS
${f128_defs}
)
get_target_property(f128_include_dirs
FortranFloat128MathILib INTERFACE_INCLUDE_DIRECTORIES
)
set_property(SOURCE ${f128_sources}
APPEND PROPERTY INCLUDE_DIRECTORIES
${f128_include_dirs}
)
else ()
set(f128_sources "")
endif ()
set(sources ${supported_sources} ${host_sources} ${f128_sources})
if (NOT WIN32)
add_flangrt_library(flang_rt.runtime STATIC
${sources}
LINK_LIBRARIES ${Backtrace_LIBRARY}
INSTALL_WITH_TOOLCHAIN
ADDITIONAL_HEADERS ${public_headers} ${private_headers}
)
enable_cuda_compilation(flang_rt.runtime "${supported_sources}")
enable_omp_offload_compilation(flang_rt.runtime "${supported_sources}")
# For unittests that depend on flang_rt. Should link to the static version
# of the library.
add_library(flang_rt.runtime.static ALIAS flang_rt.runtime)
add_library(flang_rt.runtime.unittest ALIAS flang_rt.runtime)
else()
# Target for building all versions of the runtime
add_custom_target(flang_rt.runtime)
set_target_properties(flang_rt.runtime PROPERTIES FOLDER "Flang-RT/Meta")
function (add_win_flangrt_runtime libtype suffix msvc_lib)
set(name "flang_rt.runtime.${suffix}")
add_flangrt_library(${name} ${libtype}
${sources}
${ARGN}
LINK_LIBRARIES ${Backtrace_LIBRARY}
ADDITIONAL_HEADERS ${public_headers} ${private_headers}
)
if (msvc_lib)
set_target_properties(${name}
PROPERTIES
MSVC_RUNTIME_LIBRARY "${msvc_lib}"
)
endif ()
# Setting an unique Fortran_MODULE_DIRECTORY is required for each variant to
# write a different .mod file.
set_target_properties(${name}
PROPERTIES
Fortran_MODULE_DIRECTORY "module.${suffix}"
)
enable_cuda_compilation(${name} "${supported_sources}")
enable_omp_offload_compilation(${name} "${supported_sources}")
add_dependencies(flang_rt.runtime ${name})
endfunction ()
# Variants of the static flang_rt for different versions of the msvc runtime.
#
# The dynamic/dynamic_dbg variants are not DLLs themselves, only require
# linking to msvcrt(d).dll.
# FIXME: Generating actual runtime DLLs is currently not possible. There are
# two roadblocks:
#
# * Flang emits /DEFAULTLIB:flang_rt.dynamic.lib into
# iso_fortran_env_impl.f90.obj. Because that file is itself part of
# flang_rt.dynamic, this results in a recursive dependency when invoking
# the linker.
#
# * The externally-visible functions must either be annotated with
# __declspec(dllexport), or listed in an exports file. A possible workaround
# is CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS which would also export the internal
# C++ symbols and still requires global data symbols to be annotated
# manually.
add_win_flangrt_runtime(STATIC static MultiThreaded INSTALL_WITH_TOOLCHAIN)
add_win_flangrt_runtime(STATIC static_dbg MultiThreadedDebug INSTALL_WITH_TOOLCHAIN)
add_win_flangrt_runtime(STATIC dynamic MultiThreadedDLL INSTALL_WITH_TOOLCHAIN)
add_win_flangrt_runtime(STATIC dynamic_dbg MultiThreadedDebugDLL INSTALL_WITH_TOOLCHAIN)
# Unittests link against LLVMSupport which is using CMake's default runtime
# library selection, which is either MultiThreadedDLL or MultiThreadedDebugDLL
# depending on the configuration. They have to match or linking will fail.
if (GENERATOR_IS_MULTI_CONFIG)
# We cannot select an ALIAS library because it may be different
# per configuration. Fallback to CMake's default.
add_win_flangrt_runtime(STATIC unittest "" EXCLUDE_FROM_ALL)
else ()
string(TOLOWER ${CMAKE_BUILD_TYPE} build_type)
if (build_type STREQUAL "debug")
add_library(flang_rt.runtime.unittest ALIAS flang_rt.runtime.dynamic_dbg)
else ()
add_library(flang_rt.runtime.unittest ALIAS flang_rt.runtime.dynamic)
endif ()
endif ()
endif()

@ -0,0 +1,59 @@
#===-- test/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
#
#===------------------------------------------------------------------------===#
# Test runner infrastructure for Flang. This configures the Flang test trees
# for use by Lit, and delegates to LLVM's lit test handlers.
llvm_canonicalize_cmake_booleans(
FLANG_STANDALONE_BUILD
LLVM_BUILD_EXAMPLES
LLVM_BYE_LINK_INTO_TOOLS
LLVM_ENABLE_PLUGINS
)
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
MAIN_CONFIG
${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
)
if (TARGET FlangRTUnitTests)
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in
${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py
MAIN_CONFIG
${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py
)
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/NonGtestUnit/lit.site.cfg.py.in
${CMAKE_CURRENT_BINARY_DIR}/NonGtestUnit/lit.site.cfg.py
MAIN_CONFIG
${CMAKE_CURRENT_SOURCE_DIR}/NonGtestUnit/lit.cfg.py
)
endif ()
add_custom_target(flang-rt-test-depends)
set_target_properties(flang-rt-test-depends PROPERTIES FOLDER "Flang-RT/Meta")
add_dependencies(flang-rt-test-depends
FlangRTUnitTests
flang_rt.runtime
flang_rt.runtime.unittest
)
add_lit_testsuite(check-flang-rt "Running the Flang-RT regression tests"
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS flang-rt-test-depends
)
set_target_properties(check-flang-rt PROPERTIES FOLDER "Flang-RT/Meta")
add_lit_testsuites(flang-rt ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS flang-rt-test-depends
)

@ -1,8 +1,10 @@
! UNSUPPORTED: system-windows
! REQUIRES: flang-rt
! UNSUPPORTED: offload-cuda
! RUN: split-file %s %t
! RUN: chmod +x %t/runtest.sh
! RUN: %t/runtest.sh %t %t/ffile.f90 %t/cfile.c %flang | FileCheck %s
! RUN: %clang -I"%include/flang" -c %t/cfile.c -o %t/cfile.o
! RUN: %flang -L"%libdir" %t/ffile.f90 %t/cfile.o -o %t/ctofortran
! RUN: env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:%libdir" %t/ctofortran | FileCheck %s
!--- ffile.f90
program fmain
@ -66,24 +68,3 @@ void csub() {
foo(desc);
return;
}
!--- runtest.sh
#!/bin/bash
TMPDIR=$1
FFILE=$2
CFILE=$3
FLANG=$4
shift 4
FLAGS="$*"
BINDIR=`dirname $FLANG`
LIBDIR=$BINDIR/../lib
CCOMP=$BINDIR/clang
if [ -x $CCOMP ]
then
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIBDIR
$CCOMP $FLAGS -c $CFILE -o $TMPDIR/cfile.o
$FLANG $FLAGS $FFILE $TMPDIR/cfile.o -o $TMPDIR/ctofortran
$TMPDIR/ctofortran # should print "PASS"
else
# No clang compiler, just pass by default
echo "PASS"
fi

@ -1,10 +1,10 @@
! UNSUPPORTED: system-windows
! REQUIRES: flang-rt
! UNSUPPORTED: offload-cuda
! Verify that flang can correctly build executables.
! RUN: %flang %s -o %t
! RUN: env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:%llvmshlibdir" %t | FileCheck %s
! RUN: rm -f %t
! RUN: %flang -L"%libdir" %s -o %t
! RUN: env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:%libdir" %t | FileCheck %s
! CHECK: Hello, World!
program hello

@ -0,0 +1,22 @@
# -*- Python -*-
import os
import lit.formats
# name: The name of this test suite.
config.name = "flang-rt-OldUnit"
# suffixes: A list of file extensions to treat as test files.
# On Windows, ".exe" also matches the GTests and will execited redundantly.
config.suffixes = [".test", ".exe"]
# test_source_root: The root path where unit test binaries are located.
config.test_source_root = os.path.join(config.flangrt_binary_dir, "unittests")
# test_exec_root: The root path where tests should be run.
# lit writes a '.lit_test_times.txt' file into this directory.
config.test_exec_root = config.flang_rt_binary_test_dir
# testFormat: The test format to use to interpret tests.
config.test_format = lit.formats.ExecutableTest()

@ -0,0 +1,14 @@
@LIT_SITE_CFG_IN_HEADER@
import os
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
config.flang_rt_source_dir = "@FLANG_RT_SOURCE_DIR@"
config.flangrt_binary_dir = "@FLANG_RT_BINARY_DIR@"
config.flang_rt_binary_test_dir = os.path.dirname(__file__)
import lit.llvm
lit.llvm.initialize(lit_config, config)
# Let the main config do the real work.
lit_config.load_config(config, os.path.join(config.flang_rt_source_dir, 'test', 'NonGtestUnit', 'lit.cfg.py'))

@ -3,10 +3,11 @@ This test makes sure that flang's runtime does not depend on the C++ runtime
library. It tries to link this simple file against libflang_rt.runtime.a with
a C compiler.
REQUIRES: c-compiler, flang-rt
UNSUPPORTED: system-windows
UNSUPPORTED: offload-cuda
RUN: %if system-aix %{ export OBJECT_MODE=64 %}
RUN: %cc -std=c99 %s -I%include %libruntime -lm \
RUN: %cc -std=c99 %s -I%include -L"%libdir" -lflang_rt.runtime -lm \
RUN: %if system-aix %{-lpthread %}
RUN: rm a.out
*/

@ -0,0 +1,21 @@
# -*- Python -*-
import os
import lit.formats
# name: The name of this test suite.
config.name = "flang-rt-Unit"
# suffixes: A list of file extensions to treat as test files.
config.suffixes = []
# test_source_root: The root path where unit test binaries are located.
config.test_source_root = os.path.join(config.flangrt_binary_dir, "unittests")
# test_exec_root: The root path where tests should be run.
# lit writes a '.lit_test_times.txt' file into this directory.
config.test_exec_root = config.flang_rt_binary_test_dir
# testFormat: The test format to use to interpret tests.
config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, "Tests")

@ -0,0 +1,15 @@
@LIT_SITE_CFG_IN_HEADER@
import os
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
config.llvm_build_mode = "@LLVM_BUILD_MODE@"
config.flang_rt_source_dir = "@FLANG_RT_SOURCE_DIR@"
config.flangrt_binary_dir = "@FLANG_RT_BINARY_DIR@"
config.flang_rt_binary_test_dir = os.path.dirname(__file__)
import lit.llvm
lit.llvm.initialize(lit_config, config)
# Let the main config do the real work.
lit_config.load_config(config, os.path.join(config.flang_rt_source_dir, 'test', 'Unit', 'lit.cfg.py'))

100
flang-rt/test/lit.cfg.py Normal file

@ -0,0 +1,100 @@
# -*- Python -*-
import shlex
import lit.util
from lit.llvm import llvm_config
from lit.llvm.subst import ToolSubst, FindTool
def shjoin(args, sep=" "):
return sep.join([shlex.quote(arg) for arg in args])
# Configuration file for the 'lit' test runner.
# name: The name of this test suite.
config.name = "flang-rt"
# testFormat: The test format to use to interpret tests.
#
# For now we require '&&' between commands, until they get globally killed and
# the test runner updated.
config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
# suffixes: A list of file extensions to treat as test files.
config.suffixes = [
".c",
".cpp",
".f",
".F",
".ff",
".FOR",
".for",
".f77",
".f90",
".F90",
".ff90",
".f95",
".F95",
".ff95",
".fpp",
".FPP",
".cuf",
".CUF",
".f18",
".F18",
".f03",
".F03",
".f08",
".F08",
".ll",
".fir",
".mlir",
]
llvm_config.use_default_substitutions()
# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)
# test_exec_root: The root path where tests should be run.
# lit writes a '.lit_test_times.txt' file into this directory.
config.test_exec_root = config.flang_rt_binary_test_dir
# On MacOS, -isysroot is needed to build binaries.
isysroot_flag = []
if config.osx_sysroot:
isysroot_flag = ["-isysroot", config.osx_sysroot]
tools = [
ToolSubst(
"%flang",
command=config.flang,
extra_args=isysroot_flag,
unresolved="fatal",
),
ToolSubst(
"%clang",
command=FindTool("clang"),
extra_args=isysroot_flag,
unresolved="fatal",
),
ToolSubst("%cc", command=config.cc, extra_args=isysroot_flag, unresolved="fatal"),
]
llvm_config.add_tool_substitutions(tools)
# Let tests find LLVM's standard tools (FileCheck, split-file, not, ...)
llvm_config.with_environment("PATH", config.llvm_tools_dir, append_path=True)
# Include path for C headers that define Flang's Fortran ABI.
config.substitutions.append(
("%include", os.path.join(config.flang_source_dir, "include"))
)
# Library path of libflang_rt.runtime.a (for lib search path when using non-Flang driver for linking)
config.substitutions.append(("%libdir", config.flang_rt_output_resource_lib_dir))
# For CUDA offloading, additional steps (device linking) and libraries (cudart) are needed.
if config.flang_rt_experimental_offload_support == "CUDA":
config.available_features.add("offload-cuda")

@ -0,0 +1,19 @@
@LIT_SITE_CFG_IN_HEADER@
import sys
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
config.flang_source_dir = "@FLANG_SOURCE_DIR@"
config.flang_rt_source_dir = "@FLANG_RT_SOURCE_DIR@"
config.flang_rt_binary_test_dir = os.path.dirname(__file__)
config.flang_rt_output_resource_lib_dir = "@FLANG_RT_OUTPUT_RESOURCE_LIB_DIR@"
config.flang_rt_experimental_offload_support = "@FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT@"
config.cc = "@CMAKE_C_COMPILER@"
config.flang = "@CMAKE_Fortran_COMPILER@"
config.osx_sysroot = path(r"@CMAKE_OSX_SYSROOT@")
import lit.llvm
lit.llvm.initialize(lit_config, config)
# Let the main config do the real work.
lit_config.load_config(config, os.path.join(config.flang_rt_source_dir, 'test', 'lit.cfg.py'))

@ -0,0 +1,105 @@
#===-- unittests/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
#
#===------------------------------------------------------------------------===#
# LLVM uses a modified version of GTest that uses LLVMSupport for console
# output. Therefore it also needs to include files from LLVM. Unfortunately,
# LLVM/GTest doesn't add the include search path itself. Limiting the scope
# using target_include_directories does not work because with
# LLVM_INSTALL_GTEST=ON, as llvm_gtest is an IMPORT library.
include_directories("${LLVM_INCLUDE_DIR}" "${LLVM_MAIN_INCLUDE_DIR}")
# Add GTest if not already present.
# Using a function so LLVM_SUBPROJECT_TITLE does not propagate.
function (build_gtest)
set(LLVM_SUBPROJECT_TITLE "Third-Party/Google Test")
add_subdirectory("${LLVM_THIRD_PARTY_DIR}/unittest" "${CMAKE_CURRENT_BINARY_DIR}/third-party/unittest")
endfunction ()
if (NOT TARGET llvm_gtest)
build_gtest()
endif ()
if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
add_compile_options("-Wno-suggest-override")
endif()
# Target that depends on all unittests
add_custom_target(FlangRTUnitTests)
set_target_properties(FlangRTUnitTests PROPERTIES FOLDER "Flang-RT/Meta")
function(add_flangrt_unittest_offload_properties target)
# Set CUDA_RESOLVE_DEVICE_SYMBOLS.
if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA")
set_target_properties(${target}
PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON
)
endif()
# Enable OpenMP offload during linking. We may need to replace
# LINK_OPTIONS with COMPILE_OPTIONS when there are OpenMP offload
# unittests.
#
# FIXME: replace 'native' in --offload-arch option with the list
# of targets that Fortran Runtime was built for.
if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "OpenMP")
set_target_properties(${target}
PROPERTIES LINK_OPTIONS
"-fopenmp;--offload-arch=native"
)
endif()
endfunction()
function(add_flangrt_unittest test_dirname)
cmake_parse_arguments(ARG
""
""
"LINK_LIBS"
${ARGN})
add_unittest(FlangRTUnitTests ${test_dirname} ${ARG_UNPARSED_ARGUMENTS})
target_link_libraries(${test_dirname} PRIVATE ${ARG_LINK_LIBS})
add_flangrt_unittest_offload_properties(${test_dirname})
# Required because LLVMSupport is compiled with this option.
# FIXME: According to CMake documentation, this is the default. Why is it
# needed? LLVM's add_unittest doesn't set it either.
set_target_properties(${test_dirname}
PROPERTIES
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL"
)
endfunction()
function(add_flangrt_nongtest_unittest test_name)
cmake_parse_arguments(ARG
"SLOW_TEST"
""
"LINK_LIBS"
${ARGN})
if(ARG_SLOW_TEST)
set(suffix .slow)
else()
set(suffix .test)
endif()
add_executable(${test_name}${suffix} EXCLUDE_FROM_ALL ${ARG_UNPARSED_ARGUMENTS})
set_target_properties(${test_name}${suffix} PROPERTIES FOLDER "Flang-RT/Tests/Unit")
target_link_libraries(${test_name}${suffix} PRIVATE NonGTestTesting ${ARG_LINK_LIBS})
if(NOT ARG_SLOW_TEST)
add_dependencies(FlangRTUnitTests ${test_name}${suffix})
endif()
add_flangrt_unittest_offload_properties(${test_name}${suffix})
endfunction()
add_subdirectory(Evaluate)
add_subdirectory(Runtime)

@ -0,0 +1,21 @@
#===-- unittests/Evaluate/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
#
#===------------------------------------------------------------------------===#
add_flangrt_nongtest_unittest(reshape
reshape.cpp
LINK_LIBS
flang_rt.runtime.unittest
)
add_flangrt_nongtest_unittest(ISO-Fortran-binding
ISO-Fortran-binding.cpp
LINK_LIBS
flang_rt.runtime.unittest
)

@ -0,0 +1,48 @@
#===-- unittests/Runtime/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
#
#===------------------------------------------------------------------------===#
add_flangrt_unittest(RuntimeTests
AccessTest.cpp
Allocatable.cpp
ArrayConstructor.cpp
BufferTest.cpp
CharacterTest.cpp
CommandTest.cpp
Complex.cpp
CrashHandlerFixture.cpp
Derived.cpp
ExternalIOTest.cpp
Format.cpp
Inquiry.cpp
ListInputTest.cpp
LogicalFormatTest.cpp
Matmul.cpp
MatmulTranspose.cpp
MiscIntrinsic.cpp
Namelist.cpp
Numeric.cpp
NumericalFormatTest.cpp
Pointer.cpp
Ragged.cpp
Random.cpp
Reduction.cpp
RuntimeCrashTest.cpp
Stop.cpp
Support.cpp
Time.cpp
TemporaryStack.cpp
Transformational.cpp
LINK_LIBS
flang_rt.runtime.unittest
)
target_compile_definitions(RuntimeTests PRIVATE NOT_EXE="${LLVM_TOOLS_DIR}/not${CMAKE_EXECUTABLE_SUFFIX}")
if (FLANG_RT_INCLUDE_CUF)
add_subdirectory(CUDA)
endif ()

@ -0,0 +1,18 @@
#===-- unittests/Runtime/CUDA/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
#
#===------------------------------------------------------------------------===#
add_flangrt_unittest(FlangCufRuntimeTests
Allocatable.cpp
AllocatorCUF.cpp
Memory.cpp
)
target_link_libraries(FlangCufRuntimeTests
PRIVATE
flang_rt.cuda
)

@ -35,17 +35,6 @@ endif()
option(FLANG_ENABLE_WERROR "Fail and stop building flang if a warning is triggered." OFF)
# The out of tree builds of the compiler and the Fortran runtime
# must use the same setting of FLANG_RUNTIME_F128_MATH_LIB
# to be composable. Failure to synchronize this setting may result
# in linking errors or fatal failures in F128 runtime functions.
set(FLANG_RUNTIME_F128_MATH_LIB "" CACHE STRING
"Specifies the target library used for implementing IEEE-754 128-bit float \
math in F18 runtime, e.g. it might be libquadmath for targets where \
REAL(16) is mapped to __float128, or libm for targets where REAL(16) \
is mapped to long double, etc."
)
# Check for a standalone build and configure as appropriate from
# there.
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
@ -254,7 +243,25 @@ else()
include_directories(SYSTEM ${MLIR_TABLEGEN_OUTPUT_DIR})
endif()
option(FLANG_INCLUDE_RUNTIME "Build the runtime in-tree (deprecated; to be replaced with LLVM_ENABLE_RUNTIMES=flang-rt)" ON)
set(FLANG_INCLUDE_RUNTIME_default ON)
if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
set(FLANG_INCLUDE_RUNTIME_default OFF)
endif ()
option(FLANG_INCLUDE_RUNTIME "Build the runtime in-tree (deprecated; to be replaced with LLVM_ENABLE_RUNTIMES=flang-rt)" ${FLANG_INCLUDE_RUNTIME_default})
if (FLANG_INCLUDE_RUNTIME)
if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
message(WARNING "Building Flang-RT using LLVM_ENABLE_RUNTIMES. FLANG_INCLUDE_RUNTIME=${FLANG_INCLUDE_RUNTIME} ignored.")
set(FLANG_INCLUDE_RUNTIME OFF)
else ()
message(STATUS "Building Flang-RT in-tree")
endif ()
else ()
if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
message(STATUS "Building Flang-RT using LLVM_ENABLE_RUNTIMES")
else ()
message(STATUS "Not building Flang-RT. For a usable Fortran toolchain, either add LLVM_ENABLE_RUNTIMES=flang-rt, or compile a standalone Flang-RT.")
endif ()
endif ()
set(FLANG_TOOLS_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH
"Path for binary subdirectory (defaults to '${CMAKE_INSTALL_BINDIR}')")
@ -364,20 +371,6 @@ if (FLANG_REPOSITORY_STRING)
add_definitions(-DFLANG_REPOSITORY_STRING="${FLANG_REPOSITORY_STRING}")
endif()
if (FLANG_RUNTIME_F128_MATH_LIB)
add_compile_definitions(
FLANG_RUNTIME_F128_MATH_LIB="${FLANG_RUNTIME_F128_MATH_LIB}"
)
endif()
include(TestBigEndian)
test_big_endian(IS_BIGENDIAN)
if (IS_BIGENDIAN)
add_compile_definitions(FLANG_BIG_ENDIAN=1)
else ()
add_compile_definitions(FLANG_LITTLE_ENDIAN=1)
endif ()
# Configure Flang's Version.inc file.
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/include/flang/Version.inc.in
@ -475,6 +468,7 @@ if (APPLE)
endif()
include(AddFlang)
include(FlangCommon)
if (FLANG_INCLUDE_TESTS)
add_compile_definitions(FLANG_INCLUDE_TESTS=1)
@ -568,7 +562,13 @@ include(GetClangResourceDir)
get_clang_resource_dir(HEADER_BINARY_DIR PREFIX ${LLVM_LIBRARY_OUTPUT_INTDIR}/.. SUBDIR include)
configure_file(
${FLANG_SOURCE_DIR}/include/flang/ISO_Fortran_binding.h
${HEADER_BINARY_DIR}/ISO_Fortran_binding.h)
${HEADER_BINARY_DIR}/ISO_Fortran_binding.h COPYONLY)
# llvm-test-suite explicitly searches for this header file
# (`ISO_FORTRAN_C_HEADER`), cannot hide it in Clang's resource dir.
configure_file(
${FLANG_SOURCE_DIR}/include/flang/ISO_Fortran_binding.h
${LLVM_RUNTIME_OUTPUT_INTDIR}/../include/flang/ISO_Fortran_binding.h COPYONLY)
# And also install it into the install area
get_clang_resource_dir(HEADER_INSTALL_DIR SUBDIR include)

@ -0,0 +1,43 @@
#===-- cmake/modules/FlangCommon.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
#
#===------------------------------------------------------------------------===#
#
# CMake definitions shared between Flang and Flang-RT
#
#===------------------------------------------------------------------------===#
# The out of tree builds of the compiler and the Fortran runtime
# must use the same setting of FLANG_RUNTIME_F128_MATH_LIB
# to be composable. Failure to synchronize this setting may result
# in linking errors or fatal failures in F128 runtime functions.
set(FLANG_RUNTIME_F128_MATH_LIB "" CACHE STRING
"Specifies the target library used for implementing IEEE-754 128-bit float \
math in F18 runtime, e.g. it might be libquadmath for targets where \
REAL(16) is mapped to __float128, or libm for targets where REAL(16) \
is mapped to long double, etc."
)
if (FLANG_RUNTIME_F128_MATH_LIB)
add_compile_definitions(FLANG_RUNTIME_F128_MATH_LIB="${FLANG_RUNTIME_F128_MATH_LIB}")
endif()
# Check if 128-bit float computations can be done via long double
check_cxx_source_compiles(
"#include <cfloat>
#if LDBL_MANT_DIG != 113
#error LDBL_MANT_DIG != 113
#endif
int main() { return 0; }
"
HAVE_LDBL_MANT_DIG_113)
include(TestBigEndian)
test_big_endian(IS_BIGENDIAN)
if (IS_BIGENDIAN)
add_compile_definitions(FLANG_BIG_ENDIAN=1)
else ()
add_compile_definitions(FLANG_LITTLE_ENDIAN=1)
endif ()

@ -30,7 +30,7 @@ https://llvm.org/docs/GettingStarted.html.
All of the examples below use GCC as the C/C++ compilers and ninja as the build
tool.
### Building flang in tree
### Building flang in tree with bootstrapped Flang-RT
Building flang in tree means building flang along with all of the projects on
which it depends. These projects include mlir, clang, flang, openmp, and
compiler-rt. Note that compiler-rt is only needed to access libraries that
@ -82,7 +82,7 @@ cmake \
-DLLVM_TARGETS_TO_BUILD=host \
-DLLVM_LIT_ARGS=-v \
-DLLVM_ENABLE_PROJECTS="clang;mlir;flang;openmp" \
-DLLVM_ENABLE_RUNTIMES="compiler-rt" \
-DLLVM_ENABLE_RUNTIMES="compiler-rt;flang-rt" \
../llvm-project/llvm
ninja
@ -101,7 +101,7 @@ the cmake command above:
To run the flang tests on this build, execute the command in the "build"
directory:
```bash
ninja check-flang
ninja check-flang check-flang-rt
```
To create the installed files:
@ -111,34 +111,6 @@ ninja install
echo "latest" > $INSTALLDIR/bin/versionrc
```
To build compiler-rt:
```bash
cd $ROOTDIR
rm -rf compiler-rt
mkdir compiler-rt
cd compiler-rt
CC=$INSTALLDIR/bin/clang \
CXX=$INSTALLDIR/bin/clang++ \
cmake \
-G Ninja \
../llvm-project/compiler-rt \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=$INSTALLDIR \
-DCMAKE_CXX_STANDARD=11 \
-DCMAKE_C_CFLAGS=-mlong-double-128 \
-DCMAKE_CXX_CFLAGS=-mlong-double-128 \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCOMPILER_RT_BUILD_ORC=OFF \
-DCOMPILER_RT_BUILD_XRAY=OFF \
-DCOMPILER_RT_BUILD_MEMPROF=OFF \
-DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
-DCOMPILER_RT_BUILD_SANITIZERS=OFF \
-DLLVM_CONFIG_PATH=$INSTALLDIR/bin/llvm-config
ninja
ninja install
```
Note that these instructions specify flang as one of the projects to build in
the in tree build. This is not strictly necessary for subsequent standalone
builds, but doing so lets you run the flang tests to verify that the source
@ -192,7 +164,32 @@ directory:
ninja check-flang
```
### Building flang runtime for accelerators
To build Flang-RT (required for linking executables):
```bash
cd $ROOTDIR
rm -rf flang-rt
mkdir flang-rt
cd flang-rt
CC=$INSTALLDIR/bin/clang \
CXX=$INSTALLDIR/bin/clang++ \
cmake \
-G Ninja \
../llvm-project/runtimes \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=$INSTALLDIR \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DLLVM_ENABLE_RUNTIMES=flang-rt \
-DLLVM_BINARY_DIR=$ROOTDIR/build \
-DLLVM_Fortran_COMPILER=$INSTALLDIR/bin/flang \
-DLLVM_Fortran_COMPILER_WORKS=ON
ninja
ninja check-flang-rt
ninja install
```
### Building Flang-RT for accelerators
Flang runtime can be built for accelerators in experimental mode, i.e.
complete enabling is WIP. CUDA and OpenMP target offload builds
are currently supported.
@ -203,20 +200,21 @@ are currently supported.
Clang with NVPTX backend and NVCC compilers are supported.
```bash
cd llvm-project/flang
cd llvm-project
rm -rf build_flang_runtime
mkdir build_flang_runtime
cd build_flang_runtime
cmake \
-DFLANG_EXPERIMENTAL_CUDA_RUNTIME=ON \
-DLLVM_ENABLE_RUNTIMES=flang-rt \
-DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA \
-DCMAKE_CUDA_ARCHITECTURES=80 \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_CUDA_COMPILER=clang \
-DCMAKE_CUDA_HOST_COMPILER=clang++ \
../runtime/
make -j flang-rt
../runtimes/
make flang-rt
```
Note that the used version of `clang` must [support](https://releases.llvm.org/16.0.0/tools/clang/docs/ReleaseNotes.html#cuda-support)
@ -225,21 +223,22 @@ CUDA toolkit installations, please use `-DCUDAToolkit_ROOT=/some/path`
to specify the compatible version.
```bash
cd llvm-project/flang
cd llvm-project
rm -rf build_flang_runtime
mkdir build_flang_runtime
cd build_flang_runtime
cmake \
-DFLANG_EXPERIMENTAL_CUDA_RUNTIME=ON \
-DLLVM_ENABLE_RUNTIMES=flang-rt \
-DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA \
-DCMAKE_CUDA_ARCHITECTURES=80 \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_CUDA_COMPILER=nvcc \
-DCMAKE_CUDA_HOST_COMPILER=clang++ \
../runtime/
../runtimes/
make -j flang-rt
make flang-rt
```
Note that `nvcc` might limit support to certain
@ -251,50 +250,59 @@ code. Note that the packaging of the libraries is different
between [Clang](https://clang.llvm.org/docs/OffloadingDesign.html#linking-target-device-code) and NVCC, so the library must be linked using
compatible compiler drivers.
#### Building in-tree
#### Building in-tree (bootstrapping build)
One may build Flang runtime library along with building Flang itself
by providing these additional CMake variables on top of the Flang in-tree
build config:
For example:
```bash
-DFLANG_EXPERIMENTAL_CUDA_RUNTIME=ON \
-DLLVM_ENABLE_RUNTIMES=flang-rt \
-DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA \
-DCMAKE_CUDA_ARCHITECTURES=80 \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_CUDA_COMPILER=clang \
-DCMAKE_CUDA_HOST_COMPILER=clang++ \
../llvm
```
Or:
```bash
-DFLANG_EXPERIMENTAL_CUDA_RUNTIME=ON \
-DLLVM_ENABLE_RUNTIMES=flang-rt \
-DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA \
-DCMAKE_CUDA_ARCHITECTURES=80 \
-DCMAKE_C_COMPILER=gcc \
-DCMAKE_CXX_COMPILER=g++ \
-DCMAKE_CUDA_COMPILER=nvcc \
-DCMAKE_CUDA_HOST_COMPILER=g++ \
../llvm
```
Normal `make -j check-flang` will work with such CMake configuration.
Normal `make check-flang` will work with such CMake configuration.
Consider building in parallel using the `-j<jobs>` flag, where `<jobs>` is a
number sufficiently low for all build jobs to fit into the available RAM. Using
the number of harware threads (`nprocs`) is likely too much for most
commodity machines.
##### OpenMP target offload build
Only Clang compiler is currently supported.
```bash
cd llvm-project/flang
cd llvm-project
rm -rf build_flang_runtime
mkdir build_flang_runtime
cd build_flang_runtime
cmake \
-DFLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD="host_device" \
-DLLVM_ENABLE_RUNTIMES=flang-rt \
-DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT="OpenMP" \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DFLANG_OMP_DEVICE_ARCHITECTURES="all" \
../runtime/
-DFLANG_RT_DEVICE_ARCHITECTURES=all \
../runtimes/
make -j flang-rt
make flang-rt
```
The result of the build is a "device-only" library, i.e. the host

@ -43,6 +43,12 @@ page](https://llvm.org/releases/).
* The CufRuntime_cuda_${version} library has been renamed to
`flang_rt.cuda_${version}`.
* The Fortran Runtime library has been move to a new top-level directory
named "flang-rt". It now supports the LLVM_ENABLE_RUNTIMES mechanism to
build Flang-RT for multiple target triples. libflang_rt.runtime.{a|so} will
now be emitted into Clang's per-target resource directory
(next to libclang_rt.*.*) where it is also found by Flang's driver.
## New Issues Found

@ -166,26 +166,6 @@ else:
if config.flang_include_runtime:
config.available_features.add("flang-rt")
# Define some variables to help us test that the flang runtime doesn't depend on
# the C++ runtime libraries. For this we need a C compiler. If for some reason
# we don't have one, we can just disable the test.
if config.flang_include_runtime and config.cc:
libruntime = os.path.join(config.flang_lib_dir, "libflang_rt.runtime.a")
include = os.path.join(config.flang_src_dir, "include")
if (
os.path.isfile(libruntime)
and os.path.isdir(include)
):
config.available_features.add("c-compiler")
tools.append(
ToolSubst(
"%cc", command=config.cc, extra_args=isysroot_flag, unresolved="fatal"
)
)
tools.append(ToolSubst("%libruntime", command=libruntime, unresolved="fatal"))
tools.append(ToolSubst("%include", command=include, unresolved="fatal"))
# Add all the tools and their substitutions (if applicable). Use the search paths provided for
# finding the tools.
if config.flang_standalone_build:

@ -11,18 +11,15 @@ config.llvm_target_triple_env = "@LLVM_TARGET_TRIPLE_ENV@"
config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@"
config.flang_obj_root = "@FLANG_BINARY_DIR@"
config.flang_src_dir = "@FLANG_SOURCE_DIR@"
config.flang_tools_dir = lit_config.substitute("@FLANG_TOOLS_DIR@")
config.flang_intrinsic_modules_dir = "@FLANG_INTRINSIC_MODULES_DIR@"
config.flang_llvm_tools_dir = "@CMAKE_BINARY_DIR@/bin"
config.flang_lib_dir = "@CMAKE_BINARY_DIR@/lib"
config.flang_test_triple = "@FLANG_TEST_TARGET_TRIPLE@"
config.flang_examples = @LLVM_BUILD_EXAMPLES@
config.python_executable = "@PYTHON_EXECUTABLE@"
config.flang_standalone_build = @FLANG_STANDALONE_BUILD@
config.has_plugins = @LLVM_ENABLE_PLUGINS@
config.linked_bye_extension = @LLVM_BYE_LINK_INTO_TOOLS@
config.cc = "@CMAKE_C_COMPILER@"
config.osx_sysroot = path(r"@CMAKE_OSX_SYSROOT@")
config.targets_to_build = "@TARGETS_TO_BUILD@"
config.default_sysroot = "@DEFAULT_SYSROOT@"

@ -164,12 +164,18 @@ if ("compiler-rt" IN_LIST LLVM_ENABLE_PROJECTS)
"https://compiler-rt.llvm.org/ for building the runtimes.")
endif()
if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
if (NOT "flang" IN_LIST LLVM_ENABLE_PROJECTS)
message(FATAL_ERROR "Flang is not enabled, but is required for the Flang-RT runtime")
endif ()
endif ()
# Select the runtimes to build
#
# As we migrate runtimes to using the bootstrapping build, the set of default runtimes
# should grow as we remove those runtimes from LLVM_ENABLE_PROJECTS above.
set(LLVM_DEFAULT_RUNTIMES "libcxx;libcxxabi;libunwind")
set(LLVM_SUPPORTED_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;llvm-libgcc;offload")
set(LLVM_SUPPORTED_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;llvm-libgcc;offload;flang-rt")
set(LLVM_ENABLE_RUNTIMES "" CACHE STRING
"Semicolon-separated list of runtimes to build, or \"all\" (${LLVM_DEFAULT_RUNTIMES}). Supported runtimes are ${LLVM_SUPPORTED_RUNTIMES}.")
if(LLVM_ENABLE_RUNTIMES STREQUAL "all")

@ -38,6 +38,8 @@ endfunction()
# llvm_ExternalProject_Add(name source_dir ...
# ENABLE_FORTRAN
# External project requires the Flang compiler
# USE_TOOLCHAIN
# Use just-built tools (see TOOLCHAIN_TOOLS)
# EXCLUDE_FROM_ALL
@ -65,7 +67,7 @@ endfunction()
# )
function(llvm_ExternalProject_Add name source_dir)
cmake_parse_arguments(ARG
"USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL;ALWAYS_CLEAN"
"ENABLE_FORTRAN;USE_TOOLCHAIN;EXCLUDE_FROM_ALL;NO_INSTALL;ALWAYS_CLEAN"
"SOURCE_DIR;FOLDER"
"CMAKE_ARGS;TOOLCHAIN_TOOLS;RUNTIME_LIBRARIES;DEPENDS;EXTRA_TARGETS;PASSTHROUGH_PREFIXES;STRIP_TOOL;TARGET_TRIPLE"
${ARGN})
@ -93,6 +95,9 @@ function(llvm_ExternalProject_Add name source_dir)
if(NOT ARG_TOOLCHAIN_TOOLS)
set(ARG_TOOLCHAIN_TOOLS clang)
if (ARG_ENABLE_FORTRAN)
list(APPEND ARG_TOOLCHAIN_TOOLS flang)
endif ()
# AIX 64-bit XCOFF and big AR format is not yet supported in some of these tools.
if(NOT _cmake_system_name STREQUAL AIX)
list(APPEND ARG_TOOLCHAIN_TOOLS lld llvm-ar llvm-ranlib llvm-nm llvm-objdump)
@ -143,6 +148,10 @@ function(llvm_ExternalProject_Add name source_dir)
set(CLANG_IN_TOOLCHAIN On)
endif()
if(flang IN_LIST TOOLCHAIN_TOOLS)
set(FLANG_IN_TOOLCHAIN On)
endif()
if(RUNTIME_LIBRARIES AND CLANG_IN_TOOLCHAIN)
list(APPEND TOOLCHAIN_BINS ${RUNTIME_LIBRARIES})
endif()
@ -225,6 +234,9 @@ function(llvm_ExternalProject_Add name source_dir)
-DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX})
endif()
endif()
if(FLANG_IN_TOOLCHAIN)
list(APPEND compiler_args -DCMAKE_Fortran_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/flang${CMAKE_EXECUTABLE_SUFFIX})
endif()
if(lld IN_LIST TOOLCHAIN_TOOLS)
if(is_msvc_target)
list(APPEND compiler_args -DCMAKE_LINKER=${LLVM_RUNTIME_OUTPUT_INTDIR}/lld-link${CMAKE_EXECUTABLE_SUFFIX})
@ -308,6 +320,7 @@ function(llvm_ExternalProject_Add name source_dir)
set(compiler_args -DCMAKE_ASM_COMPILER=${CMAKE_ASM_COMPILER}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER}
-DCMAKE_LINKER=${CMAKE_LINKER}
-DCMAKE_AR=${CMAKE_AR}
-DCMAKE_RANLIB=${CMAKE_RANLIB}
@ -357,6 +370,7 @@ function(llvm_ExternalProject_Add name source_dir)
if(ARG_TARGET_TRIPLE)
list(APPEND compiler_args -DCMAKE_C_COMPILER_TARGET=${ARG_TARGET_TRIPLE})
list(APPEND compiler_args -DCMAKE_CXX_COMPILER_TARGET=${ARG_TARGET_TRIPLE})
list(APPEND compiler_args -DCMAKE_Fortran_COMPILER_TARGET=${ARG_TARGET_TRIPLE})
list(APPEND compiler_args -DCMAKE_ASM_COMPILER_TARGET=${ARG_TARGET_TRIPLE})
endif()

@ -11,7 +11,8 @@ foreach(entry ${entries})
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/libunwind) AND
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/test-suite) AND
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/openmp) AND
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/cross-project-tests))
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/cross-project-tests) AND
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/flang-rt))
get_filename_component(entry_name "${entry}" NAME)
add_llvm_external_project(${entry_name})
endif()
@ -37,6 +38,7 @@ if(${LLVM_BUILD_RUNTIME})
if(NOT LLVM_BUILD_EXTERNAL_COMPILER_RT)
add_llvm_external_project(compiler-rt)
endif()
add_llvm_external_project(flang-rt)
endif()
add_llvm_external_project(dragonegg)

@ -230,7 +230,7 @@ foreach(entry ${runtimes})
endforeach()
function(runtime_default_target)
cmake_parse_arguments(ARG "" "" "DEPENDS;CMAKE_ARGS;PREFIXES" ${ARGN})
cmake_parse_arguments(ARG "" "" "DEPENDS;CMAKE_ARGS;PREFIXES;EXTRA_ARGS" ${ARGN})
include(${LLVM_BINARY_DIR}/runtimes/Components.cmake OPTIONAL)
set(SUB_CHECK_TARGETS ${SUB_CHECK_TARGETS} PARENT_SCOPE)
@ -270,14 +270,16 @@ function(runtime_default_target)
-DLLVM_BUILD_TOOLS=${LLVM_BUILD_TOOLS}
-DCMAKE_C_COMPILER_WORKS=ON
-DCMAKE_CXX_COMPILER_WORKS=ON
-DCMAKE_Fortran_COMPILER_WORKS=ON
-DCMAKE_ASM_COMPILER_WORKS=ON
${COMMON_CMAKE_ARGS}
${RUNTIMES_CMAKE_ARGS}
${ARG_CMAKE_ARGS}
PASSTHROUGH_PREFIXES LLVM_ENABLE_RUNTIMES
LLVM_USE_LINKER
CUDA # For runtimes that may look for the CUDA SDK (libc, offload)
CUDA CMAKE_CUDA # For runtimes that may look for the CUDA compiler and/or SDK (libc, offload, flang-rt)
FFI # offload uses libffi
FLANG_RUNTIME # Shared between Flang and Flang-RT
${ARG_PREFIXES}
EXTRA_TARGETS ${extra_targets}
${test_targets}
@ -287,7 +289,7 @@ function(runtime_default_target)
USE_TOOLCHAIN
TARGET_TRIPLE ${LLVM_TARGET_TRIPLE}
FOLDER "Runtimes"
${EXTRA_ARGS})
${EXTRA_ARGS} ${ARG_EXTRA_ARGS})
endfunction()
# runtime_register_target(name)
@ -404,6 +406,7 @@ function(runtime_register_target name)
-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=${LLVM_ENABLE_PER_TARGET_RUNTIME_DIR}
-DCMAKE_C_COMPILER_WORKS=ON
-DCMAKE_CXX_COMPILER_WORKS=ON
-DCMAKE_Fortran_COMPILER_WORKS=ON
-DCMAKE_ASM_COMPILER_WORKS=ON
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON
-DLLVM_RUNTIMES_TARGET=${name}
@ -463,10 +466,13 @@ if(build_runtimes)
# together in a single CMake invocation.
set(extra_deps "")
set(extra_cmake_args "")
set(extra_args "")
if(LLVM_INCLUDE_TESTS)
foreach(dep FileCheck
clang
clang-offload-packager
flang
count
lld
lli
@ -549,19 +555,24 @@ if(build_runtimes)
if(LLVM_LIBC_FULL_BUILD)
list(APPEND extra_cmake_args "-DLLVM_LIBC_FULL_BUILD=ON")
endif()
if("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
list(APPEND extra_args ENABLE_FORTRAN)
endif ()
if(NOT LLVM_RUNTIME_TARGETS)
runtime_default_target(
DEPENDS ${builtins_dep} ${extra_deps}
CMAKE_ARGS ${extra_cmake_args}
PREFIXES ${prefixes})
PREFIXES ${prefixes}
EXTRA_ARGS ${extra_args})
set(test_targets check-runtimes)
else()
if("default" IN_LIST LLVM_RUNTIME_TARGETS)
runtime_default_target(
DEPENDS ${builtins_dep} ${extra_deps}
CMAKE_ARGS ${extra_cmake_args}
PREFIXES ${prefixes})
PREFIXES ${prefixes}
EXTRA_ARGS ${extra_args})
list(REMOVE_ITEM LLVM_RUNTIME_TARGETS "default")
else()
add_custom_target(runtimes)
@ -608,7 +619,7 @@ if(build_runtimes)
runtime_register_target(${name}
DEPENDS ${builtins_dep_name} ${extra_deps}
CMAKE_ARGS -DLLVM_DEFAULT_TARGET_TRIPLE=${name} ${extra_cmake_args}
EXTRA_ARGS TARGET_TRIPLE ${name})
EXTRA_ARGS TARGET_TRIPLE ${name} ${extra_args})
endforeach()
foreach(multilib ${LLVM_RUNTIME_MULTILIBS})
@ -620,7 +631,7 @@ if(build_runtimes)
-DLLVM_RUNTIMES_LIBDIR_SUBDIR=${multilib}
${extra_cmake_args}
BASE_NAME ${name}
EXTRA_ARGS TARGET_TRIPLE ${name})
EXTRA_ARGS TARGET_TRIPLE ${name} ${extra_args})
endforeach()
endforeach()
endif()

@ -36,7 +36,7 @@ list(INSERT CMAKE_MODULE_PATH 0
# We order libraries to mirror roughly how they are layered, except that compiler-rt can depend
# on libc++, so we put it after.
set(LLVM_DEFAULT_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;offload")
set(LLVM_SUPPORTED_RUNTIMES "${LLVM_DEFAULT_RUNTIMES};llvm-libgcc")
set(LLVM_SUPPORTED_RUNTIMES "${LLVM_DEFAULT_RUNTIMES};llvm-libgcc;flang-rt")
set(LLVM_ENABLE_RUNTIMES "" CACHE STRING
"Semicolon-separated list of runtimes to build, or \"all\" (${LLVM_DEFAULT_RUNTIMES}). Supported runtimes are ${LLVM_SUPPORTED_RUNTIMES}.")
if(LLVM_ENABLE_RUNTIMES STREQUAL "all" )