Skip to content

Commit df2578a

Browse files
committed
Finalize FLANG_RT_ENABLE_SHARED
1 parent e751b6f commit df2578a

File tree

5 files changed

+175
-161
lines changed

5 files changed

+175
-161
lines changed

flang-rt/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ else ()
142142
option(FLANG_RT_ENABLE_SHARED "Build Flang-RT as a shared library." ON)
143143
endif ()
144144
if (NOT FLANG_RT_ENABLE_STATIC AND NOT FLANG_RT_ENABLE_SHARED)
145-
message(FATAL_ERROR "Must build at least one type of library
145+
message(FATAL_ERROR "
146+
Must build at least one type of library
146147
(FLANG_RT_ENABLE_STATIC=ON, FLANG_RT_ENABLE_SHARED=ON, or both)
147148
")
148149
endif ()

flang-rt/cmake/modules/AddFlangRT.cmake

Lines changed: 157 additions & 147 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
@@ -42,30 +43,35 @@ function (add_flangrt_library name)
4243
INSTALL_WITH_TOOLCHAIN and EXCLUDE_FROM_ALL are in conflict. When
4344
installing an artifact it must have been built first in the 'all' target.
4445
")
45-
return ()
4646
endif ()
4747

48-
#if (ARG_CMAKE_CONFIGURABLE AND (ARG_STATIC OR ARG_SHARED))
49-
# message(SEND_ERROR "add_flangrt_library(${name} ...):
50-
# CMAKE_CONFIGURABLE cannot be used together with STATIC or SHARED.
51-
# ")
52-
# return ()
53-
#endif ()
54-
55-
#if (NOT ARG_STATIC AND NOT ARG_SHARED AND NOT ARG_CMAKE_CONFIGURABLE AND NOT ARG_OBJECT)
56-
# message(SEND_ERROR "add_flangrt_library(${name} ...):
57-
# Must specifiy library type.
58-
# ")
59-
# return ()
60-
#endif ()
61-
62-
set(build_static OFF)
63-
set(build_shared OFF)
64-
if (ARG_STATIC AND FLANG_RT_ENABLE_STATIC)
65-
set(build_static ON)
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}")
6664
endif ()
67-
if (ARG_SHARED AND FLANG_RT_ENABLE_SHARED)
68-
set(build_shared ON)
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})
6975
endif ()
7076
if (NOT ARG_STATIC AND NOT ARG_SHARED AND NOT ARG_OBJECT)
7177
if (BUILD_SHARED_LIBS)
@@ -75,73 +81,61 @@ function (add_flangrt_library name)
7581
endif ()
7682
endif ()
7783

78-
# Name of targets must only depend on function arguments to be predictable for callers.
79-
if (ARG_STATIC AND ARG_SHARED)
80-
set(name_static "${name}.static")
81-
set(name_shared "${name}.shared")
82-
else ()
83-
set(name_static "${name}")
84-
set(name_shared "${name}")
85-
endif ()
86-
if (ARG_OBJECT AND NOT ARG_STATIC AND NOT ARG_SHARED)
87-
set(name_object "${name}")
88-
else ()
89-
set(name_object "obj.${name}")
84+
# Build an object library if building multiple libraries at once or if
85+
# explicitly requested.
86+
set(build_object OFF)
87+
if (ARG_OBJECT)
88+
set(build_object ON)
89+
elseif (build_static AND build_shared)
90+
set(build_object ON)
9091
endif ()
9192

92-
93-
if (ARG_OBJECT AND NOT build_static AND NOT build_shared)
94-
set(build_only_objectlib ON)
95-
else ()
96-
set(build_only_objectlib OFF)
93+
# srctargets: targets that contain source files
94+
# libtargets: static/shared if they are built
95+
# alltargets: static/shared/object if they are built
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}")
97103
endif ()
98-
if (build_only_objectlib OR (build_static AND build_shared))
99-
set(need_objectlib ON)
100-
else ()
101-
set(need_objectlib OFF)
104+
if (build_shared)
105+
list(APPEND srctargets "${name_shared}")
106+
list(APPEND libtargets "${name_shared}")
107+
list(APPEND alltargets "${name_shared}")
102108
endif ()
103-
104-
if (NOT build_static AND NOT build_shared AND NOT need_objectlib)
105-
# Nothing to build
106-
return ()
109+
if (build_object)
110+
set(srctargets "${name_object}")
111+
list(APPEND alltargets "${name_object}")
107112
endif ()
108113

