forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Flang] [FlangRT] Introduce FlangRT project as solution to Flang's ru…
…ntime LLVM integration See discourse thread https://discourse.llvm.org/t/rfc-support-cmake-option-to-control-link-type-built-for-flang-runtime-libraries/71602/18 for full details. Flang-rt is the new library target for the flang runtime libraries. It builds the Flang-rt library (which contains the sources of FortranRuntime and FortranDecimal) and the Fortran_main library. See documentation in this patch for detailed description (flang-rt/docs/GettingStarted.md). This patch aims to: - integrate Flang's runtime into existing llvm infrasturcture so that Flang's runtime can be built similarly to other runtimes via the runtimes target or via the llvm target as an enabled runtime - decouple the FortranDecimal library sources that were used by both compiler and runtime so that different build configurations can be applied for compiler vs runtime - add support for running flang-rt testsuites, which were created by migrating relevant tests from `flang/test` and `flang/unittest` to `flang-rt/test` and `flang-rt/unittest`, using a new `check-flang-rt` target. - provide documentation on how to build and use the new FlangRT runtime Reviewed By: DanielCChen Differential Revision: https://reviews.llvm.org/D154869
- Loading branch information
Showing
66 changed files
with
1,294 additions
and
245 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
# CMake build for the Flang runtime libraries | ||
# The source for the flang runtime libraries (FortranDecimalRT, FortranRuntime) | ||
# exist in the flang top-level directory. | ||
# Flang-rt is only scaffolding and does not provide any additional source files. | ||
|
||
cmake_minimum_required(VERSION 3.20.0) | ||
|
||
#=============================================================================== | ||
# Configure CMake | ||
#=============================================================================== | ||
set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") | ||
include(${LLVM_COMMON_CMAKE_UTILS}/Modules/CMakePolicy.cmake | ||
NO_POLICY_SCOPE) | ||
|
||
set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON) | ||
set(CMAKE_INCLUDE_CURRENT_DIR ON) | ||
|
||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/flang-rt/bin) | ||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY | ||
${CMAKE_BINARY_DIR}/flang-rt/lib) | ||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY | ||
${CMAKE_BINARY_DIR}/flang-rt/lib) | ||
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_BINARY_DIR}/flang-rt) | ||
|
||
set(FLANG_RT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") | ||
set(FLANG_RT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") | ||
|
||
#=============================================================================== | ||
# Setup Options and Defaults | ||
#=============================================================================== | ||
option(FLANG_RT_ENABLE_SHARED "Build flang-rt as a shared library." OFF) | ||
option(FLANG_RT_ENABLE_STATIC "Build flang-rt as a static library." OFF) | ||
|
||
option(FLANG_RT_INCLUDE_TESTS | ||
"Generate build targets for the Flang-rt unit tests." ${LLVM_INCLUDE_TESTS}) | ||
|
||
# MLIR_DIR must be passed on invocation of flang-rt because it is needed for the Flang package. | ||
if(NOT DEFINED MLIR_DIR OR MLIR_DIR STREQUAL "") | ||
message(FATAL_ERROR "MLIR_DIR must be set to the directory of the MLIRConfig cmake file in order to find the MLIR package.") | ||
endif() | ||
# Flang-rt requires a pre-built/installed version of flang that requires MLIR. | ||
find_package(MLIR REQUIRED HINTS "${MLIR_DIR}") | ||
|
||
# FLANG_DIR must be passed on invocation of flang-rt. | ||
if(NOT DEFINED FLANG_DIR OR FLANG_DIR STREQUAL "") | ||
message(FATAL_ERROR "FLANG_DIR must be set to the directory of the FlangConfig cmake file in order to find the Flang package.") | ||
endif() | ||
# Flang-rt requires a pre-built/installed version of flang. | ||
# Flang-rt uses flang/Common headers. | ||
# Finding this package exposes FLANG_SOURCE_DIR, FLANG_BINARY_DIR, and FLANG_INCLUDE_DIRS to Flang-rt | ||
find_package(Flang REQUIRED HINTS "${FLANG_DIR}") | ||
# If the user specifies a relative path to LLVM_DIR, the calls to include | ||
# LLVM modules fail. Append the absolute path to LLVM_DIR instead. | ||
get_filename_component(FLANG_DIR_ABSOLUTE ${FLANG_DIR} REALPATH) | ||
list(APPEND CMAKE_MODULE_PATH ${FLANG_DIR_ABSOLUTE}) | ||
|
||
set(LLVM_COMMON_CMAKE_UTILS "${FLANG_RT_SOURCE_DIR}/../cmake") | ||
set(LLVM_CMAKE_UTILS "${LLVM_BUILD_MAIN_SOURCE_DIR}/cmake") | ||
set(CLANG_CMAKE_UTILS "${FLANG_RT_SOURCE_DIR}/../clang/cmake") | ||
|
||
if (FLANG_RT_INCLUDE_TESTS) | ||
# LLVM_DIR must be passed on invocation of flang-rt when tests are enabled. | ||
if(NOT DEFINED LLVM_DIR OR LLVM_DIR STREQUAL "") | ||
message(FATAL_ERROR "LLVM_DIR must be set to the directory of the LLVMConfig cmake file in order to find the LLVM package.") | ||
endif() | ||
# We need a pre-built/installed version of LLVM for gtest. | ||
find_package(LLVM REQUIRED HINTS "${LLVM_DIR}") | ||
# If the user specifies a relative path to LLVM_DIR, the calls to include | ||
# LLVM modules fail. Append the absolute path to LLVM_DIR instead. | ||
get_filename_component(LLVM_DIR_ABSOLUTE ${LLVM_DIR} REALPATH) | ||
list(APPEND CMAKE_MODULE_PATH ${LLVM_DIR_ABSOLUTE}) | ||
|
||
add_compile_definitions(FLANG_RT_INCLUDE_TESTS=1) | ||
|
||
if (DEFINED FLANG_BINARY_DIR) | ||
set(FLANG_BINARY_DIR ${FLANG_BINARY_DIR} CACHE PATH "Path to the Flang build directory" FORCE) | ||
else() | ||
message(FATAL_ERROR "FLANG_BINARY_DIR must be defined or passed by the user when building tests.") | ||
endif() | ||
set(FLANG_RT_TEST_COMPILER ${FLANG_BINARY_DIR}/bin/flang-new | ||
CACHE PATH "Compiler to use for testing") | ||
set(FLANG_RT_GTEST_AVAIL 1) | ||
endif() | ||
|
||
# Add path for custom modules | ||
list(INSERT CMAKE_MODULE_PATH 0 | ||
"${FLANG_SOURCE_DIR}/cmake" | ||
"${FLANG_SOURCE_DIR}/cmake/modules" | ||
"${CLANG_CMAKE_UTILS}/modules" | ||
"${LLVM_CMAKE_UTILS}/modules" | ||
) | ||
|
||
include(AddClang) | ||
include(AddFlang) | ||
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 () | ||
|
||
# Flang's include directories are needed for flang/Common. | ||
include_directories(SYSTEM ${FLANG_INCLUDE_DIRS}) | ||
|
||
# LLVM's include directories are needed for gtest. | ||
include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}) | ||
|
||
#=============================================================================== | ||
# Add Subdirectories | ||
#=============================================================================== | ||
set(FORTRAN_DECIMAL_SRC "${FLANG_SOURCE_DIR}/lib/Decimal") | ||
set(FORTRAN_RUNTIME_SRC "${FLANG_SOURCE_DIR}/runtime") | ||
set(FORTRAN_MAIN_SRC "${FLANG_SOURCE_DIR}/runtime/FortranMain") | ||
|
||
add_subdirectory(${FORTRAN_DECIMAL_SRC} FortranDecimalRT) | ||
add_subdirectory(${FORTRAN_RUNTIME_SRC} FortranRuntime) | ||
add_subdirectory(${FORTRAN_MAIN_SRC} FortranMain) | ||
|
||
if (FLANG_RT_INCLUDE_TESTS) | ||
add_subdirectory(test) | ||
if (FLANG_RT_GTEST_AVAIL) | ||
add_subdirectory(unittests) | ||
endif() | ||
endif() | ||
|
||
#=============================================================================== | ||
# Create Flang-rt wrapper library | ||
#=============================================================================== | ||
# Build as shared by default if no linkage type option set. | ||
if (NOT FLANG_RT_ENABLE_SHARED AND NOT FLANG_RT_ENABLE_STATIC) | ||
add_library(flang-rt SHARED $<TARGET_OBJECTS:obj.FortranDecimalRT> | ||
$<TARGET_OBJECTS:obj.FortranRuntime>) | ||
endif() | ||
if (FLANG_RT_ENABLE_SHARED) | ||
add_library(flang-rt SHARED $<TARGET_OBJECTS:obj.FortranDecimalRT> | ||
$<TARGET_OBJECTS:obj.FortranRuntime>) | ||
endif() | ||
if (FLANG_RT_ENABLE_STATIC AND NOT FLANG_RT_ENABLE_SHARED) | ||
add_library(flang-rt STATIC $<TARGET_OBJECTS:obj.FortranDecimalRT> | ||
$<TARGET_OBJECTS:obj.FortranRuntime>) | ||
endif() | ||
# When building both static and shared, we need to append _static to the name | ||
# to avoid naming conflicts. | ||
if (FLANG_RT_ENABLE_STATIC AND FLANG_RT_ENABLE_SHARED) | ||
add_library(flang-rt_static STATIC $<TARGET_OBJECTS:obj.FortranDecimalRT> | ||
$<TARGET_OBJECTS:obj.FortranRuntime>) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
<!--===- docs/GettingStarted.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 | ||
--> | ||
|
||
# Flang-rt Runtime Library | ||
|
||
```eval_rst | ||
.. contents:: | ||
:local: | ||
``` | ||
## What is Flang-rt | ||
Flang-rt is the runtime library project for Flang. The Flang driver requires | ||
the Fortran_main and Flang-rt libraries at runtime in order to generate | ||
user executables. Building this Flang-rt project will build both Fortran_main | ||
and the Flang-rt library, which is comprised of the FortranRuntime and | ||
FortranDecimalRT libraries. | ||
|
||
### Fortran_main | ||
Fortran_main is left out of the Flang-rt library because it is required to | ||
always be static unlike the link type of the Flang-rt library which can be | ||
configured. Fortran_main implements the main entry point into Fortran's | ||
`PROGRAM` in Flang by being the bridge between object files generated by Flang | ||
and the C runtime that takes care of program set-up at system-level. For | ||
every Fortran `PROGRAM`, Flang generates the `_QQmain` function. | ||
Fortran_main implements the C `main` function that simply calls | ||
`_QQmain`. | ||
|
||
### FortranDecimalRT | ||
In order to decouple the common dependency between compiler and runtime, | ||
[FortranDecimal's sources](../../flang/lib/Decimal/CMakeLists.txt) are built | ||
separately for the compiler and the runtime. When the library is built for | ||
Flang-rt, the name FortranDecimalRT is used to avoid naming conflicts and | ||
confusion. | ||
|
||
### FortranRuntime | ||
This is the core runtime library in Flang-rt. The sources for this library | ||
currently still exist in the | ||
[Flang source directory](../../flang/runtime/CMakeLists.txt). We hope to | ||
migrate the sources to the Flang-rt directory in the future in order to further | ||
decouple the runtime from the Flang compiler. | ||
|
||
## Building Flang-rt | ||
Like other LLVM runtimes, Flang-rt can be built by targetting the | ||
[runtimes LLVM target](../../runtimes/CMakelists.txt). It can also be built | ||
when targetting the [llvm target](../../llvm/CMakeLists.txt) as an enabled | ||
runtime. Flang-rt will implicitly be added as an enabled runtime when Flang | ||
is an enabled project built by llvm. Flang-rt does not support standalone | ||
builds. | ||
|
||
In the future, we may be interested in supporting in optionally building | ||
Flang-rt when doing a Flang standalone build. | ||
|
||
### Building with the llvm target | ||
Assuming you are building Flang-rt to use with Flang, see | ||
[Flang's Getting Started guide](../../flang/docs/GettingStarted.md) for more | ||
information. To build Flang-rt when building the Flang compiler, once you have | ||
the llvm-project source ready, make a clean build directory. Let root be the | ||
root directory that you cloned llvm-project into. | ||
```bash | ||
cd root | ||
rm -rf build | ||
mkdir build | ||
cd build | ||
``` | ||
Now invoke the cmake configuration command for llvm that would build Flang with | ||
Flang-rt. | ||
```bash | ||
cmake \ | ||
-G Ninja \ | ||
-DLLVM_ENABLE_RUNTIMES="compiler-rt;flang-rt" \ | ||
-DCMAKE_CXX_STANDARD=17 \ | ||
-DLLVM_INSTALL_UTILS=On \ | ||
# New Flang-rt flags for enabled link types | ||
-DFLANG_RT_ENABLE_STATIC=On \ | ||
-DFLANG_RT_ENABLE_SHARED=On \ | ||
# We need to enable GTest if we want to run Flang-rt's testsuites | ||
-DLLVM_INSTALL_GTEST=On \ | ||
-DFLANG_ENABLE_WERROR=On \ | ||
-DLLVM_LIT_ARGS=-v \ | ||
-DCMAKE_BUILD_TYPE=Release \ | ||
-DLLVM_ENABLE_PROJECTS="clang;flang;lld;mlir;openmp" \ | ||
../llvm-project/llvm | ||
``` | ||
Flang requires other llvm projects (see LLVM_ENABLE_PROJECTS and the [Flang | ||
Getting Started Guide](../../flang/docs/GettingStarted.md) for more specifics | ||
on building Flang. | ||
|
||
By targetting the LLVM project, we are letting LLVM infrastructure handle | ||
invoking the runtimes target that will build Flang-rt. This includes finding | ||
the cmake packages for Clang, LLVM, Flang and MLIR that Flang-rt depends on. | ||
|
||
### Building with the runtimes target | ||
If you already have a pre-built/installed version of LLVM, Flang, Clang and | ||
MLIR, and would like to build Flang-rt without rebuilding the sources for these | ||
other projects. You can simply target the runtimes project directly and passing | ||
the paths to the directories of these files. If you built LLVM as we did above | ||
with default build directories, your runtimes invocation should look something | ||
like: | ||
```bash | ||
cd build | ||
BUILDDIR=`pwd` | ||
|
||
cmake \ | ||
-G Ninja \ | ||
-DCMAKE_CXX_STANDARD=17 \ | ||
# New Flang-rt flags for enabled link types | ||
-DFLANG_RT_ENABLE_SHARED=On \ | ||
-DFLANG_RT_ENABLE_STATIC=On \ | ||
-DLLVM_LIT_ARGS=-v \ | ||
-DCMAKE_BUILD_TYPE=Release \ | ||
-DCMAKE_CXX_LINK_FLAGS="-Wl,-rpath,$LD_LIBRARY_PATH" \ | ||
-DLLVM_TARGETS_TO_BUILD=host \ | ||
-DLLVM_EXTERNAL_LIT=$BUILD_DIR/bin/llvm-lit \ | ||
# We need to specify the paths to the cmake packages of the dependencies | ||
-DLLVM_DIR=$BUILD_DIR/lib/cmake/llvm \ | ||
-DMLIR_DIR=$BUILD_DIR/lib/cmake/mlir \ | ||
-DFLANG_DIR=$BUILD_DIR/lib/cmake/flang \ | ||
-DLLVM_ENABLE_RUNTIMES="flang-rt" \ | ||
../llvm-project/runtimes/ | ||
``` | ||
|
||
## Library locations | ||
When building the llvm target with flang as an enabled project, the Flang-rt | ||
library will be built to `$BUILDDIR/runtimes/runtimes-bins/flang-rt/lib`. When | ||
building the runtimes target with flang-rt as an enabled runtime, the libraries | ||
will be built to `$BUILDDIR/flang-rt/lib` by default. In either configuration, | ||
the Fortran_main library will be built to `$BUILDDIR/lib` by default. | ||
|
||
## Using Flang-rt | ||
The two build paths mentioned above get implicitly added as library paths at the | ||
invocation of the driver. If Flang-rt is a shared library, you must make the | ||
dynamic linker aware of where to look. One method to do so is to set the | ||
environment variable `LD_LIBRARY_PATH` include the path to Flang-rt's directory. | ||
|
||
## Options | ||
Flang-rt introduces 2 CMake options used to configure the library's link type: | ||
``` | ||
option(FLANG_RT_ENABLE_SHARED "Build flang-rt as a shared library." OFF) | ||
option(FLANG_RT_ENABLE_STATIC "Build flang-rt as a static library." OFF) | ||
``` | ||
Both can be specified if you want to build both shared and static versions of | ||
the Flang-rt runtime. If both are specified, the static library will be named | ||
Flang-rt_static.a to avoid naming conflicts, as per the LLVM standard. | ||
|
||
## Usage Examples | ||
```bash | ||
# Example of using Flang with the shared Flang-rt runtime | ||
# First we need to explicitly tell the dynamic linker where to find Flang-rt | ||
# since it was built as shared. | ||
$ $ export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$BUILDDIR/runtimes/runtimes-bins/flang-rt/lib" | ||
$ flang-new -ffree-form hello.f95 -o hello | ||
``` |
Oops, something went wrong.