Skip to content

Commit a3037ab

Browse files
committed
Add FLANG_RT_ENABLE_STATIC and FLANG_RT_ENABLE_SHARED
1 parent 5eaa354 commit a3037ab

File tree

7 files changed

+366
-241
lines changed

7 files changed

+366
-241
lines changed

flang-rt/CMakeLists.txt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,15 @@ cmake_path(NORMAL_PATH FLANG_RT_OUTPUT_RESOURCE_DIR)
113113
cmake_path(NORMAL_PATH FLANG_RT_INSTALL_RESOURCE_PATH)
114114

115115
# Determine subdirectories for build output and install destinations.
116+
# FIXME: For the libflang_rt.so, the toolchain resource lib dir is not a good
117+
# destination because it is not a ld.so default search path.
118+
# The machine where the executable is eventually executed may not be the
119+
# machine where the Flang compiler and its resource dir is installed, so
120+
# setting RPath by the driver is not an solution. It should belong into
121+
# /usr/lib/<triple>/libflang_rt.so, like e.g. libgcc_s.so.
122+
# But the linker as invoked by the Flang driver also requires
123+
# libflang_rt.so to be found when linking and the resource lib dir is
124+
# the only reliable location.
116125
get_toolchain_library_subdir(toolchain_lib_subdir)
117126
extend_path(FLANG_RT_OUTPUT_RESOURCE_LIB_DIR "${FLANG_RT_OUTPUT_RESOURCE_DIR}" "${toolchain_lib_subdir}")
118127
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)
130139
option(FLANG_RT_INCLUDE_TESTS "Generate build targets for the flang-rt unit and regression-tests." "${LLVM_INCLUDE_TESTS}")
131140

132141

