Revert "[Flang] [FlangRT] Introduce FlangRT project as solution to Flang's runtime LLVM integration"

This reverts commit 6403287eff71a3d6f6c862346d6ed3f0f000eb70.

This is failing on all but 1 of Linaro's flang builders.
CMake Error at /home/tcwg-buildbot/worker/clang-aarch64-full-2stage/llvm/flang-rt/unittests/CMakeLists.txt:37 (message):
  Target llvm_gtest not found.
This commit is contained in:
David Spickett 2023-10-02 09:01:11 +00:00
parent 43198b0aa2
commit ffc67bb360
66 changed files with 245 additions and 1294 deletions

View File

@ -969,41 +969,29 @@ void tools::addFortranRuntimeLibs(const ToolChain &TC,
llvm::opt::ArgStringList &CmdArgs) {
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
CmdArgs.push_back("Fortran_main.lib");
CmdArgs.push_back("flang-rt.lib");
CmdArgs.push_back("FortranRuntime.lib");
CmdArgs.push_back("FortranDecimal.lib");
} else {
CmdArgs.push_back("-lFortran_main");
CmdArgs.push_back("-lflang-rt");
CmdArgs.push_back("-lFortranRuntime");
CmdArgs.push_back("-lFortranDecimal");
}
}
void tools::addFortranRuntimeLibraryPath(const ToolChain &TC,
const llvm::opt::ArgList &Args,
ArgStringList &CmdArgs) {
// Default to the <driver-path>/../lib, <driver-path>/../flang-rt/lib, and
// <driver-path>/../runtimes/runtimes-bins/flang-rt/lib directories. This
// works fine on the platforms that we have tested so far. We will probably
// have to re-fine this in the future. In particular, on some platforms, we
// may need to use lib64 instead of lib.
SmallString<256> BuildLibPath =
// Default to the <driver-path>/../lib directory. This works fine on the
// platforms that we have tested so far. We will probably have to re-fine
// this in the future. In particular, on some platforms, we may need to use
// lib64 instead of lib.
SmallString<256> DefaultLibPath =
llvm::sys::path::parent_path(TC.getDriver().Dir);
SmallString<256> FlangRTLibPath =
llvm::sys::path::parent_path(TC.getDriver().Dir);
SmallString<256> RuntimesLibPath =
llvm::sys::path::parent_path(TC.getDriver().Dir);
// Search path for Fortran_main and Flang-rt libraries.
llvm::sys::path::append(BuildLibPath, "lib");
llvm::sys::path::append(FlangRTLibPath, "flang-rt/lib");
llvm::sys::path::append(RuntimesLibPath,
"runtimes/runtimes-bins/flang-rt/lib");
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
CmdArgs.push_back(Args.MakeArgString("-libpath:" + BuildLibPath));
CmdArgs.push_back(Args.MakeArgString("-libpath:" + FlangRTLibPath));
CmdArgs.push_back(Args.MakeArgString("-libpath:" + RuntimesLibPath));
} else {
CmdArgs.push_back(Args.MakeArgString("-L" + BuildLibPath));
CmdArgs.push_back(Args.MakeArgString("-L" + FlangRTLibPath));
CmdArgs.push_back(Args.MakeArgString("-L" + RuntimesLibPath));
}
llvm::sys::path::append(DefaultLibPath, "lib");
if (TC.getTriple().isKnownWindowsMSVCEnvironment())
CmdArgs.push_back(Args.MakeArgString("-libpath:" + DefaultLibPath));
else
CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath));
}
static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,

View File

@ -1,148 +0,0 @@
# 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()

View File

