|
16 | 16 | # STATIC
|
17 | 17 | # Build a static (.a/.lib) library
|
18 | 18 | # 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. |
20 | 21 | # INSTALL_WITH_TOOLCHAIN
|
21 | 22 | # Install library into Clang's resource directory so it can be found by the
|
22 | 23 | # Flang driver during compilation, including tests
|
@@ -44,131 +45,219 @@ function (add_flangrt_library name)
|
44 | 45 | ")
|
45 | 46 | endif ()
|
46 | 47 |
|
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}) |
51 | 75 | 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 () |
54 | 82 | endif ()
|
| 83 | + |
| 84 | + # Build an object library if building multiple libraries at once or if |
| 85 | + # explicitly requested. |
| 86 | + set(build_object OFF) |
55 | 87 | 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}") |
57 | 103 | 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 "") |
58 | 115 | if (ARG_EXCLUDE_FROM_ALL)
|
59 | 116 | list(APPEND extra_args EXCLUDE_FROM_ALL)
|
60 | 117 | endif ()
|
61 | 118 |
|
62 | 119 | # Also add header files to IDEs to list as part of the library.
|
63 | 120 | set_source_files_properties(${ARG_ADDITIONAL_HEADERS} PROPERTIES HEADER_FILE_ONLY ON)
|
64 | 121 |
|
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 | + ) |
66 | 129 |
|
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}) |
73 | 139 | endif ()
|
74 | 140 |
|
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 () |
77 | 147 |
|
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 () |
92 | 154 |
|
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 () |
105 | 176 |
|
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 () |
108 | 189 |
|
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") |
112 | 192 |
|
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") |
115 | 196 |
|
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}") |
122 | 199 |
|
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) |
131 | 205 | 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 () |
141 | 226 | endif ()
|
142 |
| - endif () |
143 | 227 |
|
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 () |
154 | 239 |
|
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 | + ) |
163 | 250 |
|
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 () |
168 | 256 |
|
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 () |
174 | 263 | endfunction (add_flangrt_library)
|
0 commit comments