109-
# Also add header files to IDEs to list as part of the library
110-
set_source_files_properties(${ARG_ADDITIONAL_HEADERS} PROPERTIES HEADER_FILE_ONLY ON)
111-
112114
set(extra_args "")
113115
if (ARG_EXCLUDE_FROM_ALL)
114116
list(APPEND extra_args EXCLUDE_FROM_ALL)
115117
endif ()
116118

119+
# Also add header files to IDEs to list as part of the library.
120+
set_source_files_properties(${ARG_ADDITIONAL_HEADERS} PROPERTIES HEADER_FILE_ONLY ON)
117121

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

122-
# Replace arguments for the libraries we are going to create
130+
# Replace arguments for the libraries we are going to create.
123131
set(ARG_ADDITIONAL_HEADERS "")
124-
set(ARG_UNPARSED_ARGUMENTS $<TARGET_OBJECTS:${objectlib_name}>)
125-
set(srctargets ${name_object})
126-
set(liblist nostargets)
127-
set(alltargets ${name_object})
128-
else ()
129-
set(liblist srctargets)
130-
set(alltargets)
132+
set(ARG_UNPARSED_ARGUMENTS "$<TARGET_OBJECTS:${objectlib_name}>")
131133
endif ()
132-
133-
set(libtargets "")
134134
if (build_static)
135135
add_library(${name_static} STATIC ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})
136-
list(APPEND alltargets ${name_static})
137-
list(APPEND libtargets ${name_static})
138-
list(APPEND ${liblist} ${name_static})
139136
endif ()
140137
if (build_shared)
141138
add_library(${name_shared} SHARED ${extra_args} ${ARG_ADDITIONAL_HEADERS} ${ARG_UNPARSED_ARGUMENTS})
142-
list(APPEND alltargets ${name_shared})
143-
list(APPEND libtargets ${name_shared})
144-
list(APPEND ${liblist} ${name_shared})
145139
endif ()
146140

147141
foreach (name IN LISTS libtargets)
@@ -152,98 +146,114 @@ function (add_flangrt_library name)
152146
endif ()
153147
endforeach ()
154148

149+
# Define how to compile and link the library.
150+
# Some conceptionally only apply to ${srctargets} or ${libtargets}, but we
151+
# apply them to ${alltargets}. In worst case, they are ignored by CMake.
155152
foreach (name IN LISTS alltargets)
156153
# Minimum required C++ version for Flang-RT, even if CMAKE_CXX_STANDARD is defined to something else.
157154
target_compile_features(${name} PRIVATE cxx_std_17)
158155

156+
# Use compiler-specific options to disable exceptions and RTTI.
157+
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
158+
target_compile_options(${name} PRIVATE
159+
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
160+
)
161+
elseif (MSVC)
162+
target_compile_options(${name} PRIVATE
163+
$<$<COMPILE_LANGUAGE:CXX>:/EHs-c- /GR->
164+
)
165+
elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
166+
target_compile_options(${name} PRIVATE
167+
$<$<COMPILE_LANGUAGE:CXX>:-qnoeh -qnortti>
168+
)
169+
endif ()
159170

160-
# Use compiler-specific options to disable exceptions and RTTI.
161-
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
162-
target_compile_options(${name} PRIVATE
163-
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
164-
)
165-
elseif (MSVC)
166-
target_compile_options(${name} PRIVATE
167-
$<$<COMPILE_LANGUAGE:CXX>:/EHs-c- /GR->
168-
)
169-
elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
170-
target_compile_options(${name} PRIVATE
171-
$<$<COMPILE_LANGUAGE:CXX>:-qnoeh -qnortti>
172-
)
173-
endif ()
174-
175-
# Also for CUDA source when compiling with FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA
176-
if (CMAKE_CUDA_COMPILER_ID MATCHES "NVIDIA")
177-
# Assuming gcc as host compiler.
178-
target_compile_options(${name} PRIVATE
179-
$<$<COMPILE_LANGUAGE:CUDA>:--no-exceptions -Xcompiler -fno-rtti -Xcompiler -fno-unwind-tables -Xcompiler -fno-asynchronous-unwind-tables>
180-
)
181-
else ()
182-
# Assuming a clang-compatible CUDA compiler.
183-
target_compile_options(${name} PRIVATE
184-
$<$<COMPILE_LANGUAGE:CUDA>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
185-
)
186-
endif ()
171+
# Also for CUDA source when compiling with FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA
172+
if (CMAKE_CUDA_COMPILER_ID MATCHES "NVIDIA")
173+
# Assuming gcc as host compiler.
174+
target_compile_options(${name} PRIVATE
175+
$<$<COMPILE_LANGUAGE:CUDA>:--no-exceptions -Xcompiler -fno-rtti -Xcompiler -fno-unwind-tables -Xcompiler -fno-asynchronous-unwind-tables>
176+
)
177+
else ()
178+
# Assuming a clang-compatible CUDA compiler.
179+
target_compile_options(${name} PRIVATE
180+
$<$<COMPILE_LANGUAGE:CUDA>:-fno-exceptions -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables>
181+
)
182+
endif ()
187183