@ -1,156 +0,0 @@
<!--===- 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
```

View File

@ -1,73 +0,0 @@
# Test runner infrastructure for Flang-rt. This configures the Flang-rt 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
)
set(FLANG_TOOLS_DIR ${FLANG_BINARY_DIR}/bin)
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
PATHS
${PATHS_FOR_PLUGINS}
)
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
)
set(FLANG_RT_TEST_PARAMS
flang_rt_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py)
set(FLANG_RT_TEST_DEPENDS
LLVMSupport
flang-rt
Fortran_main
)
if (LLVM_ENABLE_PLUGINS AND NOT WIN32)
list(APPEND FLANG_RT_TEST_DEPENDS Bye)
endif()
if (FLANG_RT_INCLUDE_TESTS)
if (FLANG_RT_GTEST_AVAIL)
list(APPEND FLANG_RT_TEST_DEPENDS FlangRTUnitTests)
endif()
endif()
add_custom_target(flang-rt-test-depends DEPENDS ${FLANG_RT_TEST_DEPENDS})
add_lit_testsuite(check-flang-rt "Running the Flang-rt regression tests"
${CMAKE_CURRENT_BINARY_DIR}
PARAMS ${FLANG_RT_TEST_PARAMS}
DEPENDS ${FLANG_RT_TEST_DEPENDS}
)
set_target_properties(check-flang-rt PROPERTIES FOLDER "Tests")
add_lit_testsuites(FLANG_RT ${CMAKE_CURRENT_SOURCE_DIR}
PARAMS ${FLANG_RT_TEST_PARAMS}
DEPENDS ${FLANG_RT_TEST_DEPENDS})
# To modify the default target triple for flang-rt tests.
if (DEFINED FLANG_RT_TEST_TARGET_TRIPLE)
if (NOT DEFINED LLVM_TARGET_TRIPLE_ENV OR LLVM_TARGET_TRIPLE_ENV STREQUAL "")
message(FATAL_ERROR "LLVM_TARGET_TRIPLE_ENV must also be defined in order "
"to use FLANG_RT_TEST_TARGET_TRIPLE.")
endif()
endif()

View File

@ -1,38 +0,0 @@
/*
This test makes sure that flang's runtime does not depend on the C++ runtime
library. It tries to link this simple file against libFortranRuntime.a with
a C compiler.
REQUIRES: c-compiler
RUN: %cc -std=c99 %s -I%include %libruntime -lm -o /dev/null
*/
#include "flang/Runtime/entry-names.h"
#include <stdint.h>
/*
Manually add declarations for the runtime functions that we want to make sure
we're testing. We can't include any headers directly since they likely contain
C++ code that would explode here.
*/
struct EnvironmentDefaultList;
struct Descriptor;
double RTNAME(CpuTime)();
void RTNAME(ProgramStart)(
int, const char *[], const char *[], const struct EnvironmentDefaultList *);
int32_t RTNAME(ArgumentCount)();
int32_t RTNAME(GetCommandArgument)(int32_t, const struct Descriptor *,
const struct Descriptor *, const struct Descriptor *);
int32_t RTNAME(GetEnvVariable)();
int main() {
double x = RTNAME(CpuTime)();
RTNAME(ProgramStart)(0, 0, 0, 0);
int32_t c = RTNAME(ArgumentCount)();
int32_t v = RTNAME(GetCommandArgument)(0, 0, 0, 0);
int32_t e = RTNAME(GetEnvVariable)("FOO", 0, 0);
return x + c + v + e;
}

View File

@ -1,22 +0,0 @@
import os
import lit.Test
config.name = "flang-rt-OldUnit"
config.suffixes = [".test"]
config.test_source_root = os.path.join(config.flang_rt_obj_root, "unittests")
config.test_exec_root = config.test_source_root
config.test_format = lit.formats.ExecutableTest()
path = os.path.pathsep.join(
(
config.flang_rt_lib_dir,
config.flang_bin_dir,
config.flang_libs_dir,
config.environment.get("LD_LIBRARY_PATH", ""),
)
)
config.environment["LD_LIBRARY_PATH"] = path

View File

@ -1,23 +0,0 @@
@LIT_SITE_CFG_IN_HEADER@
config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@")
config.llvm_libs_dir = lit_config.substitute("@LLVM_LIBS_DIR@")
config.llvm_build_mode = lit_config.substitute("@LLVM_BUILD_MODE@")
config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
config.flang_src_dir = "@FLANG_SOURCE_DIR@"
config.flang_bin_dir = "@FLANG_BINARY_DIR@/bin"
config.flang_libs_dir = "@FLANG_BINARY_DIR@/lib"
config.flang_rt_obj_root = "@FLANG_RT_BINARY_DIR@"
config.flang_tools_dir = lit_config.substitute("@FLANG_TOOLS_DIR@")
config.flang_llvm_tools_dir = "@CMAKE_BINARY_DIR@/bin"
config.flang_rt_src_dir = "@FLANG_RT_SOURCE_DIR@"
config.flang_rt_lib_dir = "@FLANG_RT_BINARY_DIR@/lib"
config.flang_rt_test_compiler = "@FLANG_RT_TEST_COMPILER@"
config.flang_rt_test_triple = "@FLANG_RT_TEST_TARGET_TRIPLE@"
config.target_triple = "@LLVM_TARGET_TRIPLE@"
config.python_executable = "@Python3_EXECUTABLE@"
# Let the main config do the real work.
lit_config.load_config(config, "@FLANG_RT_SOURCE_DIR@/test/NonGtestUnit/lit.cfg.py")

View File

@ -1,58 +0,0 @@
# -*- Python -*-
# Configuration file for the 'lit' test runner.
import os
import platform
import re
import subprocess
import sys
import lit.formats
import lit.util
from lit.llvm import llvm_config
from lit.llvm.subst import ToolSubst
from lit.llvm.subst import FindTool
# 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.
# test_exec_root: The root path where tests should be run.
config.test_source_root = os.path.join(config.flang_rt_obj_root, "unittests")
config.test_exec_root = config.test_source_root
# testFormat: The test format to use to interpret tests.
config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, "Tests")
# Tweak the PATH to include the flang bin and libs dirs.
path = os.path.pathsep.join(
(
config.flang_bin_dir,
config.llvm_tools_dir,
config.environment["PATH"]
)
)
config.environment["PATH"] = path
path = os.path.pathsep.join(
(
config.flang_rt_lib_dir,
config.flang_libs_dir,
config.flang_bin_dir,
config.environment.get("LD_LIBRARY_PATH", ""),
)
)
config.environment["LD_LIBRARY_PATH"] = path
# Propagate PYTHON_EXECUTABLE into the environment
# config.environment['PYTHON_EXECUTABLE'] = sys.executable
# To modify the default target triple for flang-rt tests.
if config.flang_rt_test_triple:
config.target_triple = config.flang_rt_test_triple
config.environment[config.llvm_target_triple_env] = config.flang_rt_test_triple

View File

@ -1,22 +0,0 @@
@LIT_SITE_CFG_IN_HEADER@
config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_target_triple_env = "@LLVM_TARGET_TRIPLE_ENV@"
config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@")
config.llvm_build_mode = lit_config.substitute("@LLVM_BUILD_MODE@")
config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
config.flang_bin_dir = "@FLANG_BINARY_DIR@/bin"
config.flang_src_dir = "@FLANG_SOURCE_DIR@"
config.flang_libs_dir = "@FLANG_BINARY_DIR@/lib"
config.flang_rt_obj_root = "@FLANG_RT_BINARY_DIR@"
config.flang_rt_src_dir = "@FLANG_RT_SOURCE_DIR@"
config.flang_rt_lib_dir = "@FLANG_RT_BINARY_DIR@/lib"
config.flang_rt_test_compiler = "@FLANG_RT_TEST_COMPILER@"
config.flang_rt_test_triple = "@FLANG_RT_TEST_TARGET_TRIPLE@"
config.flang_tools_dir = lit_config.substitute("@FLANG_TOOLS_DIR@")
config.target_triple = "@LLVM_TARGET_TRIPLE@"
config.python_executable = "@Python3_EXECUTABLE@"
# Let the main config do the real work.
lit_config.load_config(config, "@FLANG_RT_SOURCE_DIR@/test/Unit/lit.cfg.py")

View File

@ -1,173 +0,0 @@
# -*- Python -*-
import os
import platform
import re
import subprocess
import sys
import lit.formats
import lit.util
from lit.llvm import llvm_config
from lit.llvm.subst import ToolSubst
from lit.llvm.subst import FindTool
# 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",
]
config.substitutions.append(("%PATH%", config.environment["PATH"]))
config.substitutions.append(("%pluginext", config.llvm_plugin_ext))
llvm_config.use_default_substitutions()
# ask llvm-config about asserts
llvm_config.feature_config([("--assertion-mode", {"ON": "asserts"})])
# Targets
config.targets = frozenset(config.targets_to_build.split())
for arch in config.targets_to_build.split():
config.available_features.add(arch.lower() + "-registered-target")
# To modify the default target triple for flang-rt tests.
if config.flang_rt_test_triple:
config.target_triple = config.flang_rt_test_triple
config.environment[config.llvm_target_triple_env] = config.flang_rt_test_triple
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt"]
# Plugins (loadable modules)
if config.has_plugins:
config.available_features.add("plugins")
if config.linked_bye_extension:
config.substitutions.append(("%loadbye", ""))
else:
config.substitutions.append(
(
"%loadbye",
"-fpass-plugin={}/Bye{}".format(
config.llvm_shlib_dir, config.llvm_plugin_ext
),
)
)
# 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.
config.test_exec_root = os.path.join(config.flang_rt_obj_root, "test")
llvm_config.with_environment("PATH", config.flang_bin_dir, append_path=True)
llvm_config.with_environment("PATH", config.flang_rt_obj_root, append_path=True)
llvm_config.with_environment("PATH", config.flang_libs_dir, append_path=True)
llvm_config.with_environment("PATH", config.flang_rt_lib_dir, append_path=True)
# For each occurrence of a flang tool name, replace it with the full path to
# the build directory holding that tool.
tools = [
ToolSubst("%flang", command=FindTool("flang-new"), unresolved="fatal"),
ToolSubst(
"%flang_fc1",
command=FindTool("flang-new"),
extra_args=["-fc1"],
unresolved="fatal",
),
]
# Flang has several unimplemented features. TODO messages are used to mark
# and fail if these features are exercised. Some TODOs exit with a non-zero
# exit code, but others abort the execution in assert builds.
# To catch aborts, the `--crash` option for the `not` command has to be used.
tools.append(ToolSubst("%not_todo_cmd", command=FindTool("not"), unresolved="fatal"))
if "asserts" in config.available_features:
tools.append(
ToolSubst(
"%not_todo_abort_cmd",
command=FindTool("not"),
extra_args=["--crash"],
unresolved="fatal",
)
)
else:
tools.append(
ToolSubst("%not_todo_abort_cmd", command=FindTool("not"), unresolved="fatal")
)
# 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.cc:
libruntime_static = os.path.join(config.flang_rt_lib_dir, "libflang-rt.a")
libruntime_shared = os.path.join(config.flang_rt_lib_dir, "libflang-rt.so")
include = os.path.join(config.flang_src_dir, "include")
if (
os.path.isfile(libruntime_static)
and os.path.isdir(include)
):
config.available_features.add("c-compiler")
tools.append(ToolSubst("%cc", command=config.cc, unresolved="fatal"))
tools.append(ToolSubst("%libruntime", command=libruntime_static, unresolved="fatal"))
tools.append(ToolSubst("%include", command=include, unresolved="fatal"))
elif (
os.path.isfile(libruntime_shared)
and os.path.isdir(include)
):
config.available_features.add("c-compiler")
tools.append(ToolSubst("%cc", command=config.cc, unresolved="fatal"))
tools.append(ToolSubst("%libruntime", command=libruntime_shared, 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.
llvm_config.add_tool_substitutions(tools, config.llvm_tools_dir)
# Enable libpgmath testing
result = lit_config.params.get("LIBPGMATH")
if result:
config.environment["LIBPGMATH"] = True

View File

@ -1,31 +0,0 @@
@LIT_SITE_CFG_IN_HEADER@
import sys
config.llvm_tools_dir = lit_config.substitute("@LLVM_TOOLS_DIR@")
config.llvm_shlib_dir = lit_config.substitute(path(r"@SHLIBDIR@"))
config.llvm_plugin_ext = "@LLVM_PLUGIN_EXT@"
config.target_triple = "@LLVM_TARGET_TRIPLE@"
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_src_dir = "@FLANG_SOURCE_DIR@"
config.flang_bin_dir = "@FLANG_BINARY_DIR@/bin"
config.flang_libs_dir = "@FLANG_BINARY_DIR@/lib"
config.flang_tools_dir = lit_config.substitute("@FLANG_TOOLS_DIR@")
config.flang_llvm_tools_dir = "@CMAKE_BINARY_DIR@/bin"
config.flang_rt_obj_root = "@FLANG_RT_BINARY_DIR@"
config.flang_rt_src_dir = "@FLANG_RT_SOURCE_DIR@"
config.flang_rt_lib_dir = "@FLANG_RT_BINARY_DIR@/lib"
config.flang_rt_test_triple = "@FLANG_RT_TEST_TARGET_TRIPLE@"
config.python_executable = "@PYTHON_EXECUTABLE@"
config.has_plugins = @LLVM_ENABLE_PLUGINS@
config.linked_bye_extension = @LLVM_BYE_LINK_INTO_TOOLS@
config.cc = "@CMAKE_C_COMPILER@"
config.targets_to_build = "@TARGETS_TO_BUILD@"
import lit.llvm
lit.llvm.initialize(lit_config, config)
# Let the main config do the real work.
lit_config.load_config(config, "@FLANG_RT_SOURCE_DIR@/test/lit.cfg.py")

View File

@ -1,81 +0,0 @@
if (FLANG_EXPERIMENTAL_CUDA_RUNTIME)
# If Fortran runtime is built as CUDA library, the linking
# of targets that link FortranRuntime 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()
add_custom_target(FlangRTUnitTests)
set_target_properties(FlangRTUnitTests PROPERTIES FOLDER "Flang-rt Unit Tests")
function(add_flang_rt_unittest_offload_properties target)
# Set CUDA_RESOLVE_DEVICE_SYMBOLS.
if (FLANG_EXPERIMENTAL_CUDA_RUNTIME)
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.
# Common code must be moved from flang/runtime/CMakeLists.txt.
# TODO: Revisit this because of Flang-rt. runtime is no longer an added subdirectory of flang.
if (NOT FLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD STREQUAL "off")
set_target_properties(${target}
PROPERTIES LINK_OPTIONS
"-fopenmp;--offload-arch=native"
)
endif()
endfunction()
if(NOT TARGET llvm_gtest)
message(FATAL_ERROR "Target llvm_gtest not found.")
endif()
function(add_flang_rt_unittest test_dirname)
add_unittest(FlangRTUnitTests ${test_dirname} ${ARGN})
add_flang_rt_unittest_offload_properties(${test_dirname})
endfunction()
if (CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
add_compile_options("-Wno-suggest-override")
endif()
function(add_flang_rt_nongtest_unittest test_name)
cmake_parse_arguments(ARG
"SLOW_TEST"
""
""
${ARGN})
list(APPEND LLVM_COMPILE_FLAGS "-L${LLVM_BINARY_DIR}/lib")
if(ARG_SLOW_TEST)
set(suffix .slow)
else()
set(suffix .test)
endif()
add_executable(${test_name}${suffix} ${test_name}.cpp)
if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
set(llvm_libs LLVM)
else()
llvm_map_components_to_libnames(llvm_libs Support)
endif()
target_link_libraries(${test_name}${suffix} ${llvm_libs} ${ARG_UNPARSED_ARGUMENTS})
if(NOT ARG_SLOW_TEST)
add_dependencies(FlangRTUnitTests ${test_name}${suffix})
endif()
add_flang_rt_unittest_offload_properties(${test_name}${suffix})
endfunction()
add_subdirectory(FortranRuntime)
# TODO: We may want to find a better location for these tests that use the runtime
add_subdirectory(FortranEvaluate)

View File

@ -1,21 +0,0 @@
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_library(FlangRTFortranEvaluateTesting
testing.cpp
)
if (LLVM_LINK_LLVM_DYLIB)
set(llvm_libs LLVM)
else()
llvm_map_components_to_libnames(llvm_libs Support)
endif()
target_link_libraries(FlangRTFortranEvaluateTesting
${llvm_libs})
add_flang_rt_nongtest_unittest(reshape
FlangRTFortranEvaluateTesting
flang-rt
)
add_flang_rt_nongtest_unittest(ISO-Fortran-binding
FlangRTFortranEvaluateTesting
flang-rt
)

View File

@ -1,128 +0,0 @@
#include "testing.h"
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
namespace testing {
namespace {
int passes{0};
int failures{0};
} // namespace
static void BitBucket(const char *, ...) {}
static void PrintFailureDetails(const char *format, ...) {
va_list ap;
va_start(ap, format);
fputs("\t", stderr);
vfprintf(stderr, format, ap);
va_end(ap);
fputc('\n', stderr);
}
FailureDetailPrinter Test(const char *file, int line, const char *predicate,
bool pass) {
if (pass) {
++passes;
return BitBucket;
} else {
++failures;
fprintf(stderr, "%s:%d: FAIL: %s\n", file, line, predicate);
return PrintFailureDetails;
}
}
FailureDetailPrinter Match(const char *file, int line, std::uint64_t want,
const char *gots, std::uint64_t got) {
if (want == got) {
++passes;
return BitBucket;
} else {
++failures;
fprintf(stderr, "%s:%d: FAIL: %s == 0x%jx, not 0x%jx\n", file, line, gots,
static_cast<std::uintmax_t>(got),
static_cast<std::uintmax_t>(want));
return PrintFailureDetails;
}
}
FailureDetailPrinter Match(const char *file, int line, const char *want,
const char *gots, const std::string &got) {
if (want == got) {
++passes;
return BitBucket;
} else {
++failures;
fprintf(stderr, "%s:%d: FAIL: %s == \"%s\", not \"%s\"\n", file, line, gots,
got.data(), want);
return PrintFailureDetails;
}
}
FailureDetailPrinter Match(const char *file, int line, const std::string &want,
const char *gots, const std::string &got) {
return Match(file, line, want.data(), gots, got);
}
FailureDetailPrinter Compare(const char *file, int line, const char *xs,
const char *rel, const char *ys, std::uint64_t x,
std::uint64_t y) {
while (*rel == ' ') {
++rel;
}
bool pass{false};
if (*rel == '<') {
if (rel[1] == '=') {
pass = x <= y;
} else {
pass = x < y;
}
} else if (*rel == '>') {
if (rel[1] == '=') {
pass = x >= y;
} else {
pass = x > y;
}
} else if (*rel == '=') {
pass = x == y;
} else if (*rel == '!') {
pass = x != y;
}
if (pass) {
++passes;
return BitBucket;
} else {
++failures;
fprintf(stderr, "%s:%d: FAIL: %s[0x%jx] %s %s[0x%jx]\n", file, line, xs,
static_cast<std::uintmax_t>(x), rel, ys,
static_cast<std::uintmax_t>(y));
return PrintFailureDetails;
}
}
int Complete() {
if (failures == 0) {
if (passes == 1) {
fprintf(stdout, "single test PASSES\n");
} else {
fprintf(stdout, "all %d tests PASS\n", passes);
}
passes = 0;
return EXIT_SUCCESS;
} else {
if (passes == 1) {
fprintf(stderr, "1 test passes, ");
} else {
fprintf(stderr, "%d tests pass, ", passes);
}
if (failures == 1) {
fprintf(stderr, "1 test FAILS\n");
} else {
fprintf(stderr, "%d tests FAIL\n", failures);
}
passes = failures = 0;
return EXIT_FAILURE;
}
}
} // namespace testing

View File

@ -1,37 +0,0 @@
#ifndef FORTRAN_EVALUATE_TESTING_H_
#define FORTRAN_EVALUATE_TESTING_H_
#include <cinttypes>
#include <string>
namespace testing {
// Returns EXIT_SUCCESS or EXIT_FAILURE, so a test's main() should end
// with "return testing::Complete()".
int Complete();
// Pass/fail testing. These macros return a pointer to a printf-like
// function that can be optionally called to print more detail, e.g.
// COMPARE(x, ==, y)("z is 0x%llx", z);
// will also print z after the usual failure message if x != y.
#define TEST(predicate) \
testing::Test(__FILE__, __LINE__, #predicate, (predicate))
#define MATCH(want, got) testing::Match(__FILE__, __LINE__, (want), #got, (got))
#define COMPARE(x, rel, y) \
testing::Compare(__FILE__, __LINE__, #x, #rel, #y, (x), (y))
// Functions called by these macros; do not call directly.
using FailureDetailPrinter = void (*)(const char *, ...);
FailureDetailPrinter Test(const char *file, int line, const char *predicate,
bool pass);
FailureDetailPrinter Match(const char *file, int line, std::uint64_t want,
const char *gots, std::uint64_t got);
FailureDetailPrinter Match(const char *file, int line, const char *want,
const char *gots, const std::string &got);
FailureDetailPrinter Match(const char *file, int line, const std::string &want,
const char *gots, const std::string &got);
FailureDetailPrinter Compare(const char *file, int line, const char *xs,
const char *rel, const char *ys, std::uint64_t x,
std::uint64_t y);
} // namespace testing
#endif // FORTRAN_EVALUATE_TESTING_H_

View File

@ -188,7 +188,7 @@ if (FLANG_STANDALONE_BUILD)
if (FLANG_GTEST_AVAIL)
add_custom_target(check-all DEPENDS check-flang FlangUnitTests)
else()
add_custom_target(check-all DEPENDS check-flang)
add_custom_target(check-all DEPENDS check-flang )
endif()
if (LLVM_BUILD_DOCS)
add_custom_target(doxygen ALL)
@ -421,11 +421,6 @@ if (FLANG_INCLUDE_TESTS)
add_compile_definitions(FLANG_INCLUDE_TESTS=1)
endif()
# Add Flang subdirectories.
# NOTE: The runtime subdirectory is no longer added here.
# Sources for the runtime are added in Flang-rt.
# TODO: Move the runtime sources to the flang-rt top level directory.
add_subdirectory(include)
add_subdirectory(lib)
add_subdirectory(cmake/modules)
@ -435,6 +430,7 @@ option(FLANG_BUILD_TOOLS
if (FLANG_BUILD_TOOLS)
add_subdirectory(tools)
endif()
add_subdirectory(runtime)
if (LLVM_INCLUDE_EXAMPLES)
add_subdirectory(examples)

View File

@ -17,7 +17,7 @@ macro(add_flang_subdirectory name)
endmacro()
function(add_flang_library name)
set(options SHARED STATIC INSTALL_WITH_TOOLCHAIN PIC)
set(options SHARED STATIC INSTALL_WITH_TOOLCHAIN)
set(multiValueArgs ADDITIONAL_HEADERS CLANG_LIBS)
cmake_parse_arguments(ARG
"${options}"
@ -65,9 +65,6 @@ function(add_flang_library name)
endif()
llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs})
if (ARG_PIC)
set_target_properties(${name} PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif()
clang_target_link_libraries(${name} PRIVATE ${ARG_CLANG_LIBS})

View File

@ -9,8 +9,6 @@ find_package(LLVM ${LLVM_VERSION} EXACT REQUIRED CONFIG
set(FLANG_EXPORTED_TARGETS "@FLANG_EXPORTS@")
set(FLANG_CMAKE_DIR "@FLANG_CONFIG_CMAKE_DIR@")
set(FLANG_INCLUDE_DIRS "@FLANG_CONFIG_INCLUDE_DIRS@")
set(FLANG_SOURCE_DIR "@FLANG_SOURCE_DIR@")
set(FLANG_BINARY_DIR "@FLANG_BINARY_DIR@")
# Provide all our library targets to users.
@FLANG_CONFIG_INCLUDE_EXPORTS@

View File

@ -49,19 +49,7 @@ endif()
# avoid an unwanted dependency on libstdc++.so.
add_definitions(-U_GLIBCXX_ASSERTIONS)
# Build FortranDecimal when the build target is Flang or LLVM.
if (CMAKE_SOURCE_DIR STREQUAL FLANG_SOURCE_DIR OR CMAKE_SOURCE_DIR STREQUAL LLVM_MAIN_SRC_DIR)
add_flang_library(FortranDecimal
binary-to-decimal.cpp
decimal-to-binary.cpp
)
# Build FortranDecimalRT for FlangRT when the build target is Runtimes.
# Standalone builds of FlangRT is not supported.
elseif (CMAKE_SOURCE_DIR STREQUAL Runtimes_SOURCE_DIR)
add_flang_library(FortranDecimalRT STATIC INSTALL_WITH_TOOLCHAIN PIC
binary-to-decimal.cpp
decimal-to-binary.cpp
)
else()
message(FATAL_ERROR "CMAKE_SOURCE_DIR of target points to neither Flang or Flang-rt, no library added for FortranDecimal.")
endif()
add_flang_library(FortranDecimal INSTALL_WITH_TOOLCHAIN
binary-to-decimal.cpp
decimal-to-binary.cpp
)

View File

@ -6,14 +6,10 @@
#
#===------------------------------------------------------------------------===#
# TODO: Maybe this file should still be added by flang/CMakeLists.txt and
# when FLANG_STANDALONE_BUILD=On and a new variable FLANG_BUILD_RUNTIME=On
# we should invoke an ExternalProject_Add(flang-rt ...) from here?
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
cmake_minimum_required(VERSION 3.20.0)
project(FortranRuntime C CXX)
project(FlangRuntime C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
@ -86,6 +82,8 @@ append(${NO_LTO_FLAGS} CMAKE_CXX_FLAGS)
add_definitions(-U_GLIBCXX_ASSERTIONS)
add_definitions(-U_LIBCPP_ENABLE_ASSERTIONS)
add_subdirectory(FortranMain)
set(sources
ISO_Fortran_binding.cpp
allocatable.cpp
@ -270,13 +268,10 @@ if (NOT FLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD STREQUAL "off")
endif()
endif()
add_compile_options(-fPIC)
add_flang_library(FortranRuntime STATIC
add_flang_library(FortranRuntime
${sources}
LINK_LIBS
FortranDecimalRT
FortranDecimal
INSTALL_WITH_TOOLCHAIN
PIC
)

View File

@ -138,15 +138,10 @@ CppTypeFor<TypeCategory::Real, 10> RTNAME(SumReal10)(const Descriptor &x,
}
#endif
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
#if HAS_FLOAT128
using AccumType = __float128;
#else // if LDBL_MANT_DIG == 113
using AccumType = long double;
#endif
CppTypeFor<TypeCategory::Real, 16> RTNAME(SumReal16)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Real, 16>(
x, source, line, dim, mask, RealSumAccumulator<AccumType>{x}, "SUM");
x, source, line, dim, mask, RealSumAccumulator<long double>{x}, "SUM");
}
#endif

View File

@ -61,6 +61,9 @@ set(FLANG_TEST_DEPENDS
llvm-objdump
llvm-readobj
split-file
FortranRuntime
Fortran_main
FortranDecimal
)
if (LLVM_ENABLE_PLUGINS AND NOT WIN32)
list(APPEND FLANG_TEST_DEPENDS Bye)

View File

@ -24,18 +24,21 @@
! GNU-LABEL: "{{.*}}ld{{(\.exe)?}}"
! GNU-SAME: "[[object_file]]"
! GNU-SAME: -lFortran_main
! GNU-SAME: -lflang-rt
! GNU-SAME: -lFortranRuntime
! GNU-SAME: -lFortranDecimal
! GNU-SAME: -lm
! DARWIN-LABEL: "{{.*}}ld{{(\.exe)?}}"
! DARWIN-SAME: "[[object_file]]"
! DARWIN-SAME: -lFortran_main
! DARWIN-SAME: -lflang-rt
! DARWIN-SAME: -lFortranRuntime
! DARWIN-SAME: -lFortranDecimal
! MINGW-LABEL: "{{.*}}ld{{(\.exe)?}}"
! MINGW-SAME: "[[object_file]]"
! MINGW-SAME: -lFortran_main
! MINGW-SAME: -lflang-rt
! MINGW-SAME: -lFortranRuntime
! MINGW-SAME: -lFortranDecimal
! NOTE: This also matches lld-link (when CLANG_DEFAULT_LINKER=lld) and
! any .exe suffix that is added when resolving to the full path of
@ -43,6 +46,7 @@
! when the executable is not found or on non-Windows platforms.
! MSVC-LABEL: link
! MSVC-SAME: Fortran_main.lib
! MSVC-SAME: flang-rt.lib
! MSVC-SAME: FortranRuntime.lib
! MSVC-SAME: FortranDecimal.lib
! MSVC-SAME: /subsystem:console
! MSVC-SAME: "[[object_file]]"

View File

@ -153,16 +153,19 @@ else:
# 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.cc:
libruntime = os.path.join(config.flang_lib_dir, "libflang-rt.a")
libruntime = os.path.join(config.flang_lib_dir, "libFortranRuntime.a")
libdecimal = os.path.join(config.flang_lib_dir, "libFortranDecimal.a")
include = os.path.join(config.flang_src_dir, "include")
if (
os.path.isfile(libruntime)
and os.path.isfile(libdecimal)
and os.path.isdir(include)
):
config.available_features.add("c-compiler")
tools.append(ToolSubst("%cc", command=config.cc, unresolved="fatal"))
tools.append(ToolSubst("%libruntime", command=libruntime, unresolved="fatal"))
tools.append(ToolSubst("%libdecimal", command=libdecimal, 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

View File

@ -14,6 +14,14 @@ set( LLVM_LINK_COMPONENTS
add_flang_tool(flang-new
driver.cpp
fc1_main.cpp
DEPENDS
# These libraries are used in the linker invocation generated by the driver
# (i.e. when constructing the linker job). Without them the driver would be
# unable to generate executables.
FortranRuntime
FortranDecimal
Fortran_main
)
target_link_libraries(flang-new

View File

@ -24,15 +24,11 @@ function(add_flang_unittest_offload_properties target)
# FIXME: replace 'native' in --offload-arch option with the list
# of targets that Fortran Runtime was built for.
# Common code must be moved from flang/runtime/CMakeLists.txt.
# TODO: Revisit this because of Flang-rt. runtime is no longer an added subdirectory of flang. So we temporarily duplicated the option definition to here. This is not a permanent solution.
set(FLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD "off" CACHE STRING
"Compile Fortran runtime as OpenMP target offload sources (experimental). Valid options are 'off', 'host_device', 'nohost'")
if (NOT FLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD STREQUAL "off")
set_target_properties(${target}
PROPERTIES LINK_OPTIONS
"-fopenmp;--offload-arch=native"
)
PROPERTIES LINK_OPTIONS
"-fopenmp;--offload-arch=native"
)
endif()
endfunction()
@ -78,4 +74,5 @@ add_subdirectory(Optimizer)
add_subdirectory(Common)
add_subdirectory(Decimal)
add_subdirectory(Evaluate)
add_subdirectory(Runtime)
add_subdirectory(Frontend)

View File

@ -45,6 +45,7 @@ add_flang_nongtest_unittest(intrinsics
FortranDecimal
FortranSemantics
FortranParser
FortranRuntime
)
add_flang_nongtest_unittest(logical
@ -67,6 +68,20 @@ add_flang_nongtest_unittest(real
)
llvm_update_compile_flags(real.test)
add_flang_nongtest_unittest(reshape
FortranEvaluateTesting
FortranSemantics
FortranEvaluate
FortranRuntime
)
add_flang_nongtest_unittest(ISO-Fortran-binding
FortranEvaluateTesting
FortranEvaluate
FortranSemantics
FortranRuntime
)
add_flang_nongtest_unittest(folding
FortranCommon
FortranEvaluateTesting

View File

@ -19,6 +19,16 @@ add_flang_unittest(FlangOptimizerTests
Builder/DoLoopHelperTest.cpp
Builder/FIRBuilderTest.cpp
Builder/HLFIRToolsTest.cpp
Builder/Runtime/AllocatableTest.cpp
Builder/Runtime/AssignTest.cpp
Builder/Runtime/CommandTest.cpp
Builder/Runtime/CharacterTest.cpp
Builder/Runtime/DerivedTest.cpp
Builder/Runtime/NumericTest.cpp
Builder/Runtime/RaggedTest.cpp
Builder/Runtime/ReductionTest.cpp
Builder/Runtime/StopTest.cpp
Builder/Runtime/TransformationalTest.cpp
FIRContextTest.cpp
FIRTypesTest.cpp
FortranVariableTest.cpp

View File

@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "flang/../../runtime/buffer.h"
#include "../../runtime/buffer.h"
#include "CrashHandlerFixture.h"
#include "gtest/gtest.h"
#include <algorithm>
@ -30,16 +30,15 @@ public:
void set_expect(FileOffset to) { expect_ = to; }
std::size_t Read(FileOffset at, char *to, std::size_t minBytes,
std::size_t maxBytes, IoErrorHandler &handler) {
std::size_t maxBytes, IoErrorHandler &handler) {
if (enforceSequence_ && at != expect_) {
handler.SignalError("Read(%d,%d,%d) not at expected %d",
static_cast<int>(at), static_cast<int>(minBytes),
static_cast<int>(maxBytes),
static_cast<int>(expect_));
static_cast<int>(at), static_cast<int>(minBytes),
static_cast<int>(maxBytes), static_cast<int>(expect_));
} else if (at < 0 || at + minBytes > bytes_) {
handler.SignalError("Read(%d,%d,%d) is out of bounds",
static_cast<int>(at), static_cast<int>(minBytes),
static_cast<int>(maxBytes));
static_cast<int>(at), static_cast<int>(minBytes),
static_cast<int>(maxBytes));
}
auto result{std::min<std::size_t>(maxBytes, bytes_ - at)};
std::memcpy(to, &data_[at], result);
@ -47,14 +46,14 @@ public:
return result;
}
std::size_t Write(FileOffset at, const char *from, std::size_t bytes,
IoErrorHandler &handler) {
IoErrorHandler &handler) {
if (enforceSequence_ && at != expect_) {
handler.SignalError("Write(%d,%d) not at expected %d",
static_cast<int>(at), static_cast<int>(bytes),
static_cast<int>(expect_));
static_cast<int>(at), static_cast<int>(bytes),
static_cast<int>(expect_));
} else if (at < 0 || at + bytes > bytes_) {
handler.SignalError("Write(%d,%d) is out of bounds", static_cast<int>(at),
static_cast<int>(bytes));
static_cast<int>(bytes));
}
std::memcpy(&data_[at], from, bytes);
expect_ = at + bytes;
@ -71,8 +70,8 @@ private:
inline int ChunkSize(int j, int most) {
// 31, 1, 29, 3, 27, ...
j %= tinyBufferSize;
auto chunk{static_cast<int>(((j % 2) ? j : (tinyBufferSize - 1 - j)) %
tinyBufferSize)};
auto chunk{static_cast<int>(
((j % 2) ? j : (tinyBufferSize - 1 - j)) % tinyBufferSize)};
return std::min(chunk, most);
}

View File

@ -1,4 +1,4 @@
add_flang_rt_unittest(FortranRuntimeTests
add_flang_unittest(FlangRuntimeTests
Allocatable.cpp
ArrayConstructor.cpp
BufferTest.cpp
@ -29,7 +29,7 @@ add_flang_rt_unittest(FortranRuntimeTests
Transformational.cpp
)
target_link_libraries(FortranRuntimeTests
target_link_libraries(FlangRuntimeTests
PRIVATE
flang-rt
FortranRuntime
)

View File

@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
#include "CrashHandlerFixture.h"
#include "flang/../../runtime/terminator.h"
#include "../../runtime/terminator.h"
#include <cstdarg>
#include <cstdlib>
// Replaces Fortran runtime's crash handler so we can verify the crash message
[[noreturn]] static void CatchCrash(const char *sourceFile, int sourceLine,
const char *message, va_list &ap) {
[[noreturn]] static void CatchCrash(
const char *sourceFile, int sourceLine, const char *message, va_list &ap) {
char buffer[1000];
std::vsnprintf(buffer, sizeof buffer, message, ap);
va_end(ap);

View File

@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "CrashHandlerFixture.h"
#include "flang/../../runtime/io-error.h"
#include "../../runtime/io-error.h"
#include "flang/Runtime/descriptor.h"
#include "flang/Runtime/io-api.h"
@ -36,15 +36,15 @@ TEST(InputTest, TestListInputAlphabet) {
// Use _two_ input buffers and _three_ output buffers. Note the `3*` in the
// _inputBuffers_.
SetCharacter(inputBuffers[j++], maxInputBufferLength,
"3*'abcdefghijklmnopqrstuvwxyzABC");
SetCharacter(inputBuffers[j++], maxInputBufferLength,
"DEFGHIJKLMNOPQRSTUVWXYZ'");
"3*'abcdefghijklmnopqrstuvwxyzABC");
SetCharacter(
inputBuffers[j++], maxInputBufferLength, "DEFGHIJKLMNOPQRSTUVWXYZ'");
StaticDescriptor<1> staticDescriptor;
Descriptor &whole{staticDescriptor.descriptor()};
SubscriptValue extent[]{numInputBuffers};
whole.Establish(TypeCode{CFI_type_char}, maxInputBufferLength, &inputBuffers,
1, extent, CFI_attribute_pointer);
1, extent, CFI_attribute_pointer);
whole.Check();
auto *cookie{IONAME(BeginInternalArrayListInput)(whole)};
@ -79,7 +79,7 @@ TEST(InputTest, TestListInputIntegerList) {
Descriptor &whole{staticDescriptor.descriptor()};
SubscriptValue extent[]{numBuffers};
whole.Establish(TypeCode{CFI_type_char}, maxBufferLength, &buffer, 1, extent,
CFI_attribute_pointer);
CFI_attribute_pointer);
whole.Check();
auto *cookie{IONAME(BeginInternalArrayListInput)(whole)};
@ -88,10 +88,10 @@ TEST(InputTest, TestListInputIntegerList) {
// Negative numbers will be overwritten by _expectedOutput_, and positive
// numbers will not be as their indices are "Null values" of the Fortran 2018
// standard 13.10.3.2 in the format strings _buffer_
std::int64_t actualOutput[listInputLength]{-1, -2, -3, -4, 5,
-6, 7, -8, 9, 10};
const std::int64_t expectedOutput[listInputLength]{1, 2, 3, 3, 5,
6, 7, 8, 9, 10};
std::int64_t actualOutput[listInputLength]{
-1, -2, -3, -4, 5, -6, 7, -8, 9, 10};
const std::int64_t expectedOutput[listInputLength]{
1, 2, 3, 3, 5, 6, 7, 8, 9, 10};
for (j = 0; j < listInputLength; ++j) {
IONAME(InputInteger)(cookie, actualOutput[j]);
}
@ -116,7 +116,7 @@ TEST(InputTest, TestListInputInvalidFormatWithSingleSuccess) {
Descriptor &whole{staticDescriptor.descriptor()};
SubscriptValue extent[]{numBuffers};
whole.Establish(TypeCode{CFI_type_char}, formatBuffer.size(),
formatBuffer.data(), 1, extent, CFI_attribute_pointer);
formatBuffer.data(), 1, extent, CFI_attribute_pointer);
whole.Check();
auto *cookie{IONAME(BeginInternalArrayListInput)(whole)};
@ -127,7 +127,7 @@ TEST(InputTest, TestListInputInvalidFormatWithSingleSuccess) {
// Perform failing InputInteger
ASSERT_DEATH(IONAME(InputInteger)(cookie, dummy),
"Bad character 'g' in INTEGER input field");
"Bad character 'g' in INTEGER input field");
}
// Same test as _TestListInputInvalidFormatWithSingleSuccess_, however no
@ -140,7 +140,7 @@ TEST(InputTest, TestListInputInvalidFormat) {
Descriptor &whole{staticDescriptor.descriptor()};
SubscriptValue extent[]{numBuffers};
whole.Establish(TypeCode{CFI_type_char}, formatBuffer.size(),
formatBuffer.data(), 1, extent, CFI_attribute_pointer);
formatBuffer.data(), 1, extent, CFI_attribute_pointer);
whole.Check();
auto *cookie{IONAME(BeginInternalArrayListInput)(whole)};
@ -148,7 +148,7 @@ TEST(InputTest, TestListInputInvalidFormat) {
// Perform failing InputInteger
ASSERT_DEATH(IONAME(InputInteger)(cookie, dummy),
"Bad character 'g' in INTEGER input field");
"Bad character 'g' in INTEGER input field");
}
using ParamTy = std::tuple<std::string, std::vector<int>>;
@ -163,7 +163,7 @@ TEST_P(SimpleListInputTest, TestListInput) {
Descriptor &whole{staticDescriptor.descriptor()};
SubscriptValue extent[]{numBuffers};
whole.Establish(TypeCode{CFI_type_char}, formatBuffer.size(),
formatBuffer.data(), 1, extent, CFI_attribute_pointer);
formatBuffer.data(), 1, extent, CFI_attribute_pointer);
whole.Check();
auto *cookie{IONAME(BeginInternalArrayListInput)(whole)};
@ -185,10 +185,9 @@ TEST_P(SimpleListInputTest, TestListInput) {
}
}
INSTANTIATE_TEST_SUITE_P(
SimpleListInputTestInstantiation, SimpleListInputTest,
INSTANTIATE_TEST_SUITE_P(SimpleListInputTestInstantiation, SimpleListInputTest,
testing::Values(std::make_tuple("", std::vector<int>{}),
std::make_tuple("0", std::vector<int>{}),
std::make_tuple("1", std::vector<int>{1}),
std::make_tuple("1, 2", std::vector<int>{1, 2}),
std::make_tuple("3*2", std::vector<int>{2, 2, 2})));
std::make_tuple("0", std::vector<int>{}),
std::make_tuple("1", std::vector<int>{1}),
std::make_tuple("1, 2", std::vector<int>{1, 2}),
std::make_tuple("3*2", std::vector<int>{2, 2, 2})));

View File

@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
#include "flang/../../runtime/namelist.h"
#include "../../runtime/namelist.h"
#include "CrashHandlerFixture.h"
#include "tools.h"
#include "flang/Runtime/descriptor.h"
#include "flang/Runtime/io-api.h"
#include "tools.h"
#include <algorithm>
#include <cinttypes>
#include <complex>
@ -27,7 +27,7 @@ struct NamelistTests : CrashHandlerFixture {};
static void ClearDescriptorStorage(const Descriptor &descriptor) {
std::memset(descriptor.raw().base_addr, 0,
descriptor.Elements() * descriptor.ElementBytes());
descriptor.Elements() * descriptor.ElementBytes());
}
TEST(NamelistTests, BasicSanity) {
@ -38,20 +38,17 @@ TEST(NamelistTests, BasicSanity) {
Descriptor &internalDesc{statDescs[0].descriptor()};
SubscriptValue extent[]{numLines};
internalDesc.Establish(TypeCode{CFI_type_char}, /*elementBytes=*/lineLength,
&buffer, 1, extent, CFI_attribute_pointer);
&buffer, 1, extent, CFI_attribute_pointer);
// Set up data arrays
std::vector<int> ints;
for (int j{0}; j < 20; ++j) {
ints.push_back(j % 2 == 0 ? (1 << j) : -(1 << j));
}
std::vector<double> reals{0.0,
-0.0,
std::numeric_limits<double>::infinity(),
-std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::max(),
std::numeric_limits<double>::lowest(),
std::numeric_limits<double>::epsilon()};
std::vector<double> reals{0.0, -0.0, std::numeric_limits<double>::infinity(),
-std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::max(), std::numeric_limits<double>::lowest(),
std::numeric_limits<double>::epsilon()};
std::vector<std::uint8_t> logicals;
logicals.push_back(false);
logicals.push_back(true);
@ -79,14 +76,12 @@ TEST(NamelistTests, BasicSanity) {
// Create a NAMELIST group
static constexpr int items{5};
const NamelistGroup::Item itemArray[items]{{"ints", *intDesc},
{"reals", *realDesc},
{"logicals", *logicalDesc},
{"complexes", *complexDesc},
{"characters", *characterDesc}};
{"reals", *realDesc}, {"logicals", *logicalDesc},
{"complexes", *complexDesc}, {"characters", *characterDesc}};
const NamelistGroup group{"group1", items, itemArray};
// Do an internal NAMELIST write and check results
auto outCookie1{IONAME(BeginInternalArrayListOutput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
auto outCookie1{IONAME(BeginInternalArrayListOutput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(SetDelim)(outCookie1, "APOSTROPHE", 10));
ASSERT_TRUE(IONAME(OutputNamelist)(outCookie1, group));
auto outStatus1{IONAME(EndIoStatement)(outCookie1)};
@ -114,14 +109,14 @@ TEST(NamelistTests, BasicSanity) {
ClearDescriptorStorage(*logicalDesc);
ClearDescriptorStorage(*complexDesc);
ClearDescriptorStorage(*characterDesc);
auto inCookie{IONAME(BeginInternalArrayListInput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
auto inCookie{IONAME(BeginInternalArrayListInput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(InputNamelist)(inCookie, group));
auto inStatus{IONAME(EndIoStatement)(inCookie)};
ASSERT_EQ(inStatus, 0) << "Failed namelist input sanity, status "
<< static_cast<int>(inStatus);
auto outCookie2{IONAME(BeginInternalArrayListOutput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
auto outCookie2{IONAME(BeginInternalArrayListOutput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(SetDelim)(outCookie2, "APOSTROPHE", 10));
ASSERT_TRUE(IONAME(OutputNamelist)(outCookie2, group));
auto outStatus2{IONAME(EndIoStatement)(outCookie2)};
@ -144,19 +139,18 @@ TEST(NamelistTests, Subscripts) {
StaticDescriptor<1, true> statDesc;
Descriptor &internalDesc{statDesc.descriptor()};
internalDesc.Establish(TypeCode{CFI_type_char},
/*elementBytes=*/std::strlen(t1), t1, 0, nullptr,
CFI_attribute_pointer);
auto inCookie{IONAME(BeginInternalArrayListInput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
/*elementBytes=*/std::strlen(t1), t1, 0, nullptr, CFI_attribute_pointer);
auto inCookie{IONAME(BeginInternalArrayListInput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(InputNamelist)(inCookie, group));
auto inStatus{IONAME(EndIoStatement)(inCookie)};
ASSERT_EQ(inStatus, 0) << "Failed namelist input subscripts, status "
<< static_cast<int>(inStatus);
char out[40];
internalDesc.Establish(TypeCode{CFI_type_char}, /*elementBytes=*/sizeof out,
out, 0, nullptr, CFI_attribute_pointer);
auto outCookie{IONAME(BeginInternalArrayListOutput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
out, 0, nullptr, CFI_attribute_pointer);
auto outCookie{IONAME(BeginInternalArrayListOutput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(OutputNamelist)(outCookie, group));
auto outStatus{IONAME(EndIoStatement)(outCookie)};
ASSERT_EQ(outStatus, 0)
@ -183,8 +177,8 @@ TEST(NamelistTests, ShortArrayInput) {
Descriptor &internalDesc{statDesc.descriptor()};
SubscriptValue shape{2};
internalDesc.Establish(1, 12, t1, 1, &shape, CFI_attribute_pointer);
auto inCookie{IONAME(BeginInternalArrayListInput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
auto inCookie{IONAME(BeginInternalArrayListInput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(InputNamelist)(inCookie, group));
auto inStatus{IONAME(EndIoStatement)(inCookie)};
ASSERT_EQ(inStatus, 0) << "Failed namelist input subscripts, status "
@ -204,18 +198,17 @@ TEST(NamelistTests, ScalarSubstring) {
StaticDescriptor<1, true> statDesc;
Descriptor &internalDesc{statDesc.descriptor()};
internalDesc.Establish(TypeCode{CFI_type_char},
/*elementBytes=*/std::strlen(t1), t1, 0, nullptr,
CFI_attribute_pointer);
auto inCookie{IONAME(BeginInternalArrayListInput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
/*elementBytes=*/std::strlen(t1), t1, 0, nullptr, CFI_attribute_pointer);
auto inCookie{IONAME(BeginInternalArrayListInput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(InputNamelist)(inCookie, group));
ASSERT_EQ(IONAME(EndIoStatement)(inCookie), IostatOk)
<< "namelist scalar substring input";
char out[32];
internalDesc.Establish(TypeCode{CFI_type_char}, /*elementBytes=*/sizeof out,
out, 0, nullptr, CFI_attribute_pointer);
auto outCookie{IONAME(BeginInternalArrayListOutput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
out, 0, nullptr, CFI_attribute_pointer);
auto outCookie{IONAME(BeginInternalArrayListOutput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(SetDelim)(outCookie, "apostrophe", 10));
ASSERT_TRUE(IONAME(OutputNamelist)(outCookie, group));
ASSERT_EQ(IONAME(EndIoStatement)(outCookie), IostatOk) << "namelist output";
@ -225,27 +218,26 @@ TEST(NamelistTests, ScalarSubstring) {
}
TEST(NamelistTests, ArraySubstring) {
OwningPtr<Descriptor> scDesc{MakeArray<TypeCategory::Character, 1>(
std::vector<int>{2}, std::vector<std::string>{"abcdefgh", "ijklmnop"},
8)};
OwningPtr<Descriptor> scDesc{
MakeArray<TypeCategory::Character, 1>(std::vector<int>{2},
std::vector<std::string>{"abcdefgh", "ijklmnop"}, 8)};
const NamelistGroup::Item items[]{{"a", *scDesc}};
const NamelistGroup group{"justa", 1, items};
static char t1[]{"&justa A(:)(2:+5)='BCDE' 'JKLM'/"};
StaticDescriptor<1, true> statDesc;
Descriptor &internalDesc{statDesc.descriptor()};
internalDesc.Establish(TypeCode{CFI_type_char},
/*elementBytes=*/std::strlen(t1), t1, 0, nullptr,
CFI_attribute_pointer);
auto inCookie{IONAME(BeginInternalArrayListInput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
/*elementBytes=*/std::strlen(t1), t1, 0, nullptr, CFI_attribute_pointer);
auto inCookie{IONAME(BeginInternalArrayListInput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(InputNamelist)(inCookie, group));
ASSERT_EQ(IONAME(EndIoStatement)(inCookie), IostatOk)
<< "namelist scalar substring input";
char out[40];
internalDesc.Establish(TypeCode{CFI_type_char}, /*elementBytes=*/sizeof out,
out, 0, nullptr, CFI_attribute_pointer);
auto outCookie{IONAME(BeginInternalArrayListOutput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
out, 0, nullptr, CFI_attribute_pointer);
auto outCookie{IONAME(BeginInternalArrayListOutput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(SetDelim)(outCookie, "apostrophe", 10));
ASSERT_TRUE(IONAME(OutputNamelist)(outCookie, group));
ASSERT_EQ(IONAME(EndIoStatement)(outCookie), IostatOk) << "namelist output";
@ -264,18 +256,17 @@ TEST(NamelistTests, Skip) {
StaticDescriptor<1, true> statDesc;
Descriptor &internalDesc{statDesc.descriptor()};
internalDesc.Establish(TypeCode{CFI_type_char},
/*elementBytes=*/std::strlen(t1), t1, 0, nullptr,
CFI_attribute_pointer);
auto inCookie{IONAME(BeginInternalArrayListInput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
/*elementBytes=*/std::strlen(t1), t1, 0, nullptr, CFI_attribute_pointer);
auto inCookie{IONAME(BeginInternalArrayListInput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(InputNamelist)(inCookie, group));
ASSERT_EQ(IONAME(EndIoStatement)(inCookie), IostatOk)
<< "namelist input with skipping";
char out[20];
internalDesc.Establish(TypeCode{CFI_type_char}, /*elementBytes=*/sizeof out,
out, 0, nullptr, CFI_attribute_pointer);
auto outCookie{IONAME(BeginInternalArrayListOutput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
out, 0, nullptr, CFI_attribute_pointer);
auto outCookie{IONAME(BeginInternalArrayListOutput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(OutputNamelist)(outCookie, group));
ASSERT_EQ(IONAME(EndIoStatement)(outCookie), IostatOk) << "namelist output";
std::string got{out, sizeof out};
@ -294,19 +285,18 @@ TEST(NamelistTests, Comma) {
StaticDescriptor<1, true> statDesc;
Descriptor &internalDesc{statDesc.descriptor()};
internalDesc.Establish(TypeCode{CFI_type_char},
/*elementBytes=*/std::strlen(t1), t1, 0, nullptr,
CFI_attribute_pointer);
auto inCookie{IONAME(BeginInternalArrayListInput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
/*elementBytes=*/std::strlen(t1), t1, 0, nullptr, CFI_attribute_pointer);
auto inCookie{IONAME(BeginInternalArrayListInput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(SetDecimal)(inCookie, "COMMA", 5));
ASSERT_TRUE(IONAME(InputNamelist)(inCookie, group));
ASSERT_EQ(IONAME(EndIoStatement)(inCookie), IostatOk)
<< "namelist input with skipping";
char out[30];
internalDesc.Establish(TypeCode{CFI_type_char}, /*elementBytes=*/sizeof out,
out, 0, nullptr, CFI_attribute_pointer);
auto outCookie{IONAME(BeginInternalArrayListOutput)(internalDesc, nullptr, 0,
__FILE__, __LINE__)};
out, 0, nullptr, CFI_attribute_pointer);
auto outCookie{IONAME(BeginInternalArrayListOutput)(
internalDesc, nullptr, 0, __FILE__, __LINE__)};
ASSERT_TRUE(IONAME(SetDecimal)(outCookie, "COMMA", 5));
ASSERT_TRUE(IONAME(OutputNamelist)(outCookie, group));
ASSERT_EQ(IONAME(EndIoStatement)(outCookie), IostatOk) << "namelist output";

View File

@ -11,10 +11,10 @@
//
//===----------------------------------------------------------------------===//
#include "CrashHandlerFixture.h"
#include "flang/../../runtime/terminator.h"
#include "tools.h"
#include "../../runtime/terminator.h"
#include "flang/Runtime/io-api.h"
#include "flang/Runtime/transformational.h"
#include "tools.h"
#include <gtest/gtest.h>
using namespace Fortran::runtime;
@ -26,7 +26,7 @@ using Fortran::common::TypeCategory;
//------------------------------------------------------------------------------
struct TestTerminator : CrashHandlerFixture {};
#define TEST_CRASH_HANDLER_MESSAGE \
#define TEST_CRASH_HANDLER_MESSAGE \
"Intentionally crashing runtime for unit test"
TEST(TestTerminator, CrashTest) {
@ -39,13 +39,13 @@ TEST(TestTerminator, CrashTest) {
TEST(TestTerminator, CheckFailedLocationTest) {
static Fortran::runtime::Terminator t;
ASSERT_DEATH(t.CheckFailed("predicate", "someFileName", 789),
"RUNTIME_CHECK\\(predicate\\) failed at someFileName\\(789\\)");
"RUNTIME_CHECK\\(predicate\\) failed at someFileName\\(789\\)");
}
TEST(TestTerminator, CheckFailedTest) {
static Fortran::runtime::Terminator t;
ASSERT_DEATH(t.CheckFailed("predicate"),
"RUNTIME_CHECK\\(predicate\\) failed at \\(null\\)\\(0\\)");
"RUNTIME_CHECK\\(predicate\\) failed at \\(null\\)\\(0\\)");
}
//------------------------------------------------------------------------------
@ -57,10 +57,9 @@ TEST(TestIOCrash, FormatDescriptorWriteMismatchTest) {
static constexpr int bufferSize{4};
static char buffer[bufferSize];
static const char *format{"(A4)"};
auto *cookie{IONAME(BeginInternalFormattedOutput)(buffer, bufferSize, format,
std::strlen(format))};
ASSERT_DEATH(
IONAME(OutputLogical)(cookie, true),
auto *cookie{IONAME(BeginInternalFormattedOutput)(
buffer, bufferSize, format, std::strlen(format))};
ASSERT_DEATH(IONAME(OutputLogical)(cookie, true),
"Data edit descriptor 'A' may not be used with a LOGICAL data item");
}
@ -68,10 +67,10 @@ TEST(TestIOCrash, InvalidFormatCharacterTest) {
static constexpr int bufferSize{1};
static char buffer[bufferSize];
static const char *format{"(C1)"};
auto *cookie{IONAME(BeginInternalFormattedOutput)(buffer, bufferSize, format,
std::strlen(format))};
auto *cookie{IONAME(BeginInternalFormattedOutput)(
buffer, bufferSize, format, std::strlen(format))};
ASSERT_DEATH(IONAME(OutputInteger64)(cookie, 0xfeedface),
"Unknown 'C' edit descriptor in FORMAT");
"Unknown 'C' edit descriptor in FORMAT");
}
//------------------------------------------------------------------------------
@ -84,80 +83,80 @@ TEST(TestIOCrash, OverwriteBufferAsciiTest) {
static constexpr int bufferSize{4};
static char buffer[bufferSize];
static const char *format{"(A4)"};
auto *cookie{IONAME(BeginInternalFormattedOutput)(buffer, bufferSize, format,
std::strlen(format))};
auto *cookie{IONAME(BeginInternalFormattedOutput)(
buffer, bufferSize, format, std::strlen(format))};
IONAME(OutputAscii)(cookie, "four", bufferSize);
ASSERT_DEATH(IONAME(OutputAscii)(cookie, "Too many characters!", 20),
"Internal write overran available records");
"Internal write overran available records");
}
TEST(TestIOCrash, OverwriteBufferCharacterTest) {
static constexpr int bufferSize{1};
static char buffer[bufferSize];
static const char *format{"(A1)"};
auto *cookie{IONAME(BeginInternalFormattedOutput)(buffer, bufferSize, format,
std::strlen(format))};
auto *cookie{IONAME(BeginInternalFormattedOutput)(
buffer, bufferSize, format, std::strlen(format))};
IONAME(OutputCharacter)(cookie, "a", 1);
ASSERT_DEATH(IONAME(OutputCharacter)(cookie, "a", 1),
"Internal write overran available records");
"Internal write overran available records");
}
TEST(TestIOCrash, OverwriteBufferLogicalTest) {
static constexpr int bufferSize{1};
static char buffer[bufferSize];
static const char *format{"(L1)"};
auto *cookie{IONAME(BeginInternalFormattedOutput)(buffer, bufferSize, format,
std::strlen(format))};
auto *cookie{IONAME(BeginInternalFormattedOutput)(
buffer, bufferSize, format, std::strlen(format))};
IONAME(OutputLogical)(cookie, true);
ASSERT_DEATH(IONAME(OutputLogical)(cookie, true),
"Internal write overran available records");
"Internal write overran available records");
}
TEST(TestIOCrash, OverwriteBufferRealTest) {
static constexpr int bufferSize{1};
static char buffer[bufferSize];
static const char *format{"(F1)"};
auto *cookie{IONAME(BeginInternalFormattedOutput)(buffer, bufferSize, format,
std::strlen(format))};
auto *cookie{IONAME(BeginInternalFormattedOutput)(
buffer, bufferSize, format, std::strlen(format))};
IONAME(OutputReal32)(cookie, 1.);
EXPECT_DEATH(IONAME(OutputReal32)(cookie, 1.),
"Internal write overran available records");
"Internal write overran available records");
std::memset(buffer, '\0', bufferSize);
cookie = IONAME(BeginInternalFormattedOutput)(buffer, bufferSize, format,
std::strlen(format));
cookie = IONAME(BeginInternalFormattedOutput)(
buffer, bufferSize, format, std::strlen(format));
IONAME(OutputReal64)(cookie, 1.);
EXPECT_DEATH(IONAME(OutputReal64)(cookie, 1.),
"Internal write overran available records");
"Internal write overran available records");
}
TEST(TestIOCrash, OverwriteBufferComplexTest) {
static constexpr int bufferSize{8};
static char buffer[bufferSize];
static const char *format{"(Z1,Z1)"};
auto *cookie{IONAME(BeginInternalFormattedOutput)(buffer, bufferSize, format,
std::strlen(format))};
auto *cookie{IONAME(BeginInternalFormattedOutput)(
buffer, bufferSize, format, std::strlen(format))};
IONAME(OutputComplex32)(cookie, 1., 1.);
EXPECT_DEATH(IONAME(OutputComplex32)(cookie, 1., 1.),
"Internal write overran available records");
"Internal write overran available records");
std::memset(buffer, '\0', bufferSize);
cookie = IONAME(BeginInternalFormattedOutput)(buffer, bufferSize, format,
std::strlen(format));
cookie = IONAME(BeginInternalFormattedOutput)(
buffer, bufferSize, format, std::strlen(format));
IONAME(OutputComplex64)(cookie, 1., 1.);
EXPECT_DEATH(IONAME(OutputComplex64)(cookie, 1., 1.),
"Internal write overran available records");
"Internal write overran available records");
}
TEST(TestIOCrash, OverwriteBufferIntegerTest) {
static constexpr int bufferSize{1};
static char buffer[bufferSize];
static const char *format{"(I1)"};
auto *cookie{IONAME(BeginInternalFormattedOutput)(buffer, bufferSize, format,
std::strlen(format))};
auto *cookie{IONAME(BeginInternalFormattedOutput)(
buffer, bufferSize, format, std::strlen(format))};
IONAME(OutputInteger64)(cookie, 0xdeadbeef);
ASSERT_DEATH(IONAME(OutputInteger64)(cookie, 0xdeadbeef),
"Internal write overran available records");
"Internal write overran available records");
}
//------------------------------------------------------------------------------
@ -169,15 +168,13 @@ TEST(TestIntrinsicCrash, ConformityErrors) {
// ARRAY(2,3) and MASK(2,4) should trigger a runtime error.
auto array{MakeArray<TypeCategory::Integer, 4>(
std::vector<int>{2, 3}, std::vector<std::int32_t>{1, 2, 3, 4, 5, 6})};
auto mask{MakeArray<TypeCategory::Logical, 1>(
std::vector<int>{2, 4},
std::vector<std::uint8_t>{false, true, true, false, false, true, true,
true})};
auto mask{MakeArray<TypeCategory::Logical, 1>(std::vector<int>{2, 4},
std::vector<std::uint8_t>{
false, true, true, false, false, true, true, true})};
StaticDescriptor<1, true> statDesc;
Descriptor &result{statDesc.descriptor()};
ASSERT_DEATH(
RTNAME(Pack)(result, *array, *mask, nullptr, __FILE__, __LINE__),
ASSERT_DEATH(RTNAME(Pack)(result, *array, *mask, nullptr, __FILE__, __LINE__),
"Incompatible array arguments to PACK: dimension 2 of ARRAY= has extent "
"3 but MASK= has extent 4");
}

View File

@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Runtime/stop.h"
#include "CrashHandlerFixture.h"
#include "flang/../../runtime/environment.h"
#include "../../runtime/environment.h"
#include <cstdlib>
#include <gtest/gtest.h>
@ -21,69 +21,67 @@ struct TestProgramEnd : CrashHandlerFixture {};
TEST(TestProgramEnd, StopTest) {
EXPECT_EXIT(RTNAME(StopStatement)(), testing::ExitedWithCode(EXIT_SUCCESS),
"Fortran STOP");
"Fortran STOP");
}
TEST(TestProgramEnd, StopTestNoStopMessage) {
putenv(const_cast<char *>("NO_STOP_MESSAGE=1"));
Fortran::runtime::executionEnvironment.Configure(0, nullptr, nullptr,
nullptr);
EXPECT_EXIT(RTNAME(StopStatement)(), testing::ExitedWithCode(EXIT_SUCCESS),
"");
Fortran::runtime::executionEnvironment.Configure(
0, nullptr, nullptr, nullptr);
EXPECT_EXIT(
RTNAME(StopStatement)(), testing::ExitedWithCode(EXIT_SUCCESS), "");
}
TEST(TestProgramEnd, StopMessageTest) {
static const char *message{"bye bye"};
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
/*isErrorStop=*/false, /*quiet=*/false),
testing::ExitedWithCode(EXIT_SUCCESS), "Fortran STOP: bye bye");
/*isErrorStop=*/false, /*quiet=*/false),
testing::ExitedWithCode(EXIT_SUCCESS), "Fortran STOP: bye bye");
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
/*isErrorStop=*/false, /*quiet=*/true),
testing::ExitedWithCode(EXIT_SUCCESS), "");
/*isErrorStop=*/false, /*quiet=*/true),
testing::ExitedWithCode(EXIT_SUCCESS), "");
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
/*isErrorStop=*/true, /*quiet=*/false),
testing::ExitedWithCode(EXIT_FAILURE),
"Fortran ERROR STOP: bye bye");
/*isErrorStop=*/true, /*quiet=*/false),
testing::ExitedWithCode(EXIT_FAILURE), "Fortran ERROR STOP: bye bye");
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
/*isErrorStop=*/true, /*quiet=*/true),
testing::ExitedWithCode(EXIT_FAILURE), "");
/*isErrorStop=*/true, /*quiet=*/true),
testing::ExitedWithCode(EXIT_FAILURE), "");
}
TEST(TestProgramEnd, NoStopMessageTest) {
putenv(const_cast<char *>("NO_STOP_MESSAGE=1"));
Fortran::runtime::executionEnvironment.Configure(0, nullptr, nullptr,
nullptr);
Fortran::runtime::executionEnvironment.Configure(
0, nullptr, nullptr, nullptr);
static const char *message{"bye bye"};
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
/*isErrorStop=*/false, /*quiet=*/false),
testing::ExitedWithCode(EXIT_SUCCESS), "bye bye");
/*isErrorStop=*/false, /*quiet=*/false),
testing::ExitedWithCode(EXIT_SUCCESS), "bye bye");
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
/*isErrorStop=*/false, /*quiet=*/true),
testing::ExitedWithCode(EXIT_SUCCESS), "");
/*isErrorStop=*/false, /*quiet=*/true),
testing::ExitedWithCode(EXIT_SUCCESS), "");
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
/*isErrorStop=*/true, /*quiet=*/false),
testing::ExitedWithCode(EXIT_FAILURE),
"Fortran ERROR STOP: bye bye");
/*isErrorStop=*/true, /*quiet=*/false),
testing::ExitedWithCode(EXIT_FAILURE), "Fortran ERROR STOP: bye bye");
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
/*isErrorStop=*/true, /*quiet=*/true),
testing::ExitedWithCode(EXIT_FAILURE), "");
/*isErrorStop=*/true, /*quiet=*/true),
testing::ExitedWithCode(EXIT_FAILURE), "");
}
TEST(TestProgramEnd, FailImageTest) {
EXPECT_EXIT(RTNAME(FailImageStatement)(),
testing::ExitedWithCode(EXIT_FAILURE), "");
EXPECT_EXIT(
RTNAME(FailImageStatement)(), testing::ExitedWithCode(EXIT_FAILURE), "");
}
TEST(TestProgramEnd, ExitTest) {
EXPECT_EXIT(RTNAME(Exit)(), testing::ExitedWithCode(EXIT_SUCCESS), "");
EXPECT_EXIT(RTNAME(Exit)(EXIT_FAILURE), testing::ExitedWithCode(EXIT_FAILURE),
"");
EXPECT_EXIT(
RTNAME(Exit)(EXIT_FAILURE), testing::ExitedWithCode(EXIT_FAILURE), "");
}
TEST(TestProgramEnd, AbortTest) { EXPECT_DEATH(RTNAME(Abort)(), ""); }
@ -93,8 +91,8 @@ TEST(TestProgramEnd, CrashTest) {
static const std::string fileName{"file name"};
static const std::string headMessage{"fatal Fortran runtime error\\("};
static const std::string tailMessage{":343\\): "};
static const std::string fullMessage{headMessage + fileName + tailMessage +
crashMessage};
static const std::string fullMessage{
headMessage + fileName + tailMessage + crashMessage};
EXPECT_DEATH(
RTNAME(ReportFatalUserError)(crashMessage.c_str(), fileName.c_str(), 343),
fullMessage.c_str());

View File

@ -50,7 +50,8 @@ AutoExporter::AutoExporter(
"libc++",
"libc++abi",
"libFortran_main",
"libflang-rt",
"libFortranRuntime",
"libFortranDecimal",
"libunwind",
"libmsvcrt",
"libucrtbase",

View File

@ -156,10 +156,7 @@ endif()
# 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")
if ("flang" IN_LIST LLVM_ENABLE_PROJECTS)
set(LLVM_DEFAULT_RUNTIMES "libcxx;libcxxabi;libunwind;flang-rt")
endif()
set(LLVM_SUPPORTED_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;llvm-libgcc;flang-rt")
set(LLVM_SUPPORTED_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;llvm-libgcc")
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")
@ -181,11 +178,6 @@ if ("libc" IN_LIST LLVM_ENABLE_RUNTIMES)
endif()
endif()
if ("flang" IN_LIST LLVM_ENABLE_PROJECTS AND NOT "flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
message(STATUS "Enabling Flang-rt to be built with the Flang project.")
list(APPEND LLVM_ENABLE_RUNTIMES "flang-rt")
endif()
# LLVM_ENABLE_PROJECTS_USED is `ON` if the user has ever used the
# `LLVM_ENABLE_PROJECTS` CMake cache variable. This exists for
# several reasons:

View File

@ -6,7 +6,6 @@ foreach(entry ${entries})
if(IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt)
if((NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/compiler-rt) AND
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/dragonegg) AND
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/flang-rt) AND
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/libcxx) AND
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/libcxxabi) AND
(NOT ${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/libunwind) AND
@ -38,8 +37,6 @@ 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)

View File

@ -401,24 +401,17 @@ if(runtimes)
endforeach()
endif()
endif()
set(EXTRA_CMAKE_ARGS "")
if("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
list(APPEND EXTRA_CMAKE_ARGS "-DLLVM_DIR=${LLVM_BINARY_DIR}/lib/cmake/llvm")
list(APPEND EXTRA_CMAKE_ARGS "-DFLANG_DIR=${LLVM_BINARY_DIR}/lib/cmake/flang")
list(APPEND EXTRA_CMAKE_ARGS "-DCLANG_DIR=${LLVM_BINARY_DIR}/lib/cmake/clang")
list(APPEND EXTRA_CMAKE_ARGS "-DMLIR_DIR=${LLVM_BINARY_DIR}/lib/cmake/mlir")
endif()
if(NOT LLVM_RUNTIME_TARGETS)
runtime_default_target(
DEPENDS ${builtins_dep} ${extra_deps}
CMAKE_ARGS ${libc_cmake_args} ${EXTRA_CMAKE_ARGS}
CMAKE_ARGS ${libc_cmake_args}
PREFIXES ${prefixes})
set(test_targets check-runtimes)
else()
if("default" IN_LIST LLVM_RUNTIME_TARGETS)
runtime_default_target(
DEPENDS ${builtins_dep} ${extra_deps}
CMAKE_ARGS ${libc_cmake_args} ${EXTRA_CMAKE_ARGS}
CMAKE_ARGS ${libc_cmake_args}
PREFIXES ${prefixes})
list(REMOVE_ITEM LLVM_RUNTIME_TARGETS "default")
else()
@ -458,7 +451,7 @@ if(runtimes)
runtime_register_target(${name}
DEPENDS ${builtins_dep_name} ${libc_tools}
CMAKE_ARGS -DLLVM_DEFAULT_TARGET_TRIPLE=${name} ${libc_cmake_args} ${EXTRA_CMAKE_ARGS}
CMAKE_ARGS -DLLVM_DEFAULT_TARGET_TRIPLE=${name} ${libc_cmake_args}
EXTRA_ARGS TARGET_TRIPLE ${name})
add_dependencies(runtimes runtimes-${name})
@ -488,7 +481,6 @@ if(runtimes)
CMAKE_ARGS -DLLVM_DEFAULT_TARGET_TRIPLE=${name}
-DLLVM_RUNTIMES_PREFIX=${name}/
-DLLVM_RUNTIMES_LIBDIR_SUBDIR=${multilib}
${EXTRA_CMAKE_ARGS}
BASE_NAME ${name}
EXTRA_ARGS TARGET_TRIPLE ${name})

View File

@ -19,7 +19,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;flang-rt")
set(LLVM_DEFAULT_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp")
set(LLVM_SUPPORTED_RUNTIMES "${LLVM_DEFAULT_RUNTIMES};llvm-libgcc")
set(LLVM_ENABLE_RUNTIMES "" CACHE STRING
"Semicolon-separated list of runtimes to build, or \"all\" (${LLVM_DEFAULT_RUNTIMES}). Supported runtimes are ${LLVM_SUPPORTED_RUNTIMES}.")