142+
option(FLANG_RT_ENABLE_STATIC "Build Flang-RT as a static library." ON)
143+
if (WIN32)
144+
# Windows DLL currently not implemented.
145+
set(FLANG_RT_ENABLE_SHARED OFF)
146+
else ()
147+
# TODO: Enable by default to increase test coverage, and which version of the
148+
# library should be the user's choice anyway.
149+
# Currently, the Flang driver adds `-L"libdir" -lflang_rt` as linker
150+
# argument, which leaves the choice which library to use to the linker.
151+
# Since most linkers prefer the shared library, this would constitute a
152+
# breaking change unless the driver is changed.
153+
option(FLANG_RT_ENABLE_SHARED "Build Flang-RT as a shared library." OFF)
154+
endif ()
155+
if (NOT FLANG_RT_ENABLE_STATIC AND NOT FLANG_RT_ENABLE_SHARED)
156+
message(FATAL_ERROR "
157+
Must build at least one type of library
158+
(FLANG_RT_ENABLE_STATIC=ON, FLANG_RT_ENABLE_SHARED=ON, or both)
159+
")
160+
endif ()
161+
162+
133163
set(FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT "" CACHE STRING "Compile Flang-RT with GPU support (CUDA or OpenMP)")
134164
set_property(CACHE FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT PROPERTY STRINGS
135165
""

flang-rt/cmake/modules/AddFlangRT.cmake

Lines changed: 190 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
# STATIC
1717
# Build a static (.a/.lib) library
1818
# OBJECT
19-
# Create only object files without static/dynamic library
19+
# Always create an object library.
20+
# Without SHARED/STATIC, build only the object library.
2021
# INSTALL_WITH_TOOLCHAIN
2122
# Install library into Clang's resource directory so it can be found by the
2223
# Flang driver during compilation, including tests
@@ -44,131 +45,219 @@ function (add_flangrt_library name)
4445
")
4546
endif ()
4647

47-
# Forward libtype to add_library
48-
set(extra_args "")
49-
if (ARG_SHARED)
50-
list(APPEND extra_args SHARED)
48+
# Internal names of libraries. If called with just single type option, use
49+
# the default name for it. Name of targets must only depend on function
50+
# arguments to be predictable for callers.
51+
set(name_static "${name}.static")
52+
set(name_shared "${name}.shared")
53+
set(name_object "obj.${name}")
54+
if (ARG_STATIC AND NOT ARG_SHARED)
55+
set(name_static "${name}")
56+
elseif (NOT ARG_STATIC AND ARG_SHARED)
57+
set(name_shared "${name}")
58+
elseif (NOT ARG_STATIC AND NOT ARG_SHARED AND ARG_OBJECT)
59+
set(name_object "${name}")
60+
elseif (NOT ARG_STATIC AND NOT ARG_SHARED AND NOT ARG_OBJECT)
61+
# Only one of them will actually be built.
62+
set(name_static "${name}")
63+
set(name_shared "${name}")
64+
endif ()
65+
66+
# Determine what to build. If not explicitly specified, honor
67+
# BUILD_SHARED_LIBS (e.g. for unittest libraries). If can build static and
68+
# shared, use ENABLE_STATIC/ENABLE_SHARED setting.
69+
if (ARG_STATIC AND ARG_SHARED)
70+
set(build_static ${FLANG_RT_ENABLE_STATIC})
71+
set(build_shared ${FLANG_RT_ENABLE_SHARED})
72+
else ()
73+
set(build_static ${ARG_STATIC})
74+
set(build_shared ${ARG_SHARED})
5175
endif ()
52-
if (ARG_STATIC)
53-
list(APPEND extra_args STATIC)
76+
if (NOT ARG_STATIC AND NOT ARG_SHARED AND NOT ARG_OBJECT)
77+
if (BUILD_SHARED_LIBS)
78+
set(build_shared ON)
79+
else ()
80+
set(build_static ON)
81+
endif ()
5482
endif ()
83+
84+
# Build an object library if building multiple libraries at once or if
85+
# explicitly requested.
86+
set(build_object OFF)
5587
if (ARG_OBJECT)
56-
list(APPEND extra_args OBJECT)
88+
set(build_object ON)
89+
elseif (build_static AND build_shared)
90+
set(build_object ON)
91+
endif ()
92+
93+
# srctargets: targets that contain source files
94+
# libtargets: static/shared if they are built
95+
# alltargets: any add_library target added by this function
96+
set(srctargets "")
97+
set(libtargets "")
98+
set(alltargets "")
99+
if (build_static)
100+
list(APPEND srctargets "${name_static}")
101+
list(APPEND libtargets "${name_static}")
102+
list(APPEND alltargets "${name_static}")
57103
endif ()
104+
if (build_shared)
105+
list(APPEND srctargets "${name_shared}")
106+
list(APPEND libtargets "${name_shared}")
107+
list(APPEND alltargets "${name_shared}")
108+
endif ()
109+
if (build_object)
110+
set(srctargets "${name_object}")
111+
list(APPEND alltargets "${name_object}")
112+
endif ()
113+
114+
set(extra_args "")
58115
if (ARG_EXCLUDE_FROM_ALL)
59116
list(APPEND extra_args EXCLUDE_FROM_ALL)
60117
endif ()
61118

62119
# Also add header files to IDEs to list as part of the library.
63120
set_source_files_properties(${ARG_ADDITIONAL_HEADERS} PROPERTIES HEADER_FILE_ONLY ON)
64121

65-
add_library(${name} ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})
122+
# Create selected library types.
123+
if (build_object)
124+
add_library("${name_object}" OBJECT ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})
125+
set_target_properties(${name_object} PROPERTIES
126+
POSITION_INDEPENDENT_CODE ON
127+
FOLDER "Flang-RT/Object Libraries"
128+
)
66129

67-
if (ARG_INSTALL_WITH_TOOLCHAIN)
68-
set_target_properties(${name} PROPERTIES FOLDER "Flang-RT/Toolchain Libraries")
69-
elseif (ARG_OBJECT)
70-
set_target_properties(${name} PROPERTIES FOLDER "Flang-RT/Object Libraries")
71-
else ()
72-
set_target_properties(${name} PROPERTIES FOLDER "Flang-RT/Libraries")
130+
# Replace arguments for the libraries we are going to create.
131+
set(ARG_ADDITIONAL_HEADERS "")
132+
set(ARG_UNPARSED_ARGUMENTS "$<TARGET_OBJECTS:${name_object}>")
133+
endif ()
134+
if (build_static)
135+
add_library("${name_static}" STATIC ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})
136+
endif ()
137+
if (build_shared)
138+
add_library("${name_shared}" SHARED ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})
73139
endif ()
74140

75-
# Minimum required C++ version for Flang-RT, even if CMAKE_CXX_STANDARD is defined to something else.
76-
target_compile_features(${name} PRIVATE cxx_std_17)
141+
foreach (tgtname IN LISTS libtargets)
142+
if (NOT WIN32)
143+
# Use same stem name for .a and .so. Common in UNIX environments.
144+
# Not possible in Windows environments.
145+
set_target_properties(${tgtname} PROPERTIES OUTPUT_NAME "${name}")
146+
endif ()
77147

