Skip to content

Commit 1bbcec4

Browse files
committed
Revise library location
1 parent c556e08 commit 1bbcec4

File tree

8 files changed

+264
-105
lines changed

8 files changed

+264
-105
lines changed

flang-rt/CMakeLists.txt

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,14 @@
1111
#
1212
#===------------------------------------------------------------------------===#
1313

14-
set(LLVM_SUBPROJECT_TITLE "Fortran Runtime")
14+
if (NOT LLVM_RUNTIMES_BUILD)
15+
message(FATAL_ERROR "Use this CMakeLists.txt from LLVM's runtimes build system.
16+
Example:
17+
cmake <llvm-project>/runtimes -DLLVM_ENABLE_RUNTIMES=flang-rt
18+
")
19+
endif ()
20+
21+
set(LLVM_SUBPROJECT_TITLE "Flang-RT")
1522
set(FLANG_RT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
1623
set(FLANG_RT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
1724
set(FLANG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../flang")
@@ -57,25 +64,31 @@ list(APPEND CMAKE_MODULE_PATH
5764
"${FLANG_SOURCE_DIR}/cmake/modules"
5865
)
5966
include(AddFlangRT)
67+
include(GetToolchainDirs)
6068
include(FlangCommon)
6169
include(HandleCompilerRT)
70+
include(ExtendPath)
71+
include(GNUInstallDirs)
6272

6373

6474
############################
6575
# Build Mode Introspection #
6676
############################
6777

68-
# Setting these variables from an LLVM build is sufficient that flang-rt can
69-
# construct the output paths, so it can behave as if it was in-tree here.
78+
# Determine whether we are in the runtimes/runtimes-bins directory of a
79+
# bootstrap build.
7080
set(LLVM_TREE_AVAILABLE OFF)
7181
if (LLVM_LIBRARY_OUTPUT_INTDIR AND LLVM_RUNTIME_OUTPUT_INTDIR AND PACKAGE_VERSION)
72-
# This is a bootstap build
7382
set(LLVM_TREE_AVAILABLE ON)
7483
endif()
7584

7685
# Path to LLVM development tools (FileCheck, llvm-lit, not, ...)
7786
set(LLVM_TOOLS_DIR "${LLVM_BINARY_DIR}/bin")
7887

88+
# Determine build and install paths.
89+
# The build path is absolute, but the install dir is relative, CMake's install
90+
# command has to apply CMAKE_INSTALL_PREFIX itself.
91+
get_toolchain_library_subdir(toolchain_lib_subdir)
7992
if (LLVM_TREE_AVAILABLE)
8093
# In a bootstrap build emit the libraries into a default search path in the
8194
# build directory of the just-built compiler. This allows using the
@@ -84,25 +97,31 @@ if (LLVM_TREE_AVAILABLE)
8497
# Despite Clang in the name, get_clang_resource_dir does not depend on Clang
8598
# being added to the build. Flang uses the same resource dir as clang.
8699
include(GetClangResourceDir)
87-
get_clang_resource_dir(FLANG_RT_BUILD_LIB_DIR PREFIX "${LLVM_LIBRARY_OUTPUT_INTDIR}/.." SUBDIR "lib${LLVM_LIBDIR_SUFFIX}")
88-
get_clang_resource_dir(FLANG_RT_INSTALL_LIB_DIR SUBDIR "lib${LLVM_LIBDIR_SUFFIX}") # No prefix, CMake's install command finds the install prefix itself
100+
get_clang_resource_dir(FLANG_RT_OUTPUT_DIR PREFIX "${LLVM_LIBRARY_OUTPUT_INTDIR}/..")
101+
get_clang_resource_dir(FLANG_RT_INSTALL_PATH)
102+
103+
extend_path(FLANG_RT_BUILD_TOOLCHAIN_LIB_DIR "${FLANG_RT_OUTPUT_DIR}" "${toolchain_lib_subdir}")
89104
else ()
90-
# In a runtimes build never write into LLVM's build dir. It might be reused
91-
# for mutliple Flang-RT builds (e.g. Debug/Release). Instead create our own
92-
# library directory.
93-
#
94-
# TODO: Support multi-config generators
95-
set(FLANG_RT_BUILD_LIB_DIR "${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}")
96-
set(FLANG_RT_INSTALL_LIB_DIR "lib${LLVM_LIBDIR_SUFFIX}")
105+
# In a standalone runtimes build, do not write into LLVM_BINARY_DIR. It may be
106+
# read-only and/or shared by multiple runtimes with different build
107+
# configurations (e.g. Debug/Release). Use the runtime's own lib dir like any
108+
# non-toolchain library.
109+
# For the install prefix, still use the resource dir assuming that Flang will
110+
# be installed there using the same prefix. This is to not have a difference
111+
# between bootstrap and standalone runtimes builds.
112+
set(FLANG_RT_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
113+
set(FLANG_RT_INSTALL_PATH "${CMAKE_INSTALL_LIBDIR}/clang/${LLVM_VERSION_MAJOR}")
114+
115+
extend_path(FLANG_RT_BUILD_TOOLCHAIN_LIB_DIR "${FLANG_RT_OUTPUT_DIR}" "${CMAKE_INSTALL_DIR}")
97116
endif ()
98117

99-
if (DEFINED WIN32)
100-
set(FLANG_RT_BUILD_LIB_DIR "${FLANG_RT_BUILD_LIB_DIR}/windows")
101-
set(FLANG_RT_INSTALL_LIB_DIR "${FLANG_RT_INSTALL_LIB_DIR}/windows")
102-
elseif (LLVM_ENABLE_PER_TARGET_RUNTIME_DIR)
103-
set(FLANG_RT_BUILD_LIB_DIR "${FLANG_RT_BUILD_LIB_DIR}/${LLVM_TARGET_TRIPLE}")
104-
set(FLANG_RT_INSTALL_LIB_DIR "${FLANG_RT_INSTALL_LIB_DIR}/${LLVM_TARGET_TRIPLE}")
105-
endif ()
118+
# Apply the arch-specific library dir with the resource dir.
119+
extend_path(FLANG_RT_INSTALL_TOOLCHAIN_LIB_DIR "${FLANG_RT_INSTALL_PATH}" "${toolchain_lib_subdir}")
120+
121+
cmake_path(NORMAL_PATH FLANG_RT_OUTPUT_DIR)
122+
cmake_path(NORMAL_PATH FLANG_RT_INSTALL_PATH)
123+
cmake_path(NORMAL_PATH FLANG_RT_BUILD_TOOLCHAIN_LIB_DIR)
124+
cmake_path(NORMAL_PATH FLANG_RT_INSTALL_TOOLCHAIN_LIB_DIR)
106125

107126

108127
#################

flang-rt/README.md

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ Requirements:
3131
* [Same as LLVM](https://llvm.org/docs/GettingStarted.html#requirements).
3232

3333

34-
### Bootstrap/In-Tree Build
34+
### Bootstrappng Runtimes Build
3535

36-
The bootstrap build will first build Clang and Flang, then use these compilers
37-
to compile Flang-RT. CMake will create a secondary build tree
36+
The bootstrapping build will first build Clang and Flang, then use these
37+
compilers to compile Flang-RT. CMake will create a secondary build tree
3838
configured to use these just-built compilers. The secondary build will reuse
3939
the same build options (Flags, Debug/Release, ...) as the primary build.
4040
It will also ensure that once built, Flang-RT is found by Flang from either
@@ -78,12 +78,12 @@ $ ninja install
7878
```
7979

8080

81-
### Runtime-only/Out-of-Tree Build
81+
### Standalone Runtimes Build
8282

83-
Instead of building Clang and Flang from scratch, the Runtime-only build uses
84-
CMake's environment introspection to find a C, C++, and Fortran compiler. The
85-
compiler to be used can be controlled using CMake's standard mechanisms such as
86-
`CMAKE_CXX_COMPILER`, `CMAKE_CXX_COMPILER`, and `CMAKE_Fortran_COMPILER`.
83+
Instead of building Clang and Flang from scratch, the standalone Runtime build
84+
uses CMake's environment introspection to find a C, C++, and Fortran compiler.
85+
The compiler to be used can be controlled using CMake's standard mechanisms such
86+
as `CMAKE_CXX_COMPILER`, `CMAKE_CXX_COMPILER`, and `CMAKE_Fortran_COMPILER`.
8787
`CMAKE_Fortran_COMPILER` must be `flang` built from the same Git commit as
8888
Flang-RT to ensure they are using the same ABI. The C and C++ compiler
8989
can be any compiler supporting the same ABI.
@@ -113,25 +113,15 @@ Of course, Flang-RT can be built multiple times with different build
113113
configurations, but have to be located manually when using with the Flang
114114
driver using the `-L` option.
115115

116-
A more complete build configuration could be the following:
116+
After configuration, build, test, and install the runtime via
117117

118-
```bash
119-
cmake -S <path-to-llvm-project-source>/runtimes \
120-
-GNinja \
121-
-DCMAKE_BUILD_TYPE=Release \
122-
-DCMAKE_INSTALL_PREFIX="${HOME}/local" \
123-
-DLLVM_ENABLE_RUNTIMES="compiler-rt;flang-rt" \
124-
-DCMAKE_C_COMPILER=gcc \
125-
-DCMAKE_CXX_COMPILER=g++ \
126-
-DLLVM_BINARY_DIR=<path-to-llvm-builddir> \
127-
-DLLVM_DIR=<path-to-llvm-builddir>/lib/cmake/llvm \
128-
-DClang_DIR=<path-to-llvm-builddir>/lib/cmake/clang \
129-
-DCMAKE_Fortran_COMPILER=<path-to-llvm-builddir-or-installprefix>/bin/flang \
130-
-DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-linux-gnu \
131-
-DLLVM_RUNTIMES_TARGET=x86_64-linux-gnu \
132-
...
118+
```shell
119+
$ ninja
120+
$ ninja check-flang-rt
121+
$ ninja install
133122
```
134123

124+
135125
## Configuration Option Reference
136126

137127
Flang-RT has the followign configuration options. This is in
@@ -170,7 +160,7 @@ CMake itself provide.
170160
(no `CMAKE_CUDA_COMPILER`).
171161

172162

173-
### Exprimental CUDA Support
163+
### Experimental CUDA Support
174164

175165
With `-DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA`, the following
176166
additional configuration options become available.
@@ -186,7 +176,7 @@ additional configuration options become available.
186176
default.
187177

188178

189-
### Exprimental OpenMP Offload Support
179+
### Experimental OpenMP Offload Support
190180

191181
With `-DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=OpenMP`, the following
192182
additional configuration options become available.

flang-rt/cmake/modules/AddFlangRT.cmake

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ function (add_flangrt_library name)
3838
${ARGN})
3939

4040
if (ARG_INSTALL_WITH_TOOLCHAIN AND ARG_EXCLUDE_FROM_ALL)
41-
message(SEND_ERROR "add_flangrt_library(${name} ...):
42-
INSTALL_WITH_TOOLCHAIN and EXCLUDE_FROM_ALL are in conflict. When
43-
installing an artifact it must have been built first in the 'all' target.
44-
")
41+
message(SEND_ERROR "add_flangrt_library(${name} ...):
42+
INSTALL_WITH_TOOLCHAIN and EXCLUDE_FROM_ALL are in conflict. When
43+
installing an artifact it must have been built first in the 'all' target.
44+
")
4545
endif ()
4646

4747
# Also add header files to IDEs to list as part of the library
@@ -110,7 +110,7 @@ function (add_flangrt_library name)
110110
# User applications can use #include <ISO_Fortran_binding.h>
111111
target_include_directories(${name} PRIVATE "${FLANG_SOURCE_DIR}/include")
112112

113-
# For flang-rt's configured config.h to be found
113+
# For Flang-RT's configured config.h to be found
114114
target_include_directories(${name} PRIVATE "${FLANG_RT_BINARY_DIR}")
115115

116116
# Disable libstdc++/libc++ assertions, even in an LLVM_ENABLE_ASSERTIONS
@@ -146,15 +146,15 @@ function (add_flangrt_library name)
146146
if (ARG_INSTALL_WITH_TOOLCHAIN)
147147
set_target_properties(${name}
148148
PROPERTIES
149-
LIBRARY_OUTPUT_DIRECTORY "${FLANG_RT_BUILD_LIB_DIR}"
150-
ARCHIVE_OUTPUT_DIRECTORY "${FLANG_RT_BUILD_LIB_DIR}"
151-
RUNTIME_OUTPUT_DIRECTORY "${FLANG_RT_BUILD_LIB_DIR}"
149+
LIBRARY_OUTPUT_DIRECTORY "${FLANG_RT_BUILD_TOOLCHAIN_LIB_DIR}"
150+
ARCHIVE_OUTPUT_DIRECTORY "${FLANG_RT_BUILD_TOOLCHAIN_LIB_DIR}"
151+
RUNTIME_OUTPUT_DIRECTORY "${FLANG_RT_BUILD_TOOLCHAIN_LIB_DIR}"
152152
)
153153

154154
install(TARGETS ${name}
155-
LIBRARY DESTINATION "${FLANG_RT_INSTALL_LIB_DIR}"
156-
ARCHIVE DESTINATION "${FLANG_RT_INSTALL_LIB_DIR}"
157-
RUNTIME DESTINATION "${FLANG_RT_INSTALL_LIB_DIR}"
155+
LIBRARY DESTINATION "${FLANG_RT_INSTALL_TOOLCHAIN_LIB_DIR}"
156+
ARCHIVE DESTINATION "${FLANG_RT_INSTALL_TOOLCHAIN_LIB_DIR}"
157+
RUNTIME DESTINATION "${FLANG_RT_INSTALL_TOOLCHAIN_LIB_DIR}"
158158
)
159159
endif ()
160160

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#===-- cmake/modules/GetToolchainDirs.cmake --------------------------------===#
2+
#
3+
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
# See https://llvm.org/LICENSE.txt for license information.
5+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
#
7+
#===------------------------------------------------------------------------===#
8+
9+
include(GNUInstallDirs)
10+
11+
12+
# Determine the subdirectory relative to Clang's resource dir/sysroot where to
13+
# install target-specific libraries, to be found by Clang/Flang driver. This was
14+
# adapted from Compiler-RT's mechanism to find the path for
15+
# libclang_rt.builtins.a.
16+
#
17+
# Compiler-RT has two mechanisms for the path (simplified):
18+
#
19+
# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=1: lib/${oslibname}/libclang_rt.builtins-${arch}.a
20+
# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=0: lib/${triple}/libclang_rt.builtins.a
21+
#
22+
# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON is the newer scheme, but the old one is
23+
# currently still used for some platforms such as Windows. Clang looks for which
24+
# of the files exist before passing the path to the linker. Hence, the
25+
# directories have to match what Clang is looking for, which is done in
26+
# ToolChain::getArchSpecificLibPaths(..), ToolChain::getRuntimePath(),
27+
# ToolChain::getCompilerRTPath(), and ToolChain::getCompilerRT(..), not entirely
28+
# consistent between these functions, Compiler-RT's CMake code, and overrides
29+
# in different toolchains.
30+
#
31+
# For Fortran, Flang always assumes the library name libflang_rt.a without
32+
# architecture suffix. Hence, we always use the second scheme even as if
33+
# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON, even if it actually set to OFF. It as
34+
# added unconditionally to the library search path by
35+
# ToolChain::getArchSpecificLibPaths(...).
36+
function (get_toolchain_library_subdir outvar)
37+
if (NOT APPLE)
38+
set(outval "${CMAKE_INSTALL_LIBDIR}")
39+
else ()
40+
# Required to be "darwin" for MachO toolchain.
41+
get_toolchain_os_dirname(os_dirname)
42+
set(outval "${CMAKE_INSTALL_LIBDIR}/${os_dirname}")
43+
endif ()
44+
45+
get_toolchain_arch_dirname(arch_dirname)
46+
set(outval "${CMAKE_INSTALL_LIBDIR}/${arch_dirname}")
47+
48+
set(${outvar} "${outval}" PARENT_SCOPE)
49+
endfunction ()
50+
51+
52+
# Corresponds to Clang's ToolChain::getOSLibName(). Adapted from Compiler-RT.
53+
function (get_toolchain_os_dirname outvar)
54+
if (ANDROID)
55+
# The CMAKE_SYSTEM_NAME for Android is "Android", but the OS is Linux and the
56+
# driver will search for libraries in the "linux" directory.
57+
set(outval "linux")
58+
else ()
59+
string(TOLOWER "${CMAKE_SYSTEM_NAME}" outval)
60+
endif ()
61+
set(${outvar} "${outval}" PARENT_SCOPE)
62+
endfunction ()
63+
64+
65+
# Corresponds to Clang's ToolChain::getRuntimePath(). Adapted from Compiler-RT.
66+
function (get_toolchain_arch_dirname outvar)
67+
string(REPLACE "-" ";" triple_list ${LLVM_TARGET_TRIPLE})
68+
list(GET triple_list 0 arch)
69+
70+
if("${arch}" MATCHES "^i.86$")
71+
# Android uses i686, but that's remapped at a later stage.
72+
set(arch "i386")
73+
endif()
74+
75+
string(FIND ${LLVM_TARGET_TRIPLE} "-" dash_index)
76+
string(SUBSTRING ${LLVM_TARGET_TRIPLE} ${dash_index} -1 triple_suffix)
77+
string(SUBSTRING ${LLVM_TARGET_TRIPLE} 0 ${dash_index} triple_cpu)
78+
set(arch "${triple_cpu}")
79+
if("${arch}" MATCHES "^i.86$")
80+
# Android uses i686, but that's remapped at a later stage.
81+
set(arch "i386")
82+
endif()
83+
84+
if(ANDROID AND ${arch} STREQUAL "i386")
85+
set(target "i686${triple_suffix}")
86+
elseif(${arch} STREQUAL "amd64")
87+
set(target "x86_64${triple_suffix}")
88+
elseif(${arch} STREQUAL "sparc64")
89+
set(target "sparcv9${triple_suffix}")
90+
elseif("${arch}" MATCHES "mips64|mips64el")
91+
string(REGEX REPLACE "-gnu.*" "-gnuabi64" triple_suffix_gnu "${triple_suffix}")
92+
string(REGEX REPLACE "mipsisa32" "mipsisa64" triple_cpu_mips "${triple_cpu}")
93+
string(REGEX REPLACE "^mips$" "mips64" triple_cpu_mips "${triple_cpu_mips}")
94+
string(REGEX REPLACE "^mipsel$" "mips64el" triple_cpu_mips "${triple_cpu_mips}")
95+
set(target "${triple_cpu_mips}${triple_suffix_gnu}")
96+
elseif("${arch}" MATCHES "mips|mipsel")
97+
string(REGEX REPLACE "-gnuabi.*" "-gnu" triple_suffix_gnu "${triple_suffix}")
98+
string(REGEX REPLACE "mipsisa64" "mipsisa32" triple_cpu_mips "${triple_cpu}")
99+
string(REGEX REPLACE "mips64" "mips" triple_cpu_mips "${triple_cpu_mips}")
100+
set(target "${triple_cpu_mips}${triple_suffix_gnu}")
101+
elseif("${arch}" MATCHES "^arm")
102+
# FIXME: Handle arch other than arm, armhf, armv6m
103+
if (${arch} STREQUAL "armhf")
104+
# If we are building for hard float but our ABI is soft float.
105+
if ("${triple_suffix}" MATCHES ".*eabi$")
106+
# Change "eabi" -> "eabihf"
107+
set(triple_suffix "${triple_suffix}hf")
108+
endif()
109+
# ABI is already set in the triple, don't repeat it in the architecture.
110+
set(arch "arm")
111+
else ()
112+
# If we are building for soft float, but the triple's ABI is hard float.
113+
if ("${triple_suffix}" MATCHES ".*eabihf$")
114+
# Change "eabihf" -> "eabi"
115+
string(REGEX REPLACE "hf$" "" triple_suffix "${triple_suffix}")
116+
endif()
117+
endif()
118+
set(target "${arch}${triple_suffix}")
119+
elseif("${arch}" MATCHES "^amdgcn")
120+
set(target "amdgcn-amd-amdhsa")
121+
elseif("${arch}" MATCHES "^nvptx")
122+
set(target "nvptx64-nvidia-cuda")
123+
else()
124+
set(target "${arch}${triple_suffix}")
125+
endif()
126+
set(${outvar} "${target}" PARENT_SCOPE)
127+
endfunction()

0 commit comments

Comments
 (0)