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 ()
249259endfunction (add_flangrt_library)
0 commit comments