188-
# Flang-rt's public headers
189-
target_include_directories(${name} PRIVATE "${FLANG_RT_SOURCE_DIR}/include")
184+
# Flang-RT's public headers
185+
target_include_directories(${name} PRIVATE "${FLANG_RT_SOURCE_DIR}/include")
190186

191-
# For ISO_Fortran_binding.h to be found by the runtime itself (Accessed as #include "flang/ISO_Fortran_binding.h")
192-
# User applications can use #include <ISO_Fortran_binding.h>
193-
target_include_directories(${name} PRIVATE "${FLANG_SOURCE_DIR}/include")
187+
# For ISO_Fortran_binding.h to be found by the runtime itself (Accessed as #include "flang/ISO_Fortran_binding.h")
188+
# User applications can use #include <ISO_Fortran_binding.h>
189+
target_include_directories(${name} PRIVATE "${FLANG_SOURCE_DIR}/include")
194190

195-
# For Flang-RT's configured config.h to be found
196-
target_include_directories(${name} PRIVATE "${FLANG_RT_BINARY_DIR}")
191+
# For Flang-RT's configured config.h to be found
192+
target_include_directories(${name} PRIVATE "${FLANG_RT_BINARY_DIR}")
197193

198-
# Disable libstdc++/libc++ assertions, even in an LLVM_ENABLE_ASSERTIONS
199-
# build, to avoid an unwanted dependency on libstdc++/libc++.so.
200-
if (FLANG_RT_SUPPORTS_UNDEFINE_FLAG)
201-
target_compile_options(${name} PUBLIC -U_GLIBCXX_ASSERTIONS)
202-
target_compile_options(${name} PUBLIC -U_LIBCPP_ENABLE_ASSERTIONS)
203-
endif ()
194+
# Disable libstdc++/libc++ assertions, even in an LLVM_ENABLE_ASSERTIONS
195+
# build, to avoid an unwanted dependency on libstdc++/libc++.so.
196+
if (FLANG_RT_SUPPORTS_UNDEFINE_FLAG)
197+
target_compile_options(${name} PUBLIC -U_GLIBCXX_ASSERTIONS)
198+
target_compile_options(${name} PUBLIC -U_LIBCPP_ENABLE_ASSERTIONS)
199+
endif ()
204200