78-
# Use compiler-specific options to disable exceptions and RTTI.
79-
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
80-
target_compile_options(${name} PRIVATE
81-
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
82-
)
83-
elseif (MSVC)
84-
target_compile_options(${name} PRIVATE
85-
$<$<COMPILE_LANGUAGE:CXX>:/EHs-c- /GR->
86-
)
87-
elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
88-
target_compile_options(${name} PRIVATE
89-
$<$<COMPILE_LANGUAGE:CXX>:-qnoeh -qnortti>
90-
)
91-
endif ()
148+
if (ARG_INSTALL_WITH_TOOLCHAIN)
149+
set_target_properties(${tgtname} PROPERTIES FOLDER "Flang-RT/Toolchain Libraries")
150+
else ()
151+
set_target_properties(${tgtname} PROPERTIES FOLDER "Flang-RT/Libraries")
152+
endif ()
153+
endforeach ()
92154

93-
# Also for CUDA source when compiling with FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA
94-
if (CMAKE_CUDA_COMPILER_ID MATCHES "NVIDIA")
95-
# Assuming gcc as host compiler.
96-
target_compile_options(${name} PRIVATE
97-
$<$<COMPILE_LANGUAGE:CUDA>:--no-exceptions -Xcompiler -fno-rtti -Xcompiler -fno-unwind-tables -Xcompiler -fno-asynchronous-unwind-tables>
98-
)
99-
else ()
100-
# Assuming a clang-compatible CUDA compiler.
101-
target_compile_options(${name} PRIVATE
102-
$<$<COMPILE_LANGUAGE:CUDA>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
103-
)
104-
endif ()
155+
# Define how to compile and link the library.
156+
# Some conceptionally only apply to ${srctargets} or ${libtargets}, but we
157+
# apply them to ${alltargets}. In worst case, they are ignored by CMake.
158+
foreach (tgtname IN LISTS alltargets)
159+
# Minimum required C++ version for Flang-RT, even if CMAKE_CXX_STANDARD is defined to something else.
160+
target_compile_features(${tgtname} PRIVATE cxx_std_17)
161+
162+
# Use compiler-specific options to disable exceptions and RTTI.
163+
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
164+
target_compile_options(${tgtname} PRIVATE
165+
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
166+
)
167+
elseif (MSVC)
168+
target_compile_options(${tgtname} PRIVATE
169+
$<$<COMPILE_LANGUAGE:CXX>:/EHs-c- /GR->
170+
)
171+
elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
172+
target_compile_options(${tgtname} PRIVATE
173+
$<$<COMPILE_LANGUAGE:CXX>:-qnoeh -qnortti>
174+
)
175+
endif ()
105176

106-
# Flang-RT's public headers
107-
target_include_directories(${name} PRIVATE "${FLANG_RT_SOURCE_DIR}/include")
177+
# Also for CUDA source when compiling with FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA
178+
if (CMAKE_CUDA_COMPILER_ID MATCHES "NVIDIA")
179+
# Assuming gcc as host compiler.
180+
target_compile_options(${tgtname} PRIVATE
181+
$<$<COMPILE_LANGUAGE:CUDA>:--no-exceptions -Xcompiler -fno-rtti -Xcompiler -fno-unwind-tables -Xcompiler -fno-asynchronous-unwind-tables>
182+
)
183+
else ()
184+
# Assuming a clang-compatible CUDA compiler.
185+
target_compile_options(${tgtname} PRIVATE
186+
$<$<COMPILE_LANGUAGE:CUDA>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
187+
)
188+
endif ()
108189

109-
# For ISO_Fortran_binding.h to be found by the runtime itself (Accessed as #include "flang/ISO_Fortran_binding.h")
110-
# User applications can use #include <ISO_Fortran_binding.h>
111-
target_include_directories(${name} PRIVATE "${FLANG_SOURCE_DIR}/include")
190+
# Flang-RT's public headers
191+
target_include_directories(${tgtname} PRIVATE "${FLANG_RT_SOURCE_DIR}/include")
112192

113-
# For Flang-RT's configured config.h to be found
114-
target_include_directories(${name} PRIVATE "${FLANG_RT_BINARY_DIR}")
193+
# For ISO_Fortran_binding.h to be found by the runtime itself (Accessed as #include "flang/ISO_Fortran_binding.h")
194+
# User applications can use #include <ISO_Fortran_binding.h>
195+
target_include_directories(${tgtname} PRIVATE "${FLANG_SOURCE_DIR}/include")
115196

