[llvm-branch-commits] [llvm] [Flang-RT] Build libflang_rt.so (PR #121782)
Michael Kruse via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Jan 6 07:52:07 PST 2025
https://github.com/Meinersbur created https://github.com/llvm/llvm-project/pull/121782
Under non-Windows platforms, also create a dynamic library version of the runtime. Build of either version of the library can be switched on using FLANG_RT_ENABLE_STATIC=ON respectively FLANG_RT_ENABLE_SHARED=ON. Default is to build only the static library, consistent with previous behaviour. This is because the way the flang driver invokes the linker, most linkers choose the dynamic library by default, if available. Building the dynamic library therefore causes flang-built executables to depend on `libflang_rt.so`, unless explicitly told otherwise.
PR on top of #110217.
>From a3037ab5557dcc4a4deb5bb40f801ca9770e3854 Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Mon, 6 Jan 2025 16:44:08 +0100
Subject: [PATCH] Add FLANG_RT_ENABLE_STATIC and FLANG_RT_ENABLE_SHARED
---
flang-rt/CMakeLists.txt | 30 ++
flang-rt/cmake/modules/AddFlangRT.cmake | 291 ++++++++++++------
.../cmake/modules/AddFlangRTOffload.cmake | 8 +-
flang-rt/cmake/modules/GetToolchainDirs.cmake | 254 +++++++--------
flang-rt/lib/flang_rt/CMakeLists.txt | 20 +-
flang-rt/test/CMakeLists.txt | 2 +-
flang-rt/test/lit.cfg.py | 2 +-
7 files changed, 366 insertions(+), 241 deletions(-)
diff --git a/flang-rt/CMakeLists.txt b/flang-rt/CMakeLists.txt
index 7b3d22e454a108..7effa6012a078f 100644
--- a/flang-rt/CMakeLists.txt
+++ b/flang-rt/CMakeLists.txt
@@ -113,6 +113,15 @@ cmake_path(NORMAL_PATH FLANG_RT_OUTPUT_RESOURCE_DIR)
cmake_path(NORMAL_PATH FLANG_RT_INSTALL_RESOURCE_PATH)
# Determine subdirectories for build output and install destinations.
+# FIXME: For the libflang_rt.so, the toolchain resource lib dir is not a good
+# destination because it is not a ld.so default search path.
+# The machine where the executable is eventually executed may not be the
+# machine where the Flang compiler and its resource dir is installed, so
+# setting RPath by the driver is not an solution. It should belong into
+# /usr/lib/<triple>/libflang_rt.so, like e.g. libgcc_s.so.
+# But the linker as invoked by the Flang driver also requires
+# libflang_rt.so to be found when linking and the resource lib dir is
+# the only reliable location.
get_toolchain_library_subdir(toolchain_lib_subdir)
extend_path(FLANG_RT_OUTPUT_RESOURCE_LIB_DIR "${FLANG_RT_OUTPUT_RESOURCE_DIR}" "${toolchain_lib_subdir}")
extend_path(FLANG_RT_INSTALL_RESOURCE_LIB_PATH "${FLANG_RT_INSTALL_RESOURCE_PATH}" "${toolchain_lib_subdir}")
@@ -130,6 +139,27 @@ cmake_path(NORMAL_PATH FLANG_RT_INSTALL_RESOURCE_LIB_PATH)
option(FLANG_RT_INCLUDE_TESTS "Generate build targets for the flang-rt unit and regression-tests." "${LLVM_INCLUDE_TESTS}")
+option(FLANG_RT_ENABLE_STATIC "Build Flang-RT as a static library." ON)
+if (WIN32)
+ # Windows DLL currently not implemented.
+ set(FLANG_RT_ENABLE_SHARED OFF)
+else ()
+ # TODO: Enable by default to increase test coverage, and which version of the
+ # library should be the user's choice anyway.
+ # Currently, the Flang driver adds `-L"libdir" -lflang_rt` as linker
+ # argument, which leaves the choice which library to use to the linker.
+ # Since most linkers prefer the shared library, this would constitute a
+ # breaking change unless the driver is changed.
+ option(FLANG_RT_ENABLE_SHARED "Build Flang-RT as a shared library." OFF)
+endif ()
+if (NOT FLANG_RT_ENABLE_STATIC AND NOT FLANG_RT_ENABLE_SHARED)
+ message(FATAL_ERROR "
+ Must build at least one type of library
+ (FLANG_RT_ENABLE_STATIC=ON, FLANG_RT_ENABLE_SHARED=ON, or both)
+ ")
+endif ()
+
+
set(FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT "" CACHE STRING "Compile Flang-RT with GPU support (CUDA or OpenMP)")
set_property(CACHE FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT PROPERTY STRINGS
""
diff --git a/flang-rt/cmake/modules/AddFlangRT.cmake b/flang-rt/cmake/modules/AddFlangRT.cmake
index 1f8b5111433825..5f493a80c35f20 100644
--- a/flang-rt/cmake/modules/AddFlangRT.cmake
+++ b/flang-rt/cmake/modules/AddFlangRT.cmake
@@ -16,7 +16,8 @@
# STATIC
# Build a static (.a/.lib) library
# OBJECT
-# Create only object files without static/dynamic library
+# Always create an object library.
+# Without SHARED/STATIC, build only the object library.
# INSTALL_WITH_TOOLCHAIN
# Install library into Clang's resource directory so it can be found by the
# Flang driver during compilation, including tests
@@ -44,17 +45,73 @@ function (add_flangrt_library name)
")
endif ()
- # Forward libtype to add_library
- set(extra_args "")
- if (ARG_SHARED)
- list(APPEND extra_args SHARED)
+ # Internal names of libraries. If called with just single type option, use
+ # the default name for it. Name of targets must only depend on function
+ # arguments to be predictable for callers.
+ set(name_static "${name}.static")
+ set(name_shared "${name}.shared")
+ set(name_object "obj.${name}")
+ if (ARG_STATIC AND NOT ARG_SHARED)
+ set(name_static "${name}")
+ elseif (NOT ARG_STATIC AND ARG_SHARED)
+ set(name_shared "${name}")
+ elseif (NOT ARG_STATIC AND NOT ARG_SHARED AND ARG_OBJECT)
+ set(name_object "${name}")
+ elseif (NOT ARG_STATIC AND NOT ARG_SHARED AND NOT ARG_OBJECT)
+ # Only one of them will actually be built.
+ set(name_static "${name}")
+ set(name_shared "${name}")
+ endif ()
+
+ # Determine what to build. If not explicitly specified, honor
+ # BUILD_SHARED_LIBS (e.g. for unittest libraries). If can build static and
+ # shared, use ENABLE_STATIC/ENABLE_SHARED setting.
+ if (ARG_STATIC AND ARG_SHARED)
+ set(build_static ${FLANG_RT_ENABLE_STATIC})
+ set(build_shared ${FLANG_RT_ENABLE_SHARED})
+ else ()
+ set(build_static ${ARG_STATIC})
+ set(build_shared ${ARG_SHARED})
endif ()
- if (ARG_STATIC)
- list(APPEND extra_args STATIC)
+ if (NOT ARG_STATIC AND NOT ARG_SHARED AND NOT ARG_OBJECT)
+ if (BUILD_SHARED_LIBS)
+ set(build_shared ON)
+ else ()
+ set(build_static ON)
+ endif ()
endif ()
+
+ # Build an object library if building multiple libraries at once or if
+ # explicitly requested.
+ set(build_object OFF)
if (ARG_OBJECT)
- list(APPEND extra_args OBJECT)
+ set(build_object ON)
+ elseif (build_static AND build_shared)
+ set(build_object ON)
+ endif ()
+
+ # srctargets: targets that contain source files
+ # libtargets: static/shared if they are built
+ # alltargets: any add_library target added by this function
+ set(srctargets "")
+ set(libtargets "")
+ set(alltargets "")
+ if (build_static)
+ list(APPEND srctargets "${name_static}")
+ list(APPEND libtargets "${name_static}")
+ list(APPEND alltargets "${name_static}")
endif ()
+ if (build_shared)
+ list(APPEND srctargets "${name_shared}")
+ list(APPEND libtargets "${name_shared}")
+ list(APPEND alltargets "${name_shared}")
+ endif ()
+ if (build_object)
+ set(srctargets "${name_object}")
+ list(APPEND alltargets "${name_object}")
+ endif ()
+
+ set(extra_args "")
if (ARG_EXCLUDE_FROM_ALL)
list(APPEND extra_args EXCLUDE_FROM_ALL)
endif ()
@@ -62,113 +119,145 @@ function (add_flangrt_library name)
# Also add header files to IDEs to list as part of the library.
set_source_files_properties(${ARG_ADDITIONAL_HEADERS} PROPERTIES HEADER_FILE_ONLY ON)
- add_library(${name} ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})
+ # Create selected library types.
+ if (build_object)
+ add_library("${name_object}" OBJECT ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})
+ set_target_properties(${name_object} PROPERTIES
+ POSITION_INDEPENDENT_CODE ON
+ FOLDER "Flang-RT/Object Libraries"
+ )
- if (ARG_INSTALL_WITH_TOOLCHAIN)
- set_target_properties(${name} PROPERTIES FOLDER "Flang-RT/Toolchain Libraries")
- elseif (ARG_OBJECT)
- set_target_properties(${name} PROPERTIES FOLDER "Flang-RT/Object Libraries")
- else ()
- set_target_properties(${name} PROPERTIES FOLDER "Flang-RT/Libraries")
+ # Replace arguments for the libraries we are going to create.
+ set(ARG_ADDITIONAL_HEADERS "")
+ set(ARG_UNPARSED_ARGUMENTS "$<TARGET_OBJECTS:${name_object}>")
+ endif ()
+ if (build_static)
+ add_library("${name_static}" STATIC ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})
+ endif ()
+ if (build_shared)
+ add_library("${name_shared}" SHARED ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})
endif ()
- # Minimum required C++ version for Flang-RT, even if CMAKE_CXX_STANDARD is defined to something else.
- target_compile_features(${name} PRIVATE cxx_std_17)
+ foreach (tgtname IN LISTS libtargets)
+ if (NOT WIN32)
+ # Use same stem name for .a and .so. Common in UNIX environments.
+ # Not possible in Windows environments.
+ set_target_properties(${tgtname} PROPERTIES OUTPUT_NAME "${name}")
+ endif ()
- # Use compiler-specific options to disable exceptions and RTTI.
- if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
- target_compile_options(${name} PRIVATE
- $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
- )
- elseif (MSVC)
- target_compile_options(${name} PRIVATE
- $<$<COMPILE_LANGUAGE:CXX>:/EHs-c- /GR->
- )
- elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
- target_compile_options(${name} PRIVATE
- $<$<COMPILE_LANGUAGE:CXX>:-qnoeh -qnortti>
- )
- endif ()
+ if (ARG_INSTALL_WITH_TOOLCHAIN)
+ set_target_properties(${tgtname} PROPERTIES FOLDER "Flang-RT/Toolchain Libraries")
+ else ()
+ set_target_properties(${tgtname} PROPERTIES FOLDER "Flang-RT/Libraries")
+ endif ()
+ endforeach ()
- # Also for CUDA source when compiling with FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA
- if (CMAKE_CUDA_COMPILER_ID MATCHES "NVIDIA")
- # Assuming gcc as host compiler.
- target_compile_options(${name} PRIVATE
- $<$<COMPILE_LANGUAGE:CUDA>:--no-exceptions -Xcompiler -fno-rtti -Xcompiler -fno-unwind-tables -Xcompiler -fno-asynchronous-unwind-tables>
- )
- else ()
- # Assuming a clang-compatible CUDA compiler.
- target_compile_options(${name} PRIVATE
- $<$<COMPILE_LANGUAGE:CUDA>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
- )
- endif ()
+ # Define how to compile and link the library.
+ # Some conceptionally only apply to ${srctargets} or ${libtargets}, but we
+ # apply them to ${alltargets}. In worst case, they are ignored by CMake.
+ foreach (tgtname IN LISTS alltargets)
+ # Minimum required C++ version for Flang-RT, even if CMAKE_CXX_STANDARD is defined to something else.
+ target_compile_features(${tgtname} PRIVATE cxx_std_17)
+
+ # Use compiler-specific options to disable exceptions and RTTI.
+ if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
+ target_compile_options(${tgtname} PRIVATE
+ $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
+ )
+ elseif (MSVC)
+ target_compile_options(${tgtname} PRIVATE
+ $<$<COMPILE_LANGUAGE:CXX>:/EHs-c- /GR->
+ )
+ elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
+ target_compile_options(${tgtname} PRIVATE
+ $<$<COMPILE_LANGUAGE:CXX>:-qnoeh -qnortti>
+ )
+ endif ()
- # Flang-RT's public headers
- target_include_directories(${name} PRIVATE "${FLANG_RT_SOURCE_DIR}/include")
+ # Also for CUDA source when compiling with FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA
+ if (CMAKE_CUDA_COMPILER_ID MATCHES "NVIDIA")
+ # Assuming gcc as host compiler.
+ target_compile_options(${tgtname} PRIVATE
+ $<$<COMPILE_LANGUAGE:CUDA>:--no-exceptions -Xcompiler -fno-rtti -Xcompiler -fno-unwind-tables -Xcompiler -fno-asynchronous-unwind-tables>
+ )
+ else ()
+ # Assuming a clang-compatible CUDA compiler.
+ target_compile_options(${tgtname} PRIVATE
+ $<$<COMPILE_LANGUAGE:CUDA>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
+ )
+ endif ()
- # For ISO_Fortran_binding.h to be found by the runtime itself (Accessed as #include "flang/ISO_Fortran_binding.h")
- # User applications can use #include <ISO_Fortran_binding.h>
- target_include_directories(${name} PRIVATE "${FLANG_SOURCE_DIR}/include")
+ # Flang-RT's public headers
+ target_include_directories(${tgtname} PRIVATE "${FLANG_RT_SOURCE_DIR}/include")
- # For Flang-RT's configured config.h to be found
- target_include_directories(${name} PRIVATE "${FLANG_RT_BINARY_DIR}")
+ # For ISO_Fortran_binding.h to be found by the runtime itself (Accessed as #include "flang/ISO_Fortran_binding.h")
+ # User applications can use #include <ISO_Fortran_binding.h>
+ target_include_directories(${tgtname} PRIVATE "${FLANG_SOURCE_DIR}/include")
- # Disable libstdc++/libc++ assertions, even in an LLVM_ENABLE_ASSERTIONS
- # build, to avoid an unwanted dependency on libstdc++/libc++.so.
- if (FLANG_RT_SUPPORTS_UNDEFINE_FLAG)
- target_compile_options(${name} PUBLIC -U_GLIBCXX_ASSERTIONS)
- target_compile_options(${name} PUBLIC -U_LIBCPP_ENABLE_ASSERTIONS)
- endif ()
+ # For Flang-RT's configured config.h to be found
+ target_include_directories(${tgtname} PRIVATE "${FLANG_RT_BINARY_DIR}")
- # Flang/Clang (including clang-cl) -compiled programs targeting the MSVC ABI
- # should only depend on msvcrt/ucrt. LLVM still emits libgcc/compiler-rt
- # functions in some cases like 128-bit integer math (__udivti3, __modti3,
- # __fixsfti, __floattidf, ...) that msvc does not support. We are injecting a
- # dependency to Compiler-RT's builtin library where these are implemented.
- if (MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- if (FLANG_RT_BUILTINS_LIBRARY)
- target_compile_options(${name} PRIVATE "$<$<COMPILE_LANGUAGE:CXX,C>:-Xclang>" "$<$<COMPILE_LANGUAGE:CXX,C>:--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}>")
+ # Disable libstdc++/libc++ assertions, even in an LLVM_ENABLE_ASSERTIONS
+ # build, to avoid an unwanted dependency on libstdc++/libc++.so.
+ if (FLANG_RT_SUPPORTS_UNDEFINE_FLAG)
+ target_compile_options(${tgtname} PUBLIC -U_GLIBCXX_ASSERTIONS)
+ target_compile_options(${tgtname} PUBLIC -U_LIBCPP_ENABLE_ASSERTIONS)
endif ()
- endif ()
- if (MSVC AND CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
- if (FLANG_RT_BUILTINS_LIBRARY)
- target_compile_options(${name} PRIVATE "$<$<COMPILE_LANGUAGE:Fortran>:-Xflang>" "$<$<COMPILE_LANGUAGE:Fortran>:--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}>")
- else ()
- message(WARNING "Did not find libclang_rt.builtins.lib.
- LLVM may emit builtins that are not implemented in msvcrt/ucrt and
- instead falls back to builtins from Compiler-RT. Linking with ${name}
- may result in a linker error.")
+
+ # Flang/Clang (including clang-cl) -compiled programs targeting the MSVC ABI
+ # should only depend on msvcrt/ucrt. LLVM still emits libgcc/compiler-rt
+ # functions in some cases like 128-bit integer math (__udivti3, __modti3,
+ # __fixsfti, __floattidf, ...) that msvc does not support. We are injecting a
+ # dependency to Compiler-RT's builtin library where these are implemented.
+ if (MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ if (FLANG_RT_BUILTINS_LIBRARY)
+ target_compile_options(${tgtname} PRIVATE "$<$<COMPILE_LANGUAGE:CXX,C>:-Xclang>" "$<$<COMPILE_LANGUAGE:CXX,C>:--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}>")
+ endif ()
+ endif ()
+ if (MSVC AND CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
+ if (FLANG_RT_BUILTINS_LIBRARY)
+ target_compile_options(${tgtname} PRIVATE "$<$<COMPILE_LANGUAGE:Fortran>:-Xflang>" "$<$<COMPILE_LANGUAGE:Fortran>:--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}>")
+ else ()
+ message(WARNING "Did not find libclang_rt.builtins.lib.
+ LLVM may emit builtins that are not implemented in msvcrt/ucrt and
+ instead falls back to builtins from Compiler-RT. Linking with ${tgtname}
+ may result in a linker error.")
+ endif ()
endif ()
- endif ()
- # Non-GTest unittests depend on LLVMSupport
- if (ARG_LINK_TO_LLVM)
- if (LLVM_LINK_LLVM_DYLIB)
- set(llvm_libs LLVM)
- else()
- llvm_map_components_to_libnames(llvm_libs Support)
- endif()
- target_link_libraries(${name} PUBLIC ${llvm_libs})
- target_include_directories(${name} PUBLIC ${LLVM_INCLUDE_DIRS})
- endif ()
+ # Non-GTest unittests depend on LLVMSupport
+ if (ARG_LINK_TO_LLVM)
+ if (LLVM_LINK_LLVM_DYLIB)
+ set(llvm_libs LLVM)
+ else()
+ llvm_map_components_to_libnames(llvm_libs Support)
+ endif()
+ target_link_libraries(${tgtname} PUBLIC ${llvm_libs})
+ target_include_directories(${tgtname} PUBLIC ${LLVM_INCLUDE_DIRS})
+ endif ()
+ endforeach ()
- # If this is part of the toolchain, put it into the compiler's resource
- # directory. Otherwise it is part of testing and is not installed at all.
- # TODO: Consider multi-configuration builds (MSVC_IDE, "Ninja Multi-Config")
- if (ARG_INSTALL_WITH_TOOLCHAIN)
- set_target_properties(${name}
- PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY "${FLANG_RT_OUTPUT_RESOURCE_LIB_DIR}"
- )
+ foreach (tgtname IN LISTS libtargets)
+ # If this is part of the toolchain, put it into the compiler's resource
+ # directory. Otherwise it is part of testing and is not installed at all.
+ # TODO: Consider multi-configuration builds (MSVC_IDE, "Ninja Multi-Config")
+ if (ARG_INSTALL_WITH_TOOLCHAIN)
+ set_target_properties(${tgtname}
+ PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY "${FLANG_RT_OUTPUT_RESOURCE_LIB_DIR}"
+ LIBRARY_OUTPUT_DIRECTORY "${FLANG_RT_OUTPUT_RESOURCE_LIB_DIR}"
+ )
- install(TARGETS ${name}
- ARCHIVE DESTINATION "${FLANG_RT_INSTALL_RESOURCE_LIB_PATH}"
- )
- endif ()
+ install(TARGETS ${tgtname}
+ ARCHIVE DESTINATION "${FLANG_RT_INSTALL_RESOURCE_LIB_PATH}"
+ LIBRARY DESTINATION "${FLANG_RT_INSTALL_RESOURCE_LIB_PATH}"
+ )
+ endif ()
- # flang-rt should build all the Flang-RT targets that are built in an
- # 'all' build.
- if (NOT ARG_EXCLUDE_FROM_ALL)
- add_dependencies(flang-rt ${name})
- endif ()
+ # flang-rt should build all the Flang-RT targets that are built in an
+ # 'all' build.
+ if (NOT ARG_EXCLUDE_FROM_ALL)
+ add_dependencies(flang-rt ${tgtname})
+ endif ()
+ endforeach ()
endfunction (add_flangrt_library)
diff --git a/flang-rt/cmake/modules/AddFlangRTOffload.cmake b/flang-rt/cmake/modules/AddFlangRTOffload.cmake
index 84eabba05b49b9..94b7309a955f32 100644
--- a/flang-rt/cmake/modules/AddFlangRTOffload.cmake
+++ b/flang-rt/cmake/modules/AddFlangRTOffload.cmake
@@ -8,9 +8,9 @@
macro(enable_cuda_compilation name files)
if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA")
- if (BUILD_SHARED_LIBS)
+ if (FLANG_RT_ENABLE_SHARED)
message(FATAL_ERROR
- "BUILD_SHARED_LIBS is not supported for CUDA build of Fortran runtime"
+ "FLANG_RT_ENABLE_SHARED is not supported for CUDA build of Flang-RT"
)
endif()
@@ -70,9 +70,9 @@ macro(enable_omp_offload_compilation name files)
if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "OpenMP")
# OpenMP offload build only works with Clang compiler currently.
- if (BUILD_SHARED_LIBS)
+ if (FLANG_RT_ENABLE_SHARED)
message(FATAL_ERROR
- "BUILD_SHARED_LIBS is not supported for OpenMP offload build of Fortran runtime"
+ "FLANG_RT_ENABLE_SHARED is not supported for OpenMP offload build of Flang-RT"
)
endif()
diff --git a/flang-rt/cmake/modules/GetToolchainDirs.cmake b/flang-rt/cmake/modules/GetToolchainDirs.cmake
index fc1a406f99ab29..1f251790f22a01 100644
--- a/flang-rt/cmake/modules/GetToolchainDirs.cmake
+++ b/flang-rt/cmake/modules/GetToolchainDirs.cmake
@@ -1,127 +1,127 @@
-#===-- cmake/modules/GetToolchainDirs.cmake --------------------------------===#
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-#
-#===------------------------------------------------------------------------===#
-
-include(GNUInstallDirs)
-
-
-# Determine the subdirectory relative to Clang's resource dir/sysroot where to
-# install target-specific libraries, to be found by Clang/Flang driver. This was
-# adapted from Compiler-RT's mechanism to find the path for
-# libclang_rt.builtins.a.
-#
-# Compiler-RT has two mechanisms for the path (simplified):
-#
-# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=1: lib/${oslibname}/libclang_rt.builtins-${arch}.a
-# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=0: lib/${triple}/libclang_rt.builtins.a
-#
-# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON is the newer scheme, but the old one is
-# currently still used for some platforms such as Windows. Clang looks for which
-# of the files exist before passing the path to the linker. Hence, the
-# directories have to match what Clang is looking for, which is done in
-# ToolChain::getArchSpecificLibPaths(..), ToolChain::getRuntimePath(),
-# ToolChain::getCompilerRTPath(), and ToolChain::getCompilerRT(..), not entirely
-# consistent between these functions, Compiler-RT's CMake code, and overrides
-# in different toolchains.
-#
-# For Fortran, Flang always assumes the library name libflang_rt.a without
-# architecture suffix. Hence, we always use the second scheme even as if
-# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON, even if it actually set to OFF. It as
-# added unconditionally to the library search path by
-# ToolChain::getArchSpecificLibPaths(...).
-function (get_toolchain_library_subdir outvar)
- if (NOT APPLE)
- set(outval "${CMAKE_INSTALL_LIBDIR}")
- else ()
- # Required to be "darwin" for MachO toolchain.
- get_toolchain_os_dirname(os_dirname)
- set(outval "${CMAKE_INSTALL_LIBDIR}/${os_dirname}")
- endif ()
-
- get_toolchain_arch_dirname(arch_dirname)
- set(outval "${CMAKE_INSTALL_LIBDIR}/${arch_dirname}")
-
- set(${outvar} "${outval}" PARENT_SCOPE)
-endfunction ()
-
-
-# Corresponds to Clang's ToolChain::getOSLibName(). Adapted from Compiler-RT.
-function (get_toolchain_os_dirname outvar)
- if (ANDROID)
- # The CMAKE_SYSTEM_NAME for Android is "Android", but the OS is Linux and the
- # driver will search for libraries in the "linux" directory.
- set(outval "linux")
- else ()
- string(TOLOWER "${CMAKE_SYSTEM_NAME}" outval)
- endif ()
- set(${outvar} "${outval}" PARENT_SCOPE)
-endfunction ()
-
-
-# Corresponds to Clang's ToolChain::getRuntimePath(). Adapted from Compiler-RT.
-function (get_toolchain_arch_dirname outvar)
- string(REPLACE "-" ";" triple_list ${LLVM_TARGET_TRIPLE})
- list(GET triple_list 0 arch)
-
- if("${arch}" MATCHES "^i.86$")
- # Android uses i686, but that's remapped at a later stage.
- set(arch "i386")
- endif()
-
- string(FIND ${LLVM_TARGET_TRIPLE} "-" dash_index)
- string(SUBSTRING ${LLVM_TARGET_TRIPLE} ${dash_index} -1 triple_suffix)
- string(SUBSTRING ${LLVM_TARGET_TRIPLE} 0 ${dash_index} triple_cpu)
- set(arch "${triple_cpu}")
- if("${arch}" MATCHES "^i.86$")
- # Android uses i686, but that's remapped at a later stage.
- set(arch "i386")
- endif()
-
- if(ANDROID AND ${arch} STREQUAL "i386")
- set(target "i686${triple_suffix}")
- elseif(${arch} STREQUAL "amd64")
- set(target "x86_64${triple_suffix}")
- elseif(${arch} STREQUAL "sparc64")
- set(target "sparcv9${triple_suffix}")
- elseif("${arch}" MATCHES "mips64|mips64el")
- string(REGEX REPLACE "-gnu.*" "-gnuabi64" triple_suffix_gnu "${triple_suffix}")
- string(REGEX REPLACE "mipsisa32" "mipsisa64" triple_cpu_mips "${triple_cpu}")
- string(REGEX REPLACE "^mips$" "mips64" triple_cpu_mips "${triple_cpu_mips}")
- string(REGEX REPLACE "^mipsel$" "mips64el" triple_cpu_mips "${triple_cpu_mips}")
- set(target "${triple_cpu_mips}${triple_suffix_gnu}")
- elseif("${arch}" MATCHES "mips|mipsel")
- string(REGEX REPLACE "-gnuabi.*" "-gnu" triple_suffix_gnu "${triple_suffix}")
- string(REGEX REPLACE "mipsisa64" "mipsisa32" triple_cpu_mips "${triple_cpu}")
- string(REGEX REPLACE "mips64" "mips" triple_cpu_mips "${triple_cpu_mips}")
- set(target "${triple_cpu_mips}${triple_suffix_gnu}")
- elseif("${arch}" MATCHES "^arm")
- # FIXME: Handle arch other than arm, armhf, armv6m
- if (${arch} STREQUAL "armhf")
- # If we are building for hard float but our ABI is soft float.
- if ("${triple_suffix}" MATCHES ".*eabi$")
- # Change "eabi" -> "eabihf"
- set(triple_suffix "${triple_suffix}hf")
- endif()
- # ABI is already set in the triple, don't repeat it in the architecture.
- set(arch "arm")
- else ()
- # If we are building for soft float, but the triple's ABI is hard float.
- if ("${triple_suffix}" MATCHES ".*eabihf$")
- # Change "eabihf" -> "eabi"
- string(REGEX REPLACE "hf$" "" triple_suffix "${triple_suffix}")
- endif()
- endif()
- set(target "${arch}${triple_suffix}")
- elseif("${arch}" MATCHES "^amdgcn")
- set(target "amdgcn-amd-amdhsa")
- elseif("${arch}" MATCHES "^nvptx")
- set(target "nvptx64-nvidia-cuda")
- else()
- set(target "${arch}${triple_suffix}")
- endif()
- set(${outvar} "${target}" PARENT_SCOPE)
-endfunction()
+#===-- cmake/modules/GetToolchainDirs.cmake --------------------------------===#
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+#===------------------------------------------------------------------------===#
+
+include(GNUInstallDirs)
+
+
+# Determine the subdirectory relative to Clang's resource dir/sysroot where to
+# install target-specific libraries, to be found by Clang/Flang driver. This was
+# adapted from Compiler-RT's mechanism to find the path for
+# libclang_rt.builtins.a.
+#
+# Compiler-RT has two mechanisms for the path (simplified):
+#
+# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=1: lib/${oslibname}/libclang_rt.builtins-${arch}.a
+# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=0: lib/${triple}/libclang_rt.builtins.a
+#
+# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON is the newer scheme, but the old one is
+# currently still used for some platforms such as Windows. Clang looks for which
+# of the files exist before passing the path to the linker. Hence, the
+# directories have to match what Clang is looking for, which is done in
+# ToolChain::getArchSpecificLibPaths(..), ToolChain::getRuntimePath(),
+# ToolChain::getCompilerRTPath(), and ToolChain::getCompilerRT(..), not entirely
+# consistent between these functions, Compiler-RT's CMake code, and overrides
+# in different toolchains.
+#
+# For Fortran, Flang always assumes the library name libflang_rt.a without
+# architecture suffix. Hence, we always use the second scheme even as if
+# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON, even if it actually set to OFF. It as
+# added unconditionally to the library search path by
+# ToolChain::getArchSpecificLibPaths(...).
+function (get_toolchain_library_subdir outvar)
+ if (NOT APPLE)
+ set(outval "${CMAKE_INSTALL_LIBDIR}")
+ else ()
+ # Required to be "darwin" for MachO toolchain.
+ get_toolchain_os_dirname(os_dirname)
+ set(outval "${CMAKE_INSTALL_LIBDIR}/${os_dirname}")
+ endif ()
+
+ get_toolchain_arch_dirname(arch_dirname)
+ set(outval "${CMAKE_INSTALL_LIBDIR}/${arch_dirname}")
+
+ set(${outvar} "${outval}" PARENT_SCOPE)
+endfunction ()
+
+
+# Corresponds to Clang's ToolChain::getOSLibName(). Adapted from Compiler-RT.
+function (get_toolchain_os_dirname outvar)
+ if (ANDROID)
+ # The CMAKE_SYSTEM_NAME for Android is "Android", but the OS is Linux and the
+ # driver will search for libraries in the "linux" directory.
+ set(outval "linux")
+ else ()
+ string(TOLOWER "${CMAKE_SYSTEM_NAME}" outval)
+ endif ()
+ set(${outvar} "${outval}" PARENT_SCOPE)
+endfunction ()
+
+
+# Corresponds to Clang's ToolChain::getRuntimePath(). Adapted from Compiler-RT.
+function (get_toolchain_arch_dirname outvar)
+ string(REPLACE "-" ";" triple_list ${LLVM_TARGET_TRIPLE})
+ list(GET triple_list 0 arch)
+
+ if("${arch}" MATCHES "^i.86$")
+ # Android uses i686, but that's remapped at a later stage.
+ set(arch "i386")
+ endif()
+
+ string(FIND ${LLVM_TARGET_TRIPLE} "-" dash_index)
+ string(SUBSTRING ${LLVM_TARGET_TRIPLE} ${dash_index} -1 triple_suffix)
+ string(SUBSTRING ${LLVM_TARGET_TRIPLE} 0 ${dash_index} triple_cpu)
+ set(arch "${triple_cpu}")
+ if("${arch}" MATCHES "^i.86$")
+ # Android uses i686, but that's remapped at a later stage.
+ set(arch "i386")
+ endif()
+
+ if(ANDROID AND ${arch} STREQUAL "i386")
+ set(target "i686${triple_suffix}")
+ elseif(${arch} STREQUAL "amd64")
+ set(target "x86_64${triple_suffix}")
+ elseif(${arch} STREQUAL "sparc64")
+ set(target "sparcv9${triple_suffix}")
+ elseif("${arch}" MATCHES "mips64|mips64el")
+ string(REGEX REPLACE "-gnu.*" "-gnuabi64" triple_suffix_gnu "${triple_suffix}")
+ string(REGEX REPLACE "mipsisa32" "mipsisa64" triple_cpu_mips "${triple_cpu}")
+ string(REGEX REPLACE "^mips$" "mips64" triple_cpu_mips "${triple_cpu_mips}")
+ string(REGEX REPLACE "^mipsel$" "mips64el" triple_cpu_mips "${triple_cpu_mips}")
+ set(target "${triple_cpu_mips}${triple_suffix_gnu}")
+ elseif("${arch}" MATCHES "mips|mipsel")
+ string(REGEX REPLACE "-gnuabi.*" "-gnu" triple_suffix_gnu "${triple_suffix}")
+ string(REGEX REPLACE "mipsisa64" "mipsisa32" triple_cpu_mips "${triple_cpu}")
+ string(REGEX REPLACE "mips64" "mips" triple_cpu_mips "${triple_cpu_mips}")
+ set(target "${triple_cpu_mips}${triple_suffix_gnu}")
+ elseif("${arch}" MATCHES "^arm")
+ # FIXME: Handle arch other than arm, armhf, armv6m
+ if (${arch} STREQUAL "armhf")
+ # If we are building for hard float but our ABI is soft float.
+ if ("${triple_suffix}" MATCHES ".*eabi$")
+ # Change "eabi" -> "eabihf"
+ set(triple_suffix "${triple_suffix}hf")
+ endif()
+ # ABI is already set in the triple, don't repeat it in the architecture.
+ set(arch "arm")
+ else ()
+ # If we are building for soft float, but the triple's ABI is hard float.
+ if ("${triple_suffix}" MATCHES ".*eabihf$")
+ # Change "eabihf" -> "eabi"
+ string(REGEX REPLACE "hf$" "" triple_suffix "${triple_suffix}")
+ endif()
+ endif()
+ set(target "${arch}${triple_suffix}")
+ elseif("${arch}" MATCHES "^amdgcn")
+ set(target "amdgcn-amd-amdhsa")
+ elseif("${arch}" MATCHES "^nvptx")
+ set(target "nvptx64-nvidia-cuda")
+ else()
+ set(target "${arch}${triple_suffix}")
+ endif()
+ set(${outvar} "${target}" PARENT_SCOPE)
+endfunction()
diff --git a/flang-rt/lib/flang_rt/CMakeLists.txt b/flang-rt/lib/flang_rt/CMakeLists.txt
index ff45e26961a42c..c0dfc7e976f28b 100644
--- a/flang-rt/lib/flang_rt/CMakeLists.txt
+++ b/flang-rt/lib/flang_rt/CMakeLists.txt
@@ -128,19 +128,25 @@ endif ()
set(sources ${supported_sources} ${host_sources} ${f128_sources})
if (NOT WIN32)
- add_flangrt_library(flang_rt STATIC
+ add_flangrt_library(flang_rt STATIC SHARED
${sources}
INSTALL_WITH_TOOLCHAIN
ADDITIONAL_HEADERS ${public_headers} ${private_headers}
)
- enable_cuda_compilation(flang_rt "${supported_sources}")
- enable_omp_offload_compilation(flang_rt "${supported_sources}")
+ enable_cuda_compilation(flang_rt.static "${supported_sources}")
+ enable_omp_offload_compilation(flang_rt.static "${supported_sources}")
- # For unittests that depend on flang_rt. Should link to the static version
- # of the library.
- add_library(flang_rt.static ALIAS flang_rt)
- add_library(flang_rt.unittest ALIAS flang_rt)
+ # Select a default runtime, which is used for unittests.
+ if (TARGET flang_rt.shared AND BUILD_SHARED_LIBS)
+ set(default_flang_rt "flang_rt.shared")
+ elseif (TARGET flang_rt.static)
+ set(default_flang_rt "flang_rt.static")
+ else ()
+ set(default_flang_rt "flang_rt.shared")
+ endif ()
+ add_library(flang_rt ALIAS "${default_flang_rt}")
+ add_library(flang_rt.unittest ALIAS "${default_flang_rt}")
else()
# Target for building all versions of the runtime
add_custom_target(flang_rt)
diff --git a/flang-rt/test/CMakeLists.txt b/flang-rt/test/CMakeLists.txt
index 5ca07b66e4f9b5..74f506d6f98f00 100644
--- a/flang-rt/test/CMakeLists.txt
+++ b/flang-rt/test/CMakeLists.txt
@@ -45,7 +45,7 @@ set_target_properties(flang-rt-test-depends PROPERTIES FOLDER "Flang-RT/Meta")
add_dependencies(flang-rt-test-depends
FlangRTUnitTests
flang_rt.unittest
- flang_rt.static
+ flang_rt
)
add_lit_testsuite(check-flang-rt "Running the Flang-RT regression tests"
diff --git a/flang-rt/test/lit.cfg.py b/flang-rt/test/lit.cfg.py
index 8a810f40558664..46274c5c8b1b1e 100644
--- a/flang-rt/test/lit.cfg.py
+++ b/flang-rt/test/lit.cfg.py
@@ -94,7 +94,7 @@ def shjoin(args, sep=" "):
# Include path for C headers that define Flang's Fortran ABI.
config.substitutions.append(("%include", os.path.join(config.flang_source_dir, "include")))
-# Library path of libflang_rt.a (for lib search path when using non-Flang driver for linking)
+# Library path of libflang_rt.a/.so (for lib search path when using non-Flang driver for linking and LD_LIBRARY_PATH)
config.substitutions.append(("%libdir", config.flang_rt_output_resource_lib_dir))
# Additional library depedendencies the that Flang driver does not add itself.
More information about the llvm-branch-commits
mailing list