205-
# Flang/Clang (including clang-cl) -compiled programs targeting the MSVC ABI
206-
# should only depend on msv(u)crt. LLVM still emits libgcc/compiler-rt
207-
# functions in some cases like 128-bit integer math (__udivti3, __modti3,
208-
# __fixsfti, __floattidf, ...) that msvc does not support. We are injecting a
209-
# dependency to Compiler-RT's builtin library where these are implemented.
210-
if (MSVC AND (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") AND FLANG_RT_BUILTINS_LIBRARY)
211-
target_compile_options(${name} PRIVATE "$<$<COMPILE_LANGUAGE:CXX,C>:-Xclang>$<$<COMPILE_LANGUAGE:Fortran>:-Xflang>" "--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}")
212-
endif ()
201+
# Flang/Clang (including clang-cl) -compiled programs targeting the MSVC ABI
202+
# should only depend on msvcrt/ucrt. LLVM still emits libgcc/compiler-rt
203+
# functions in some cases like 128-bit integer math (__udivti3, __modti3,
204+
# __fixsfti, __floattidf, ...) that msvc does not support. We are injecting a
205+
# dependency to Compiler-RT's builtin library where these are implemented.
206+
if (MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
207+
if (FLANG_RT_BUILTINS_LIBRARY)
208+
target_compile_options(${name} PRIVATE "$<$<COMPILE_LANGUAGE:CXX,C>:-Xclang>" "--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}")
209+
endif ()
210+
endif ()
211+
if (MSVC AND CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
212+
if (FLANG_RT_BUILTINS_LIBRARY)
213+
target_compile_options(${name} PRIVATE "$<$<COMPILE_LANGUAGE:Fortran>:-Xflang>" "--dependent-lib=${FLANG_RT_BUILTINS_LIBRARY}")
214+
else ()
215+
message(WARNING "Did not find libclang_rt.builtins.lib.
216+
LLVM may emit builtins that are not implemented in msvcrt/ucrt and
217+
instead falls back to builtins from Compiler-RT. Linking with ${name}
218+
may result in a linker error.")
219+
endif ()
220+
endif ()
213221

214-
# Non-GTest unittests depend on LLVMSupport
215-
if (ARG_LINK_TO_LLVM)
216-
if (LLVM_LINK_LLVM_DYLIB)
217-
set(llvm_libs LLVM)
218-
else()
219-
llvm_map_components_to_libnames(llvm_libs Support)
220-
endif()
221-
target_link_libraries(${name} PUBLIC ${llvm_libs})
222-
target_include_directories(${name} PUBLIC ${LLVM_INCLUDE_DIRS})
223-
endif ()
222+
# Non-GTest unittests depend on LLVMSupport
223+
if (ARG_LINK_TO_LLVM)
224+
if (LLVM_LINK_LLVM_DYLIB)
225+
set(llvm_libs LLVM)
226+
else()
227+
llvm_map_components_to_libnames(llvm_libs Support)
228+
endif()
229+
target_link_libraries(${name} PUBLIC ${llvm_libs})
230+
target_include_directories(${name} PUBLIC ${LLVM_INCLUDE_DIRS})
231+
endif ()
232+
endforeach ()
224233

225-
# If this is part of the toolchain, put it into the compiler's resource
226-
# directory. Otherwise it is part of testing and is not installed at all.
227-
# TODO: Consider multi-configuration builds (MSVC_IDE, "Ninja Multi-Config")
228-
if (ARG_INSTALL_WITH_TOOLCHAIN)
229-
set_target_properties(${name}
230-
PROPERTIES
231-
LIBRARY_OUTPUT_DIRECTORY "${FLANG_RT_BUILD_TOOLCHAIN_LIB_DIR}"
232-
ARCHIVE_OUTPUT_DIRECTORY "${FLANG_RT_BUILD_TOOLCHAIN_LIB_DIR}"
233-
RUNTIME_OUTPUT_DIRECTORY "${FLANG_RT_BUILD_TOOLCHAIN_LIB_DIR}"
234-
)
234+
foreach (name IN LISTS libtargets)
235+
# If this is part of the toolchain, put it into the compiler's resource
236+
# directory. Otherwise it is part of testing and is not installed at all.
237+
# TODO: Consider multi-configuration builds (MSVC_IDE, "Ninja Multi-Config")
238+
if (ARG_INSTALL_WITH_TOOLCHAIN)
239+
set_target_properties(${name}
240+
PROPERTIES
241+
LIBRARY_OUTPUT_DIRECTORY "${FLANG_RT_BUILD_TOOLCHAIN_LIB_DIR}"
242+
ARCHIVE_OUTPUT_DIRECTORY "${FLANG_RT_BUILD_TOOLCHAIN_LIB_DIR}"
243+
RUNTIME_OUTPUT_DIRECTORY "${FLANG_RT_BUILD_TOOLCHAIN_LIB_DIR}"
244+
)
235245

236-
install(TARGETS ${name}
237-
LIBRARY DESTINATION "${FLANG_RT_INSTALL_TOOLCHAIN_LIB_DIR}"
238-
ARCHIVE DESTINATION "${FLANG_RT_INSTALL_TOOLCHAIN_LIB_DIR}"
239-
RUNTIME DESTINATION "${FLANG_RT_INSTALL_TOOLCHAIN_LIB_DIR}"
240-
)
241-
endif ()
246+
install(TARGETS ${name}
247+
LIBRARY DESTINATION "${FLANG_RT_INSTALL_TOOLCHAIN_LIB_DIR}"
248+
ARCHIVE DESTINATION "${FLANG_RT_INSTALL_TOOLCHAIN_LIB_DIR}"
249+
RUNTIME DESTINATION "${FLANG_RT_INSTALL_TOOLCHAIN_LIB_DIR}"
250+
)
251+
endif ()
242252

243-
# flang-rt should build all the flang-rt targets that are built in an
244-
# 'all' build.
245-
if (NOT ARG_EXCLUDE_FROM_ALL)
246-
add_dependencies(flang-rt ${name})
247-
endif ()
253+
# flang-rt should build all the Flang-RT targets that are built in an
254+
# 'all' build.
255+
if (NOT ARG_EXCLUDE_FROM_ALL)
256+
add_dependencies(flang-rt ${name})
257+
endif ()
248258
endforeach ()
249259
endfunction (add_flangrt_library)

0 commit comments

Comments
 (0)