116-
# Disable libstdc++/libc++ assertions, even in an LLVM_ENABLE_ASSERTIONS
117-
# build, to avoid an unwanted dependency on libstdc++/libc++.so.
118-
if (FLANG_RT_SUPPORTS_UNDEFINE_FLAG)
119-
target_compile_options(${name} PUBLIC -U_GLIBCXX_ASSERTIONS)
120-
target_compile_options(${name} PUBLIC -U_LIBCPP_ENABLE_ASSERTIONS)
121-
endif ()
197+
# For Flang-RT's configured config.h to be found
198+
target_include_directories(${tgtname} PRIVATE "${FLANG_RT_BINARY_DIR}")
122199

123-
# Flang/Clang (including clang-cl) -compiled programs targeting the MSVC ABI
124-
# should only depend on msvcrt/ucrt. LLVM still emits libgcc/compiler-rt
125-
# functions in some cases like 128-bit integer math (__udivti3, __modti3,
126-
# __fixsfti, __floattidf, ...) that msvc does not support. We are injecting a
127-
# dependency to Compiler-RT's builtin library where these are implemented.
128-
if (MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
129-
if (FLANG_RT_BUILTINS_LIBRARY)
130-
target_compile_options(${name} PRIVATE "$<$<COMPILE_LANGUAGE:CXX,C>:-Xclang>" "$<$<COMPILE_LANGUAGE:CXX,C>:--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}>")
200+
# Disable libstdc++/libc++ assertions, even in an LLVM_ENABLE_ASSERTIONS
201+
# build, to avoid an unwanted dependency on libstdc++/libc++.so.
202+
if (FLANG_RT_SUPPORTS_UNDEFINE_FLAG)
203+
target_compile_options(${tgtname} PUBLIC -U_GLIBCXX_ASSERTIONS)
204+
target_compile_options(${tgtname} PUBLIC -U_LIBCPP_ENABLE_ASSERTIONS)
131205
endif ()
132-
endif ()
133-
if (MSVC AND CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
134-
if (FLANG_RT_BUILTINS_LIBRARY)
135-
target_compile_options(${name} PRIVATE "$<$<COMPILE_LANGUAGE:Fortran>:-Xflang>" "$<$<COMPILE_LANGUAGE:Fortran>:--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}>")
136-
else ()
137-
message(WARNING "Did not find libclang_rt.builtins.lib.
138-
LLVM may emit builtins that are not implemented in msvcrt/ucrt and
139-
instead falls back to builtins from Compiler-RT. Linking with ${name}
140-
may result in a linker error.")
206+
207+
# Flang/Clang (including clang-cl) -compiled programs targeting the MSVC ABI
208+
# should only depend on msvcrt/ucrt. LLVM still emits libgcc/compiler-rt
209+
# functions in some cases like 128-bit integer math (__udivti3, __modti3,
210+
# __fixsfti, __floattidf, ...) that msvc does not support. We are injecting a
211+
# dependency to Compiler-RT's builtin library where these are implemented.
212+
if (MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
213+
if (FLANG_RT_BUILTINS_LIBRARY)
214+
target_compile_options(${tgtname} PRIVATE "$<$<COMPILE_LANGUAGE:CXX,C>:-Xclang>" "$<$<COMPILE_LANGUAGE:CXX,C>:--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}>")
215+
endif ()
216+
endif ()
217+
if (MSVC AND CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
218+
if (FLANG_RT_BUILTINS_LIBRARY)
219+
target_compile_options(${tgtname} PRIVATE "$<$<COMPILE_LANGUAGE:Fortran>:-Xflang>" "$<$<COMPILE_LANGUAGE:Fortran>:--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}>")
220+
else ()
221+
message(WARNING "Did not find libclang_rt.builtins.lib.
222+
LLVM may emit builtins that are not implemented in msvcrt/ucrt and
223+
instead falls back to builtins from Compiler-RT. Linking with ${tgtname}
224+
may result in a linker error.")
225+
endif ()
141226
endif ()
142-
endif ()
143227

144-
# Non-GTest unittests depend on LLVMSupport
145-
if (ARG_LINK_TO_LLVM)
146-
if (LLVM_LINK_LLVM_DYLIB)
147-
set(llvm_libs LLVM)
148-
else()
149-
llvm_map_components_to_libnames(llvm_libs Support)
150-
endif()
151-
target_link_libraries(${name} PUBLIC ${llvm_libs})
152-
target_include_directories(${name} PUBLIC ${LLVM_INCLUDE_DIRS})
153-
endif ()
228+
# Non-GTest unittests depend on LLVMSupport
229+
if (ARG_LINK_TO_LLVM)
230+
if (LLVM_LINK_LLVM_DYLIB)
231+
set(llvm_libs LLVM)
232+
else()
233+
llvm_map_components_to_libnames(llvm_libs Support)
234+
endif()
235+
target_link_libraries(${tgtname} PUBLIC ${llvm_libs})
236+
target_include_directories(${tgtname} PUBLIC ${LLVM_INCLUDE_DIRS})
237+
endif ()
238+
endforeach ()
154239

155-
# If this is part of the toolchain, put it into the compiler's resource
156-
# directory. Otherwise it is part of testing and is not installed at all.
157-
# TODO: Consider multi-configuration builds (MSVC_IDE, "Ninja Multi-Config")
158-
if (ARG_INSTALL_WITH_TOOLCHAIN)
159-
set_target_properties(${name}
160-
PROPERTIES
161-
ARCHIVE_OUTPUT_DIRECTORY "${FLANG_RT_OUTPUT_RESOURCE_LIB_DIR}"
162-
)
240+
foreach (tgtname IN LISTS libtargets)
241+
# If this is part of the toolchain, put it into the compiler's resource
242+
# directory. Otherwise it is part of testing and is not installed at all.
243+
# TODO: Consider multi-configuration builds (MSVC_IDE, "Ninja Multi-Config")
244+
if (ARG_INSTALL_WITH_TOOLCHAIN)
245+
set_target_properties(${tgtname}
246+
PROPERTIES
247+
ARCHIVE_OUTPUT_DIRECTORY "${FLANG_RT_OUTPUT_RESOURCE_LIB_DIR}"
248+
LIBRARY_OUTPUT_DIRECTORY "${FLANG_RT_OUTPUT_RESOURCE_LIB_DIR}"
249+
)
163250

164-
install(TARGETS ${name}
165-
ARCHIVE DESTINATION "${FLANG_RT_INSTALL_RESOURCE_LIB_PATH}"
166-
)
167-
endif ()
251+
install(TARGETS ${tgtname}
252+
ARCHIVE DESTINATION "${FLANG_RT_INSTALL_RESOURCE_LIB_PATH}"
253+
LIBRARY DESTINATION "${FLANG_RT_INSTALL_RESOURCE_LIB_PATH}"
254+
)
255+
endif ()
168256

169-
# flang-rt should build all the Flang-RT targets that are built in an
170-
# 'all' build.
171-
if (NOT ARG_EXCLUDE_FROM_ALL)
172-
add_dependencies(flang-rt ${name})
173-
endif ()
257+
# flang-rt should build all the Flang-RT targets that are built in an
258+
# 'all' build.
259+
if (NOT ARG_EXCLUDE_FROM_ALL)
260+
add_dependencies(flang-rt ${tgtname})
261+
endif ()
262+
endforeach ()
174263
endfunction (add_flangrt_library)

flang-rt/cmake/modules/AddFlangRTOffload.cmake

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
macro(enable_cuda_compilation name files)
1010
if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA")
11-
if (BUILD_SHARED_LIBS)
11+
if (FLANG_RT_ENABLE_SHARED)
1212
message(FATAL_ERROR
13-
"BUILD_SHARED_LIBS is not supported for CUDA build of Fortran runtime"
13+
"FLANG_RT_ENABLE_SHARED is not supported for CUDA build of Flang-RT"
1414
)
1515
endif()
1616

@@ -70,9 +70,9 @@ macro(enable_omp_offload_compilation name files)
7070
if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "OpenMP")
7171
# OpenMP offload build only works with Clang compiler currently.
7272

73-
if (BUILD_SHARED_LIBS)
73+
if (FLANG_RT_ENABLE_SHARED)
7474
message(FATAL_ERROR
75-
"BUILD_SHARED_LIBS is not supported for OpenMP offload build of Fortran runtime"
75+
"FLANG_RT_ENABLE_SHARED is not supported for OpenMP offload build of Flang-RT"
7676
)
7777
endif()
7878

0 commit comments

Comments
 (0)