Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | include(GNUInstallDirs) |
| 2 | include(LLVMDistributionSupport) |
||
| 3 | include(LLVMProcessSources) |
||
| 4 | include(LLVM-Config) |
||
| 5 | include(DetermineGCCCompatible) |
||
| 6 | |||
| 7 | function(llvm_update_compile_flags name) |
||
| 8 | get_property(sources TARGET ${name} PROPERTY SOURCES) |
||
| 9 | if("${sources}" MATCHES "\\.c(;|$)") |
||
| 10 | set(update_src_props ON) |
||
| 11 | endif() |
||
| 12 | |||
| 13 | list(APPEND LLVM_COMPILE_CFLAGS " ${LLVM_COMPILE_FLAGS}") |
||
| 14 | |||
| 15 | # LLVM_REQUIRES_EH is an internal flag that individual targets can use to |
||
| 16 | # force EH |
||
| 17 | if(LLVM_REQUIRES_EH OR LLVM_ENABLE_EH) |
||
| 18 | if(NOT (LLVM_REQUIRES_RTTI OR LLVM_ENABLE_RTTI)) |
||
| 19 | message(AUTHOR_WARNING "Exception handling requires RTTI. Enabling RTTI for ${name}") |
||
| 20 | set(LLVM_REQUIRES_RTTI ON) |
||
| 21 | endif() |
||
| 22 | if(MSVC) |
||
| 23 | list(APPEND LLVM_COMPILE_FLAGS "/EHsc") |
||
| 24 | endif() |
||
| 25 | else() |
||
| 26 | if(LLVM_COMPILER_IS_GCC_COMPATIBLE) |
||
| 27 | list(APPEND LLVM_COMPILE_FLAGS "-fno-exceptions") |
||
| 28 | if(NOT LLVM_ENABLE_UNWIND_TABLES) |
||
| 29 | list(APPEND LLVM_COMPILE_FLAGS "-fno-unwind-tables") |
||
| 30 | list(APPEND LLVM_COMPILE_FLAGS "-fno-asynchronous-unwind-tables") |
||
| 31 | endif() |
||
| 32 | elseif(MSVC) |
||
| 33 | list(APPEND LLVM_COMPILE_DEFINITIONS _HAS_EXCEPTIONS=0) |
||
| 34 | list(APPEND LLVM_COMPILE_FLAGS "/EHs-c-") |
||
| 35 | elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL") |
||
| 36 | list(APPEND LLVM_COMPILE_FLAGS "-qnoeh") |
||
| 37 | endif() |
||
| 38 | endif() |
||
| 39 | |||
| 40 | # LLVM_REQUIRES_RTTI is an internal flag that individual |
||
| 41 | # targets can use to force RTTI |
||
| 42 | set(LLVM_CONFIG_HAS_RTTI YES CACHE INTERNAL "") |
||
| 43 | if(NOT (LLVM_REQUIRES_RTTI OR LLVM_ENABLE_RTTI)) |
||
| 44 | set(LLVM_CONFIG_HAS_RTTI NO CACHE INTERNAL "") |
||
| 45 | list(APPEND LLVM_COMPILE_DEFINITIONS GTEST_HAS_RTTI=0) |
||
| 46 | if (LLVM_COMPILER_IS_GCC_COMPATIBLE) |
||
| 47 | list(APPEND LLVM_COMPILE_FLAGS "-fno-rtti") |
||
| 48 | elseif (MSVC) |
||
| 49 | list(APPEND LLVM_COMPILE_FLAGS "/GR-") |
||
| 50 | elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL") |
||
| 51 | list(APPEND LLVM_COMPILE_FLAGS "-qnortti") |
||
| 52 | endif () |
||
| 53 | elseif(MSVC) |
||
| 54 | list(APPEND LLVM_COMPILE_FLAGS "/GR") |
||
| 55 | endif() |
||
| 56 | |||
| 57 | # Assume that; |
||
| 58 | # - LLVM_COMPILE_FLAGS is list. |
||
| 59 | # - PROPERTY COMPILE_FLAGS is string. |
||
| 60 | string(REPLACE ";" " " target_compile_flags " ${LLVM_COMPILE_FLAGS}") |
||
| 61 | string(REPLACE ";" " " target_compile_cflags " ${LLVM_COMPILE_CFLAGS}") |
||
| 62 | |||
| 63 | if(update_src_props) |
||
| 64 | foreach(fn ${sources}) |
||
| 65 | get_filename_component(suf ${fn} EXT) |
||
| 66 | if("${suf}" STREQUAL ".cpp") |
||
| 67 | set_property(SOURCE ${fn} APPEND_STRING PROPERTY |
||
| 68 | COMPILE_FLAGS "${target_compile_flags}") |
||
| 69 | endif() |
||
| 70 | if("${suf}" STREQUAL ".c") |
||
| 71 | set_property(SOURCE ${fn} APPEND_STRING PROPERTY |
||
| 72 | COMPILE_FLAGS "${target_compile_cflags}") |
||
| 73 | endif() |
||
| 74 | endforeach() |
||
| 75 | else() |
||
| 76 | # Update target props, since all sources are C++. |
||
| 77 | set_property(TARGET ${name} APPEND_STRING PROPERTY |
||
| 78 | COMPILE_FLAGS "${target_compile_flags}") |
||
| 79 | endif() |
||
| 80 | |||
| 81 | set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS ${LLVM_COMPILE_DEFINITIONS}) |
||
| 82 | endfunction() |
||
| 83 | |||
| 84 | function(add_llvm_symbol_exports target_name export_file) |
||
| 85 | if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") |
||
| 86 | set(native_export_file "${target_name}.exports") |
||
| 87 | add_custom_command(OUTPUT ${native_export_file} |
||
| 88 | COMMAND sed -e "s/^/_/" < ${export_file} > ${native_export_file} |
||
| 89 | DEPENDS ${export_file} |
||
| 90 | VERBATIM |
||
| 91 | COMMENT "Creating export file for ${target_name}") |
||
| 92 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 93 | LINK_FLAGS " -Wl,-exported_symbols_list,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\"") |
||
| 94 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "AIX") |
||
| 95 | # FIXME: `-Wl,-bE:` bypasses whatever handling there is in the build |
||
| 96 | # compiler driver to defer to the specified export list. |
||
| 97 | set(native_export_file "${export_file}") |
||
| 98 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 99 | LINK_FLAGS " -Wl,-bE:${export_file}") |
||
| 100 | elseif(LLVM_HAVE_LINK_VERSION_SCRIPT) |
||
| 101 | # Gold and BFD ld require a version script rather than a plain list. |
||
| 102 | set(native_export_file "${target_name}.exports") |
||
| 103 | # FIXME: Don't write the "local:" line on OpenBSD. |
||
| 104 | # in the export file, also add a linker script to version LLVM symbols (form: LLVM_N.M) |
||
| 105 | add_custom_command(OUTPUT ${native_export_file} |
||
| 106 | COMMAND "${Python3_EXECUTABLE}" "-c" |
||
| 107 | "import sys; \ |
||
| 108 | lines = [' ' + l.rstrip() for l in sys.stdin] + [' local: *;']; \ |
||
| 109 | print('LLVM_${LLVM_VERSION_MAJOR} {'); \ |
||
| 110 | print(' global:') if len(lines) > 1 else None; \ |
||
| 111 | print(';\\n'.join(lines) + '\\n};')" |
||
| 112 | < ${export_file} > ${native_export_file} |
||
| 113 | DEPENDS ${export_file} |
||
| 114 | VERBATIM |
||
| 115 | COMMENT "Creating export file for ${target_name}") |
||
| 116 | if (${LLVM_LINKER_IS_SOLARISLD}) |
||
| 117 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 118 | LINK_FLAGS " -Wl,-M,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\"") |
||
| 119 | else() |
||
| 120 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 121 | LINK_FLAGS " -Wl,--version-script,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\"") |
||
| 122 | endif() |
||
| 123 | elseif(WIN32) |
||
| 124 | set(native_export_file "${target_name}.def") |
||
| 125 | |||
| 126 | add_custom_command(OUTPUT ${native_export_file} |
||
| 127 | COMMAND "${Python3_EXECUTABLE}" -c "import sys;print(''.join(['EXPORTS\\n']+sys.stdin.readlines(),))" |
||
| 128 | < ${export_file} > ${native_export_file} |
||
| 129 | DEPENDS ${export_file} |
||
| 130 | VERBATIM |
||
| 131 | COMMENT "Creating export file for ${target_name}") |
||
| 132 | set(export_file_linker_flag "${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}") |
||
| 133 | if(MSVC) |
||
| 134 | # cl.exe or clang-cl, i.e. MSVC style command line interface |
||
| 135 | set(export_file_linker_flag "/DEF:\"${export_file_linker_flag}\"") |
||
| 136 | elseif(CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") |
||
| 137 | # clang in msvc mode, calling a link.exe/lld-link style linker |
||
| 138 | set(export_file_linker_flag "-Wl,/DEF:\"${export_file_linker_flag}\"") |
||
| 139 | elseif(MINGW) |
||
| 140 | # ${export_file_linker_flag}, which is the plain file name, works as is |
||
| 141 | # when passed to the compiler driver, which then passes it on to the |
||
| 142 | # linker as an input file. |
||
| 143 | set(export_file_linker_flag "\"${export_file_linker_flag}\"") |
||
| 144 | else() |
||
| 145 | message(FATAL_ERROR "Unsupported Windows toolchain") |
||
| 146 | endif() |
||
| 147 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 148 | LINK_FLAGS " ${export_file_linker_flag}") |
||
| 149 | endif() |
||
| 150 | |||
| 151 | add_custom_target(${target_name}_exports DEPENDS ${native_export_file}) |
||
| 152 | set_target_properties(${target_name}_exports PROPERTIES FOLDER "Misc") |
||
| 153 | |||
| 154 | get_property(srcs TARGET ${target_name} PROPERTY SOURCES) |
||
| 155 | foreach(src ${srcs}) |
||
| 156 | get_filename_component(extension ${src} EXT) |
||
| 157 | if(extension STREQUAL ".cpp") |
||
| 158 | set(first_source_file ${src}) |
||
| 159 | break() |
||
| 160 | endif() |
||
| 161 | endforeach() |
||
| 162 | |||
| 163 | # Force re-linking when the exports file changes. Actually, it |
||
| 164 | # forces recompilation of the source file. The LINK_DEPENDS target |
||
| 165 | # property only works for makefile-based generators. |
||
| 166 | # FIXME: This is not safe because this will create the same target |
||
| 167 | # ${native_export_file} in several different file: |
||
| 168 | # - One where we emitted ${target_name}_exports |
||
| 169 | # - One where we emitted the build command for the following object. |
||
| 170 | # set_property(SOURCE ${first_source_file} APPEND PROPERTY |
||
| 171 | # OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}) |
||
| 172 | |||
| 173 | set_property(DIRECTORY APPEND |
||
| 174 | PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${native_export_file}) |
||
| 175 | |||
| 176 | add_dependencies(${target_name} ${target_name}_exports) |
||
| 177 | |||
| 178 | # Add dependency to *_exports later -- CMake issue 14747 |
||
| 179 | list(APPEND LLVM_COMMON_DEPENDS ${target_name}_exports) |
||
| 180 | set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE) |
||
| 181 | endfunction(add_llvm_symbol_exports) |
||
| 182 | |||
| 183 | if (NOT DEFINED LLVM_LINKER_DETECTED AND NOT WIN32) |
||
| 184 | # Detect what linker we have here. |
||
| 185 | if(APPLE) |
||
| 186 | # Linkers with ld64-compatible flags. |
||
| 187 | set(version_flag "-Wl,-v") |
||
| 188 | else() |
||
| 189 | # Linkers with BFD ld-compatible flags. |
||
| 190 | set(version_flag "-Wl,--version") |
||
| 191 | endif() |
||
| 192 | |||
| 193 | if (CMAKE_HOST_WIN32) |
||
| 194 | set(DEVNULL "NUL") |
||
| 195 | else() |
||
| 196 | set(DEVNULL "/dev/null") |
||
| 197 | endif() |
||
| 198 | |||
| 199 | if(LLVM_USE_LINKER) |
||
| 200 | set(command ${CMAKE_C_COMPILER} -fuse-ld=${LLVM_USE_LINKER} ${version_flag} -o ${DEVNULL}) |
||
| 201 | else() |
||
| 202 | separate_arguments(flags UNIX_COMMAND "${CMAKE_EXE_LINKER_FLAGS}") |
||
| 203 | set(command ${CMAKE_C_COMPILER} ${flags} ${version_flag} -o ${DEVNULL}) |
||
| 204 | endif() |
||
| 205 | execute_process( |
||
| 206 | COMMAND ${command} |
||
| 207 | OUTPUT_VARIABLE stdout |
||
| 208 | ERROR_VARIABLE stderr |
||
| 209 | ) |
||
| 210 | |||
| 211 | if(APPLE) |
||
| 212 | if("${stderr}" MATCHES "PROJECT:ld64") |
||
| 213 | set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "") |
||
| 214 | set(LLVM_LINKER_IS_LD64 YES CACHE INTERNAL "") |
||
| 215 | message(STATUS "Linker detection: ld64") |
||
| 216 | elseif("${stderr}" MATCHES "^LLD" OR |
||
| 217 | "${stdout}" MATCHES "^LLD") |
||
| 218 | set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "") |
||
| 219 | set(LLVM_LINKER_IS_LLD YES CACHE INTERNAL "") |
||
| 220 | message(STATUS "Linker detection: lld") |
||
| 221 | else() |
||
| 222 | set(LLVM_LINKER_DETECTED NO CACHE INTERNAL "") |
||
| 223 | message(STATUS "Linker detection: unknown") |
||
| 224 | endif() |
||
| 225 | else() |
||
| 226 | if("${stdout}" MATCHES "^mold") |
||
| 227 | set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "") |
||
| 228 | set(LLVM_LINKER_IS_MOLD YES CACHE INTERNAL "") |
||
| 229 | message(STATUS "Linker detection: mold") |
||
| 230 | elseif("${stdout}" MATCHES "GNU gold") |
||
| 231 | set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "") |
||
| 232 | set(LLVM_LINKER_IS_GOLD YES CACHE INTERNAL "") |
||
| 233 | message(STATUS "Linker detection: GNU Gold") |
||
| 234 | elseif("${stdout}" MATCHES "^LLD") |
||
| 235 | set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "") |
||
| 236 | set(LLVM_LINKER_IS_LLD YES CACHE INTERNAL "") |
||
| 237 | message(STATUS "Linker detection: LLD") |
||
| 238 | elseif("${stdout}" MATCHES "GNU ld") |
||
| 239 | set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "") |
||
| 240 | set(LLVM_LINKER_IS_GNULD YES CACHE INTERNAL "") |
||
| 241 | message(STATUS "Linker detection: GNU ld") |
||
| 242 | elseif("${stderr}" MATCHES "Solaris Link Editors" OR |
||
| 243 | "${stdout}" MATCHES "Solaris Link Editors") |
||
| 244 | set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "") |
||
| 245 | set(LLVM_LINKER_IS_SOLARISLD YES CACHE INTERNAL "") |
||
| 246 | message(STATUS "Linker detection: Solaris ld") |
||
| 247 | else() |
||
| 248 | set(LLVM_LINKER_DETECTED NO CACHE INTERNAL "") |
||
| 249 | message(STATUS "Linker detection: unknown") |
||
| 250 | endif() |
||
| 251 | endif() |
||
| 252 | endif() |
||
| 253 | |||
| 254 | function(add_link_opts target_name) |
||
| 255 | get_llvm_distribution(${target_name} in_distribution in_distribution_var) |
||
| 256 | if(NOT in_distribution) |
||
| 257 | # Don't LTO optimize targets that aren't part of any distribution. |
||
| 258 | if (LLVM_ENABLE_LTO) |
||
| 259 | # We may consider avoiding LTO altogether by using -fembed-bitcode |
||
| 260 | # and teaching the linker to select machine code from .o files, see |
||
| 261 | # https://lists.llvm.org/pipermail/llvm-dev/2021-April/149843.html |
||
| 262 | if((UNIX OR MINGW) AND LINKER_IS_LLD) |
||
| 263 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 264 | LINK_FLAGS " -Wl,--lto-O0") |
||
| 265 | elseif(LINKER_IS_LLD_LINK) |
||
| 266 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 267 | LINK_FLAGS " /opt:lldlto=0") |
||
| 268 | elseif(APPLE AND NOT uppercase_LLVM_ENABLE_LTO STREQUAL "THIN") |
||
| 269 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 270 | LINK_FLAGS " -Wl,-mllvm,-O0") |
||
| 271 | endif() |
||
| 272 | endif() |
||
| 273 | endif() |
||
| 274 | |||
| 275 | # Don't use linker optimizations in debug builds since it slows down the |
||
| 276 | # linker in a context where the optimizations are not important. |
||
| 277 | if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") |
||
| 278 | if(NOT LLVM_NO_DEAD_STRIP) |
||
| 279 | if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") |
||
| 280 | # ld64's implementation of -dead_strip breaks tools that use plugins. |
||
| 281 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 282 | LINK_FLAGS " -Wl,-dead_strip") |
||
| 283 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") |
||
| 284 | # Support for ld -z discard-unused=sections was only added in |
||
| 285 | # Solaris 11.4. |
||
| 286 | include(LLVMCheckLinkerFlag) |
||
| 287 | llvm_check_linker_flag(CXX "-Wl,-z,discard-unused=sections" LINKER_SUPPORTS_Z_DISCARD_UNUSED) |
||
| 288 | if (LINKER_SUPPORTS_Z_DISCARD_UNUSED) |
||
| 289 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 290 | LINK_FLAGS " -Wl,-z,discard-unused=sections") |
||
| 291 | endif() |
||
| 292 | elseif(NOT MSVC AND NOT CMAKE_SYSTEM_NAME MATCHES "AIX|OS390") |
||
| 293 | # TODO Revisit this later on z/OS. |
||
| 294 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 295 | LINK_FLAGS " -Wl,--gc-sections") |
||
| 296 | endif() |
||
| 297 | else() #LLVM_NO_DEAD_STRIP |
||
| 298 | if(${CMAKE_SYSTEM_NAME} MATCHES "AIX") |
||
| 299 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 300 | LINK_FLAGS " -Wl,-bnogc") |
||
| 301 | endif() |
||
| 302 | endif() |
||
| 303 | endif() |
||
| 304 | |||
| 305 | if(ARG_SUPPORT_PLUGINS AND ${CMAKE_SYSTEM_NAME} MATCHES "AIX") |
||
| 306 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 307 | LINK_FLAGS " -Wl,-brtl") |
||
| 308 | endif() |
||
| 309 | endfunction(add_link_opts) |
||
| 310 | |||
| 311 | # Set each output directory according to ${CMAKE_CONFIGURATION_TYPES}. |
||
| 312 | # Note: Don't set variables CMAKE_*_OUTPUT_DIRECTORY any more, |
||
| 313 | # or a certain builder, for eaxample, msbuild.exe, would be confused. |
||
| 314 | function(set_output_directory target) |
||
| 315 | cmake_parse_arguments(ARG "" "BINARY_DIR;LIBRARY_DIR" "" ${ARGN}) |
||
| 316 | |||
| 317 | # module_dir -- corresponding to LIBRARY_OUTPUT_DIRECTORY. |
||
| 318 | # It affects output of add_library(MODULE). |
||
| 319 | if(WIN32 OR CYGWIN) |
||
| 320 | # DLL platform |
||
| 321 | set(module_dir ${ARG_BINARY_DIR}) |
||
| 322 | else() |
||
| 323 | set(module_dir ${ARG_LIBRARY_DIR}) |
||
| 324 | endif() |
||
| 325 | if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") |
||
| 326 | foreach(build_mode ${CMAKE_CONFIGURATION_TYPES}) |
||
| 327 | string(TOUPPER "${build_mode}" CONFIG_SUFFIX) |
||
| 328 | if(ARG_BINARY_DIR) |
||
| 329 | string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} bi ${ARG_BINARY_DIR}) |
||
| 330 | set_target_properties(${target} PROPERTIES "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${bi}) |
||
| 331 | endif() |
||
| 332 | if(ARG_LIBRARY_DIR) |
||
| 333 | string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} li ${ARG_LIBRARY_DIR}) |
||
| 334 | set_target_properties(${target} PROPERTIES "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${li}) |
||
| 335 | endif() |
||
| 336 | if(module_dir) |
||
| 337 | string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} mi ${module_dir}) |
||
| 338 | set_target_properties(${target} PROPERTIES "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${mi}) |
||
| 339 | endif() |
||
| 340 | endforeach() |
||
| 341 | else() |
||
| 342 | if(ARG_BINARY_DIR) |
||
| 343 | set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ARG_BINARY_DIR}) |
||
| 344 | endif() |
||
| 345 | if(ARG_LIBRARY_DIR) |
||
| 346 | set_target_properties(${target} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${ARG_LIBRARY_DIR}) |
||
| 347 | endif() |
||
| 348 | if(module_dir) |
||
| 349 | set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${module_dir}) |
||
| 350 | endif() |
||
| 351 | endif() |
||
| 352 | endfunction() |
||
| 353 | |||
| 354 | # If on Windows and building with MSVC, add the resource script containing the |
||
| 355 | # VERSIONINFO data to the project. This embeds version resource information |
||
| 356 | # into the output .exe or .dll. |
||
| 357 | # TODO: Enable for MinGW Windows builds too. |
||
| 358 | # |
||
| 359 | function(add_windows_version_resource_file OUT_VAR) |
||
| 360 | set(sources ${ARGN}) |
||
| 361 | if (MSVC AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") |
||
| 362 | set(resource_file ${LLVM_SOURCE_DIR}/resources/windows_version_resource.rc) |
||
| 363 | if(EXISTS ${resource_file}) |
||
| 364 | set(sources ${sources} ${resource_file}) |
||
| 365 | source_group("Resource Files" ${resource_file}) |
||
| 366 | set(windows_resource_file ${resource_file} PARENT_SCOPE) |
||
| 367 | endif() |
||
| 368 | endif(MSVC AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") |
||
| 369 | |||
| 370 | set(${OUT_VAR} ${sources} PARENT_SCOPE) |
||
| 371 | endfunction(add_windows_version_resource_file) |
||
| 372 | |||
| 373 | # set_windows_version_resource_properties(name resource_file... |
||
| 374 | # VERSION_MAJOR int |
||
| 375 | # Optional major version number (defaults to LLVM_VERSION_MAJOR) |
||
| 376 | # VERSION_MINOR int |
||
| 377 | # Optional minor version number (defaults to LLVM_VERSION_MINOR) |
||
| 378 | # VERSION_PATCHLEVEL int |
||
| 379 | # Optional patchlevel version number (defaults to LLVM_VERSION_PATCH) |
||
| 380 | # VERSION_STRING |
||
| 381 | # Optional version string (defaults to PACKAGE_VERSION) |
||
| 382 | # PRODUCT_NAME |
||
| 383 | # Optional product name string (defaults to "LLVM") |
||
| 384 | # ) |
||
| 385 | function(set_windows_version_resource_properties name resource_file) |
||
| 386 | cmake_parse_arguments(ARG |
||
| 387 | "" |
||
| 388 | "VERSION_MAJOR;VERSION_MINOR;VERSION_PATCHLEVEL;VERSION_STRING;PRODUCT_NAME" |
||
| 389 | "" |
||
| 390 | ${ARGN}) |
||
| 391 | |||
| 392 | if (NOT DEFINED ARG_VERSION_MAJOR) |
||
| 393 | if (${LLVM_VERSION_MAJOR}) |
||
| 394 | set(ARG_VERSION_MAJOR ${LLVM_VERSION_MAJOR}) |
||
| 395 | else() |
||
| 396 | set(ARG_VERSION_MAJOR 0) |
||
| 397 | endif() |
||
| 398 | endif() |
||
| 399 | |||
| 400 | if (NOT DEFINED ARG_VERSION_MINOR) |
||
| 401 | if (${LLVM_VERSION_MINOR}) |
||
| 402 | set(ARG_VERSION_MINOR ${LLVM_VERSION_MINOR}) |
||
| 403 | else() |
||
| 404 | set(ARG_VERSION_MINOR 0) |
||
| 405 | endif() |
||
| 406 | endif() |
||
| 407 | |||
| 408 | if (NOT DEFINED ARG_VERSION_PATCHLEVEL) |
||
| 409 | if (${LLVM_VERSION_PATCH}) |
||
| 410 | set(ARG_VERSION_PATCHLEVEL ${LLVM_VERSION_PATCH}) |
||
| 411 | else() |
||
| 412 | set(ARG_VERSION_PATCHLEVEL 0) |
||
| 413 | endif() |
||
| 414 | endif() |
||
| 415 | |||
| 416 | if (NOT DEFINED ARG_VERSION_STRING) |
||
| 417 | if (${PACKAGE_VERSION}) |
||
| 418 | set(ARG_VERSION_STRING ${PACKAGE_VERSION}) |
||
| 419 | else() |
||
| 420 | set(ARG_VERSION_STRING 0) |
||
| 421 | endif() |
||
| 422 | endif() |
||
| 423 | |||
| 424 | if (NOT DEFINED ARG_PRODUCT_NAME) |
||
| 425 | set(ARG_PRODUCT_NAME "LLVM") |
||
| 426 | endif() |
||
| 427 | |||
| 428 | set_property(SOURCE ${resource_file} |
||
| 429 | PROPERTY COMPILE_FLAGS /nologo) |
||
| 430 | set_property(SOURCE ${resource_file} |
||
| 431 | PROPERTY COMPILE_DEFINITIONS |
||
| 432 | "RC_VERSION_FIELD_1=${ARG_VERSION_MAJOR}" |
||
| 433 | "RC_VERSION_FIELD_2=${ARG_VERSION_MINOR}" |
||
| 434 | "RC_VERSION_FIELD_3=${ARG_VERSION_PATCHLEVEL}" |
||
| 435 | "RC_VERSION_FIELD_4=0" |
||
| 436 | "RC_FILE_VERSION=\"${ARG_VERSION_STRING}\"" |
||
| 437 | "RC_INTERNAL_NAME=\"${name}\"" |
||
| 438 | "RC_PRODUCT_NAME=\"${ARG_PRODUCT_NAME}\"" |
||
| 439 | "RC_PRODUCT_VERSION=\"${ARG_VERSION_STRING}\"") |
||
| 440 | endfunction(set_windows_version_resource_properties) |
||
| 441 | |||
| 442 | # llvm_add_library(name sources... |
||
| 443 | # SHARED;STATIC |
||
| 444 | # STATIC by default w/o BUILD_SHARED_LIBS. |
||
| 445 | # SHARED by default w/ BUILD_SHARED_LIBS. |
||
| 446 | # OBJECT |
||
| 447 | # Also create an OBJECT library target. Default if STATIC && SHARED. |
||
| 448 | # MODULE |
||
| 449 | # Target ${name} might not be created on unsupported platforms. |
||
| 450 | # Check with "if(TARGET ${name})". |
||
| 451 | # DISABLE_LLVM_LINK_LLVM_DYLIB |
||
| 452 | # Do not link this library to libLLVM, even if |
||
| 453 | # LLVM_LINK_LLVM_DYLIB is enabled. |
||
| 454 | # OUTPUT_NAME name |
||
| 455 | # Corresponds to OUTPUT_NAME in target properties. |
||
| 456 | # DEPENDS targets... |
||
| 457 | # Same semantics as add_dependencies(). |
||
| 458 | # LINK_COMPONENTS components... |
||
| 459 | # Same as the variable LLVM_LINK_COMPONENTS. |
||
| 460 | # LINK_LIBS lib_targets... |
||
| 461 | # Same semantics as target_link_libraries(). |
||
| 462 | # ADDITIONAL_HEADERS |
||
| 463 | # May specify header files for IDE generators. |
||
| 464 | # SONAME |
||
| 465 | # Should set SONAME link flags and create symlinks |
||
| 466 | # NO_INSTALL_RPATH |
||
| 467 | # Suppress default RPATH settings in shared libraries. |
||
| 468 | # PLUGIN_TOOL |
||
| 469 | # The tool (i.e. cmake target) that this plugin will link against |
||
| 470 | # COMPONENT_LIB |
||
| 471 | # This is used to specify that this is a component library of |
||
| 472 | # LLVM which means that the source resides in llvm/lib/ and it is a |
||
| 473 | # candidate for inclusion into libLLVM.so. |
||
| 474 | # ) |
||
| 475 | function(llvm_add_library name) |
||
| 476 | cmake_parse_arguments(ARG |
||
| 477 | "MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB" |
||
| 478 | "OUTPUT_NAME;PLUGIN_TOOL;ENTITLEMENTS;BUNDLE_PATH" |
||
| 479 | "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS" |
||
| 480 | ${ARGN}) |
||
| 481 | list(APPEND LLVM_COMMON_DEPENDS ${ARG_DEPENDS}) |
||
| 482 | if(ARG_ADDITIONAL_HEADERS) |
||
| 483 | # Pass through ADDITIONAL_HEADERS. |
||
| 484 | set(ARG_ADDITIONAL_HEADERS ADDITIONAL_HEADERS ${ARG_ADDITIONAL_HEADERS}) |
||
| 485 | endif() |
||
| 486 | if(ARG_OBJLIBS) |
||
| 487 | set(ALL_FILES ${ARG_OBJLIBS}) |
||
| 488 | else() |
||
| 489 | llvm_process_sources(ALL_FILES ${ARG_UNPARSED_ARGUMENTS} ${ARG_ADDITIONAL_HEADERS}) |
||
| 490 | endif() |
||
| 491 | |||
| 492 | if(ARG_MODULE) |
||
| 493 | if(ARG_SHARED OR ARG_STATIC) |
||
| 494 | message(WARNING "MODULE with SHARED|STATIC doesn't make sense.") |
||
| 495 | endif() |
||
| 496 | # Plugins that link against a tool are allowed even when plugins in general are not |
||
| 497 | if(NOT LLVM_ENABLE_PLUGINS AND NOT (ARG_PLUGIN_TOOL AND LLVM_EXPORT_SYMBOLS_FOR_PLUGINS)) |
||
| 498 | message(STATUS "${name} ignored -- Loadable modules not supported on this platform.") |
||
| 499 | return() |
||
| 500 | endif() |
||
| 501 | else() |
||
| 502 | if(ARG_PLUGIN_TOOL) |
||
| 503 | message(WARNING "PLUGIN_TOOL without MODULE doesn't make sense.") |
||
| 504 | endif() |
||
| 505 | if(BUILD_SHARED_LIBS AND NOT ARG_STATIC) |
||
| 506 | set(ARG_SHARED TRUE) |
||
| 507 | endif() |
||
| 508 | if(NOT ARG_SHARED) |
||
| 509 | set(ARG_STATIC TRUE) |
||
| 510 | endif() |
||
| 511 | endif() |
||
| 512 | |||
| 513 | # Generate objlib |
||
| 514 | if((ARG_SHARED AND ARG_STATIC) OR ARG_OBJECT) |
||
| 515 | # Generate an obj library for both targets. |
||
| 516 | set(obj_name "obj.${name}") |
||
| 517 | add_library(${obj_name} OBJECT EXCLUDE_FROM_ALL |
||
| 518 | ${ALL_FILES} |
||
| 519 | ) |
||
| 520 | llvm_update_compile_flags(${obj_name}) |
||
| 521 | if(CMAKE_GENERATOR STREQUAL "Xcode") |
||
| 522 | set(DUMMY_FILE ${CMAKE_CURRENT_BINARY_DIR}/Dummy.c) |
||
| 523 | file(WRITE ${DUMMY_FILE} "// This file intentionally empty\n") |
||
| 524 | set_property(SOURCE ${DUMMY_FILE} APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-empty-translation-unit") |
||
| 525 | endif() |
||
| 526 | set(ALL_FILES "$<TARGET_OBJECTS:${obj_name}>" ${DUMMY_FILE}) |
||
| 527 | |||
| 528 | # Do add_dependencies(obj) later due to CMake issue 14747. |
||
| 529 | list(APPEND objlibs ${obj_name}) |
||
| 530 | |||
| 531 | # Bring in the target include directories from our original target. |
||
| 532 | target_include_directories(${obj_name} PRIVATE $<TARGET_PROPERTY:${name},INCLUDE_DIRECTORIES>) |
||
| 533 | |||
| 534 | set_target_properties(${obj_name} PROPERTIES FOLDER "Object Libraries") |
||
| 535 | if(ARG_DEPENDS) |
||
| 536 | add_dependencies(${obj_name} ${ARG_DEPENDS}) |
||
| 537 | endif() |
||
| 538 | # Treat link libraries like PUBLIC dependencies. LINK_LIBS might |
||
| 539 | # result in generating header files. Add a dependendency so that |
||
| 540 | # the generated header is created before this object library. |
||
| 541 | if(ARG_LINK_LIBS) |
||
| 542 | cmake_parse_arguments(LINK_LIBS_ARG |
||
| 543 | "" |
||
| 544 | "" |
||
| 545 | "PUBLIC;PRIVATE" |
||
| 546 | ${ARG_LINK_LIBS}) |
||
| 547 | foreach(link_lib ${LINK_LIBS_ARG_PUBLIC}) |
||
| 548 | if(LLVM_PTHREAD_LIB) |
||
| 549 | # Can't specify a dependence on -lpthread |
||
| 550 | if(NOT ${link_lib} STREQUAL ${LLVM_PTHREAD_LIB}) |
||
| 551 | add_dependencies(${obj_name} ${link_lib}) |
||
| 552 | endif() |
||
| 553 | else() |
||
| 554 | add_dependencies(${obj_name} ${link_lib}) |
||
| 555 | endif() |
||
| 556 | endforeach() |
||
| 557 | endif() |
||
| 558 | endif() |
||
| 559 | |||
| 560 | if(ARG_SHARED AND ARG_STATIC) |
||
| 561 | # static |
||
| 562 | set(name_static "${name}_static") |
||
| 563 | if(ARG_OUTPUT_NAME) |
||
| 564 | set(output_name OUTPUT_NAME "${ARG_OUTPUT_NAME}") |
||
| 565 | endif() |
||
| 566 | # DEPENDS has been appended to LLVM_COMMON_LIBS. |
||
| 567 | llvm_add_library(${name_static} STATIC |
||
| 568 | ${output_name} |
||
| 569 | OBJLIBS ${ALL_FILES} # objlib |
||
| 570 | LINK_LIBS ${ARG_LINK_LIBS} |
||
| 571 | LINK_COMPONENTS ${ARG_LINK_COMPONENTS} |
||
| 572 | ) |
||
| 573 | |||
| 574 | # Bring in the target link info from our original target. |
||
| 575 | target_link_directories(${name_static} PRIVATE $<TARGET_PROPERTY:${name},LINK_DIRECTORIES>) |
||
| 576 | target_link_libraries(${name_static} PRIVATE $<TARGET_PROPERTY:${name},LINK_LIBRARIES>) |
||
| 577 | |||
| 578 | # FIXME: Add name_static to anywhere in TARGET ${name}'s PROPERTY. |
||
| 579 | set(ARG_STATIC) |
||
| 580 | endif() |
||
| 581 | |||
| 582 | if(ARG_MODULE) |
||
| 583 | add_library(${name} MODULE ${ALL_FILES}) |
||
| 584 | elseif(ARG_SHARED) |
||
| 585 | add_windows_version_resource_file(ALL_FILES ${ALL_FILES}) |
||
| 586 | add_library(${name} SHARED ${ALL_FILES}) |
||
| 587 | else() |
||
| 588 | add_library(${name} STATIC ${ALL_FILES}) |
||
| 589 | endif() |
||
| 590 | |||
| 591 | if(ARG_COMPONENT_LIB) |
||
| 592 | set_target_properties(${name} PROPERTIES LLVM_COMPONENT TRUE) |
||
| 593 | set_property(GLOBAL APPEND PROPERTY LLVM_COMPONENT_LIBS ${name}) |
||
| 594 | endif() |
||
| 595 | |||
| 596 | if(NOT ARG_NO_INSTALL_RPATH) |
||
| 597 | if(ARG_MODULE OR ARG_SHARED) |
||
| 598 | llvm_setup_rpath(${name}) |
||
| 599 | endif() |
||
| 600 | endif() |
||
| 601 | |||
| 602 | setup_dependency_debugging(${name} ${LLVM_COMMON_DEPENDS}) |
||
| 603 | |||
| 604 | if(DEFINED windows_resource_file) |
||
| 605 | set_windows_version_resource_properties(${name} ${windows_resource_file}) |
||
| 606 | set(windows_resource_file ${windows_resource_file} PARENT_SCOPE) |
||
| 607 | endif() |
||
| 608 | |||
| 609 | set_output_directory(${name} BINARY_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR} LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) |
||
| 610 | # $<TARGET_OBJECTS> doesn't require compile flags. |
||
| 611 | if(NOT obj_name) |
||
| 612 | llvm_update_compile_flags(${name}) |
||
| 613 | endif() |
||
| 614 | add_link_opts( ${name} ) |
||
| 615 | if(ARG_OUTPUT_NAME) |
||
| 616 | set_target_properties(${name} |
||
| 617 | PROPERTIES |
||
| 618 | OUTPUT_NAME ${ARG_OUTPUT_NAME} |
||
| 619 | ) |
||
| 620 | endif() |
||
| 621 | |||
| 622 | if(ARG_MODULE) |
||
| 623 | set_target_properties(${name} PROPERTIES |
||
| 624 | PREFIX "" |
||
| 625 | SUFFIX ${LLVM_PLUGIN_EXT} |
||
| 626 | ) |
||
| 627 | endif() |
||
| 628 | |||
| 629 | if(ARG_SHARED) |
||
| 630 | if(MSVC) |
||
| 631 | set_target_properties(${name} PROPERTIES |
||
| 632 | PREFIX "" |
||
| 633 | ) |
||
| 634 | endif() |
||
| 635 | |||
| 636 | # Set SOVERSION on shared libraries that lack explicit SONAME |
||
| 637 | # specifier, on *nix systems that are not Darwin. |
||
| 638 | if(UNIX AND NOT APPLE AND NOT ARG_SONAME) |
||
| 639 | set_target_properties(${name} |
||
| 640 | PROPERTIES |
||
| 641 | # Since 4.0.0, the ABI version is indicated by the major version |
||
| 642 | SOVERSION ${LLVM_VERSION_MAJOR}${LLVM_VERSION_SUFFIX} |
||
| 643 | VERSION ${LLVM_VERSION_MAJOR}${LLVM_VERSION_SUFFIX}) |
||
| 644 | endif() |
||
| 645 | endif() |
||
| 646 | |||
| 647 | if(ARG_MODULE OR ARG_SHARED) |
||
| 648 | # Do not add -Dname_EXPORTS to the command-line when building files in this |
||
| 649 | # target. Doing so is actively harmful for the modules build because it |
||
| 650 | # creates extra module variants, and not useful because we don't use these |
||
| 651 | # macros. |
||
| 652 | set_target_properties( ${name} PROPERTIES DEFINE_SYMBOL "" ) |
||
| 653 | |||
| 654 | if (LLVM_EXPORTED_SYMBOL_FILE) |
||
| 655 | add_llvm_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} ) |
||
| 656 | endif() |
||
| 657 | endif() |
||
| 658 | |||
| 659 | if(ARG_SHARED) |
||
| 660 | if(NOT APPLE AND ARG_SONAME) |
||
| 661 | get_target_property(output_name ${name} OUTPUT_NAME) |
||
| 662 | if(${output_name} STREQUAL "output_name-NOTFOUND") |
||
| 663 | set(output_name ${name}) |
||
| 664 | endif() |
||
| 665 | set(library_name ${output_name}-${LLVM_VERSION_MAJOR}${LLVM_VERSION_SUFFIX}) |
||
| 666 | set(api_name ${output_name}-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}${LLVM_VERSION_SUFFIX}) |
||
| 667 | set_target_properties(${name} PROPERTIES OUTPUT_NAME ${library_name}) |
||
| 668 | if(UNIX) |
||
| 669 | llvm_install_library_symlink(${api_name} ${library_name} SHARED |
||
| 670 | COMPONENT ${name}) |
||
| 671 | llvm_install_library_symlink(${output_name} ${library_name} SHARED |
||
| 672 | COMPONENT ${name}) |
||
| 673 | endif() |
||
| 674 | endif() |
||
| 675 | endif() |
||
| 676 | |||
| 677 | if(ARG_STATIC) |
||
| 678 | set(libtype PUBLIC) |
||
| 679 | else() |
||
| 680 | # We can use PRIVATE since SO knows its dependent libs. |
||
| 681 | set(libtype PRIVATE) |
||
| 682 | endif() |
||
| 683 | |||
| 684 | if(ARG_MODULE AND LLVM_EXPORT_SYMBOLS_FOR_PLUGINS AND ARG_PLUGIN_TOOL AND (WIN32 OR CYGWIN)) |
||
| 685 | # On DLL platforms symbols are imported from the tool by linking against it. |
||
| 686 | set(llvm_libs ${ARG_PLUGIN_TOOL}) |
||
| 687 | elseif (NOT ARG_COMPONENT_LIB) |
||
| 688 | if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB) |
||
| 689 | set(llvm_libs LLVM) |
||
| 690 | else() |
||
| 691 | llvm_map_components_to_libnames(llvm_libs |
||
| 692 | ${ARG_LINK_COMPONENTS} |
||
| 693 | ${LLVM_LINK_COMPONENTS} |
||
| 694 | ) |
||
| 695 | endif() |
||
| 696 | else() |
||
| 697 | # Components have not been defined explicitly in CMake, so add the |
||
| 698 | # dependency information for this library through their name, and let |
||
| 699 | # LLVMBuildResolveComponentsLink resolve the mapping. |
||
| 700 | # |
||
| 701 | # It would be nice to verify that we have the dependencies for this library |
||
| 702 | # name, but using get_property(... SET) doesn't suffice to determine if a |
||
| 703 | # property has been set to an empty value. |
||
| 704 | set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS} ${LLVM_LINK_COMPONENTS}) |
||
| 705 | |||
| 706 | # This property is an internal property only used to make sure the |
||
| 707 | # link step applied in LLVMBuildResolveComponentsLink uses the same |
||
| 708 | # property as the target_link_libraries call below. |
||
| 709 | set_property(TARGET ${name} PROPERTY LLVM_LIBTYPE ${libtype}) |
||
| 710 | endif() |
||
| 711 | |||
| 712 | target_link_libraries(${name} ${libtype} |
||
| 713 | ${ARG_LINK_LIBS} |
||
| 714 | ${lib_deps} |
||
| 715 | ${llvm_libs} |
||
| 716 | ) |
||
| 717 | |||
| 718 | if(LLVM_COMMON_DEPENDS) |
||
| 719 | add_dependencies(${name} ${LLVM_COMMON_DEPENDS}) |
||
| 720 | # Add dependencies also to objlibs. |
||
| 721 | # CMake issue 14747 -- add_dependencies() might be ignored to objlib's user. |
||
| 722 | foreach(objlib ${objlibs}) |
||
| 723 | add_dependencies(${objlib} ${LLVM_COMMON_DEPENDS}) |
||
| 724 | endforeach() |
||
| 725 | endif() |
||
| 726 | |||
| 727 | if(ARG_SHARED OR ARG_MODULE) |
||
| 728 | llvm_externalize_debuginfo(${name}) |
||
| 729 | llvm_codesign(${name} ENTITLEMENTS ${ARG_ENTITLEMENTS} BUNDLE_PATH ${ARG_BUNDLE_PATH}) |
||
| 730 | endif() |
||
| 731 | # clang and newer versions of ninja use high-resolutions timestamps, |
||
| 732 | # but older versions of libtool on Darwin don't, so the archive will |
||
| 733 | # often get an older timestamp than the last object that was added |
||
| 734 | # or updated. To fix this, we add a custom command to touch archive |
||
| 735 | # after it's been built so that ninja won't rebuild it unnecessarily |
||
| 736 | # the next time it's run. |
||
| 737 | if(ARG_STATIC AND LLVM_TOUCH_STATIC_LIBRARIES) |
||
| 738 | add_custom_command(TARGET ${name} |
||
| 739 | POST_BUILD |
||
| 740 | COMMAND touch ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${name}${CMAKE_STATIC_LIBRARY_SUFFIX} |
||
| 741 | ) |
||
| 742 | endif() |
||
| 743 | endfunction() |
||
| 744 | |||
| 745 | function(add_llvm_install_targets target) |
||
| 746 | cmake_parse_arguments(ARG "" "COMPONENT;PREFIX;SYMLINK" "DEPENDS" ${ARGN}) |
||
| 747 | if(ARG_COMPONENT) |
||
| 748 | set(component_option -DCMAKE_INSTALL_COMPONENT="${ARG_COMPONENT}") |
||
| 749 | endif() |
||
| 750 | if(ARG_PREFIX) |
||
| 751 | set(prefix_option -DCMAKE_INSTALL_PREFIX="${ARG_PREFIX}") |
||
| 752 | endif() |
||
| 753 | |||
| 754 | set(file_dependencies) |
||
| 755 | set(target_dependencies) |
||
| 756 | foreach(dependency ${ARG_DEPENDS}) |
||
| 757 | if(TARGET ${dependency}) |
||
| 758 | list(APPEND target_dependencies ${dependency}) |
||
| 759 | else() |
||
| 760 | list(APPEND file_dependencies ${dependency}) |
||
| 761 | endif() |
||
| 762 | endforeach() |
||
| 763 | |||
| 764 | add_custom_target(${target} |
||
| 765 | DEPENDS ${file_dependencies} |
||
| 766 | COMMAND "${CMAKE_COMMAND}" |
||
| 767 | ${component_option} |
||
| 768 | ${prefix_option} |
||
| 769 | -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" |
||
| 770 | USES_TERMINAL) |
||
| 771 | set_target_properties(${target} PROPERTIES FOLDER "Component Install Targets") |
||
| 772 | add_custom_target(${target}-stripped |
||
| 773 | DEPENDS ${file_dependencies} |
||
| 774 | COMMAND "${CMAKE_COMMAND}" |
||
| 775 | ${component_option} |
||
| 776 | ${prefix_option} |
||
| 777 | -DCMAKE_INSTALL_DO_STRIP=1 |
||
| 778 | -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" |
||
| 779 | USES_TERMINAL) |
||
| 780 | set_target_properties(${target}-stripped PROPERTIES FOLDER "Component Install Targets (Stripped)") |
||
| 781 | if(target_dependencies) |
||
| 782 | add_dependencies(${target} ${target_dependencies}) |
||
| 783 | add_dependencies(${target}-stripped ${target_dependencies}) |
||
| 784 | endif() |
||
| 785 | |||
| 786 | if(ARG_SYMLINK) |
||
| 787 | add_dependencies(${target} install-${ARG_SYMLINK}) |
||
| 788 | add_dependencies(${target}-stripped install-${ARG_SYMLINK}-stripped) |
||
| 789 | endif() |
||
| 790 | endfunction() |
||
| 791 | |||
| 792 | # Define special targets that behave like a component group. They don't have any |
||
| 793 | # source attached but other components can add themselves to them. If the |
||
| 794 | # component supports is a Target and it supports JIT compilation, HAS_JIT must |
||
| 795 | # be passed. One can use ADD_TO_COMPONENT option from add_llvm_component_library |
||
| 796 | # to link extra component into an existing group. |
||
| 797 | function(add_llvm_component_group name) |
||
| 798 | cmake_parse_arguments(ARG "HAS_JIT" "" "LINK_COMPONENTS" ${ARGN}) |
||
| 799 | add_custom_target(${name}) |
||
| 800 | if(ARG_HAS_JIT) |
||
| 801 | set_property(TARGET ${name} PROPERTY COMPONENT_HAS_JIT ON) |
||
| 802 | endif() |
||
| 803 | if(ARG_LINK_COMPONENTS) |
||
| 804 | set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS}) |
||
| 805 | endif() |
||
| 806 | endfunction() |
||
| 807 | |||
| 808 | # An LLVM component is a cmake target with the following cmake properties |
||
| 809 | # eventually set: |
||
| 810 | # - LLVM_COMPONENT_NAME: the name of the component, which can be the name of |
||
| 811 | # the associated library or the one specified through COMPONENT_NAME |
||
| 812 | # - LLVM_LINK_COMPONENTS: a list of component this component depends on |
||
| 813 | # - COMPONENT_HAS_JIT: (only for group component) whether this target group |
||
| 814 | # supports JIT compilation |
||
| 815 | # Additionnaly, the ADD_TO_COMPONENT <component> option make it possible to add this |
||
| 816 | # component to the LLVM_LINK_COMPONENTS of <component>. |
||
| 817 | function(add_llvm_component_library name) |
||
| 818 | cmake_parse_arguments(ARG |
||
| 819 | "" |
||
| 820 | "COMPONENT_NAME;ADD_TO_COMPONENT" |
||
| 821 | "" |
||
| 822 | ${ARGN}) |
||
| 823 | add_llvm_library(${name} COMPONENT_LIB ${ARG_UNPARSED_ARGUMENTS}) |
||
| 824 | string(REGEX REPLACE "^LLVM" "" component_name ${name}) |
||
| 825 | set_property(TARGET ${name} PROPERTY LLVM_COMPONENT_NAME ${component_name}) |
||
| 826 | |||
| 827 | if(ARG_COMPONENT_NAME) |
||
| 828 | set_property(GLOBAL PROPERTY LLVM_COMPONENT_NAME_${ARG_COMPONENT_NAME} ${component_name}) |
||
| 829 | endif() |
||
| 830 | |||
| 831 | if(ARG_ADD_TO_COMPONENT) |
||
| 832 | set_property(TARGET ${ARG_ADD_TO_COMPONENT} APPEND PROPERTY LLVM_LINK_COMPONENTS ${component_name}) |
||
| 833 | endif() |
||
| 834 | |||
| 835 | endfunction() |
||
| 836 | |||
| 837 | macro(add_llvm_library name) |
||
| 838 | cmake_parse_arguments(ARG |
||
| 839 | "SHARED;BUILDTREE_ONLY;MODULE;INSTALL_WITH_TOOLCHAIN" |
||
| 840 | "" |
||
| 841 | "" |
||
| 842 | ${ARGN}) |
||
| 843 | if(ARG_MODULE) |
||
| 844 | llvm_add_library(${name} MODULE ${ARG_UNPARSED_ARGUMENTS}) |
||
| 845 | elseif( BUILD_SHARED_LIBS OR ARG_SHARED ) |
||
| 846 | llvm_add_library(${name} SHARED ${ARG_UNPARSED_ARGUMENTS}) |
||
| 847 | else() |
||
| 848 | llvm_add_library(${name} ${ARG_UNPARSED_ARGUMENTS}) |
||
| 849 | endif() |
||
| 850 | |||
| 851 | # Libraries that are meant to only be exposed via the build tree only are |
||
| 852 | # never installed and are only exported as a target in the special build tree |
||
| 853 | # config file. |
||
| 854 | if (NOT ARG_BUILDTREE_ONLY AND NOT ARG_MODULE) |
||
| 855 | set_property( GLOBAL APPEND PROPERTY LLVM_LIBS ${name} ) |
||
| 856 | set(in_llvm_libs YES) |
||
| 857 | endif() |
||
| 858 | |||
| 859 | if (ARG_MODULE AND NOT TARGET ${name}) |
||
| 860 | # Add empty "phony" target |
||
| 861 | add_custom_target(${name}) |
||
| 862 | elseif( EXCLUDE_FROM_ALL ) |
||
| 863 | set_target_properties( ${name} PROPERTIES EXCLUDE_FROM_ALL ON) |
||
| 864 | elseif(ARG_BUILDTREE_ONLY) |
||
| 865 | set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS_BUILDTREE_ONLY ${name}) |
||
| 866 | else() |
||
| 867 | if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ARG_INSTALL_WITH_TOOLCHAIN) |
||
| 868 | if(in_llvm_libs) |
||
| 869 | set(umbrella UMBRELLA llvm-libraries) |
||
| 870 | else() |
||
| 871 | set(umbrella) |
||
| 872 | endif() |
||
| 873 | |||
| 874 | get_target_export_arg(${name} LLVM export_to_llvmexports ${umbrella}) |
||
| 875 | install(TARGETS ${name} |
||
| 876 | ${export_to_llvmexports} |
||
| 877 | LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name} |
||
| 878 | ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name} |
||
| 879 | RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT ${name}) |
||
| 880 | |||
| 881 | if (NOT LLVM_ENABLE_IDE) |
||
| 882 | add_llvm_install_targets(install-${name} |
||
| 883 | DEPENDS ${name} |
||
| 884 | COMPONENT ${name}) |
||
| 885 | endif() |
||
| 886 | endif() |
||
| 887 | set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name}) |
||
| 888 | endif() |
||
| 889 | if (ARG_MODULE) |
||
| 890 | set_target_properties(${name} PROPERTIES FOLDER "Loadable modules") |
||
| 891 | else() |
||
| 892 | set_target_properties(${name} PROPERTIES FOLDER "Libraries") |
||
| 893 | endif() |
||
| 894 | endmacro(add_llvm_library name) |
||
| 895 | |||
| 896 | macro(generate_llvm_objects name) |
||
| 897 | cmake_parse_arguments(ARG "GENERATE_DRIVER" "" "DEPENDS" ${ARGN}) |
||
| 898 | |||
| 899 | llvm_process_sources( ALL_FILES ${ARG_UNPARSED_ARGUMENTS} ) |
||
| 900 | |||
| 901 | list(APPEND LLVM_COMMON_DEPENDS ${ARG_DEPENDS}) |
||
| 902 | |||
| 903 | # Generate objlib |
||
| 904 | if(LLVM_ENABLE_OBJLIB OR (ARG_GENERATE_DRIVER AND LLVM_TOOL_LLVM_DRIVER_BUILD)) |
||
| 905 | # Generate an obj library for both targets. |
||
| 906 | set(obj_name "obj.${name}") |
||
| 907 | add_library(${obj_name} OBJECT EXCLUDE_FROM_ALL |
||
| 908 | ${ALL_FILES} |
||
| 909 | ) |
||
| 910 | llvm_update_compile_flags(${obj_name}) |
||
| 911 | set(ALL_FILES "$<TARGET_OBJECTS:${obj_name}>") |
||
| 912 | if(ARG_DEPENDS) |
||
| 913 | add_dependencies(${obj_name} ${ARG_DEPENDS}) |
||
| 914 | endif() |
||
| 915 | |||
| 916 | set_target_properties(${obj_name} PROPERTIES FOLDER "Object Libraries") |
||
| 917 | endif() |
||
| 918 | |||
| 919 | if (ARG_GENERATE_DRIVER) |
||
| 920 | string(REPLACE "-" "_" TOOL_NAME ${name}) |
||
| 921 | foreach(path ${CMAKE_MODULE_PATH}) |
||
| 922 | if(EXISTS ${path}/llvm-driver-template.cpp.in) |
||
| 923 | configure_file( |
||
| 924 | ${path}/llvm-driver-template.cpp.in |
||
| 925 | ${CMAKE_CURRENT_BINARY_DIR}/${name}-driver.cpp) |
||
| 926 | break() |
||
| 927 | endif() |
||
| 928 | endforeach() |
||
| 929 | |||
| 930 | list(APPEND ALL_FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}-driver.cpp) |
||
| 931 | |||
| 932 | if (LLVM_TOOL_LLVM_DRIVER_BUILD |
||
| 933 | AND (NOT LLVM_DISTRIBUTION_COMPONENTS OR ${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS) |
||
| 934 | ) |
||
| 935 | set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_COMPONENTS ${LLVM_LINK_COMPONENTS}) |
||
| 936 | set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_DEPS ${ARG_DEPENDS} ${LLVM_COMMON_DEPENDS}) |
||
| 937 | set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_OBJLIBS "${obj_name}") |
||
| 938 | |||
| 939 | set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_TOOLS ${name}) |
||
| 940 | set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_TOOL_ALIASES_${name} ${name}) |
||
| 941 | target_link_libraries(${obj_name} ${LLVM_PTHREAD_LIB}) |
||
| 942 | llvm_config(${obj_name} ${USE_SHARED} ${LLVM_LINK_COMPONENTS} ) |
||
| 943 | endif() |
||
| 944 | endif() |
||
| 945 | endmacro() |
||
| 946 | |||
| 947 | macro(add_llvm_executable name) |
||
| 948 | cmake_parse_arguments(ARG |
||
| 949 | "DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS" |
||
| 950 | "ENTITLEMENTS;BUNDLE_PATH" |
||
| 951 | "" |
||
| 952 | ${ARGN}) |
||
| 953 | generate_llvm_objects(${name} ${ARG_UNPARSED_ARGUMENTS}) |
||
| 954 | add_windows_version_resource_file(ALL_FILES ${ALL_FILES}) |
||
| 955 | |||
| 956 | if(XCODE) |
||
| 957 | # Note: the dummy.cpp source file provides no definitions. However, |
||
| 958 | # it forces Xcode to properly link the static library. |
||
| 959 | list(APPEND ALL_FILES "${LLVM_MAIN_SRC_DIR}/cmake/dummy.cpp") |
||
| 960 | endif() |
||
| 961 | |||
| 962 | if( EXCLUDE_FROM_ALL ) |
||
| 963 | add_executable(${name} EXCLUDE_FROM_ALL ${ALL_FILES}) |
||
| 964 | else() |
||
| 965 | add_executable(${name} ${ALL_FILES}) |
||
| 966 | endif() |
||
| 967 | |||
| 968 | setup_dependency_debugging(${name} ${LLVM_COMMON_DEPENDS}) |
||
| 969 | |||
| 970 | if(NOT ARG_NO_INSTALL_RPATH) |
||
| 971 | llvm_setup_rpath(${name}) |
||
| 972 | elseif(NOT "${LLVM_LOCAL_RPATH}" STREQUAL "") |
||
| 973 | # Enable BUILD_WITH_INSTALL_RPATH unless CMAKE_BUILD_RPATH is set. |
||
| 974 | if("${CMAKE_BUILD_RPATH}" STREQUAL "") |
||
| 975 | set_property(TARGET ${name} PROPERTY BUILD_WITH_INSTALL_RPATH ON) |
||
| 976 | endif() |
||
| 977 | |||
| 978 | set_property(TARGET ${name} PROPERTY INSTALL_RPATH "${LLVM_LOCAL_RPATH}") |
||
| 979 | endif() |
||
| 980 | |||
| 981 | if(DEFINED windows_resource_file) |
||
| 982 | set_windows_version_resource_properties(${name} ${windows_resource_file}) |
||
| 983 | endif() |
||
| 984 | |||
| 985 | # $<TARGET_OBJECTS> doesn't require compile flags. |
||
| 986 | if(NOT LLVM_ENABLE_OBJLIB) |
||
| 987 | llvm_update_compile_flags(${name}) |
||
| 988 | endif() |
||
| 989 | |||
| 990 | if (ARG_SUPPORT_PLUGINS AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "AIX") |
||
| 991 | set(LLVM_NO_DEAD_STRIP On) |
||
| 992 | endif() |
||
| 993 | |||
| 994 | add_link_opts( ${name} ) |
||
| 995 | |||
| 996 | # Do not add -Dname_EXPORTS to the command-line when building files in this |
||
| 997 | # target. Doing so is actively harmful for the modules build because it |
||
| 998 | # creates extra module variants, and not useful because we don't use these |
||
| 999 | # macros. |
||
| 1000 | set_target_properties( ${name} PROPERTIES DEFINE_SYMBOL "" ) |
||
| 1001 | |||
| 1002 | if (LLVM_EXPORTED_SYMBOL_FILE) |
||
| 1003 | add_llvm_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} ) |
||
| 1004 | endif(LLVM_EXPORTED_SYMBOL_FILE) |
||
| 1005 | |||
| 1006 | if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB) |
||
| 1007 | set(USE_SHARED USE_SHARED) |
||
| 1008 | endif() |
||
| 1009 | |||
| 1010 | set(EXCLUDE_FROM_ALL OFF) |
||
| 1011 | set_output_directory(${name} BINARY_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR} LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) |
||
| 1012 | llvm_config( ${name} ${USE_SHARED} ${LLVM_LINK_COMPONENTS} ) |
||
| 1013 | if( LLVM_COMMON_DEPENDS ) |
||
| 1014 | add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} ) |
||
| 1015 | foreach(objlib ${obj_name}) |
||
| 1016 | add_dependencies(${objlib} ${LLVM_COMMON_DEPENDS}) |
||
| 1017 | endforeach() |
||
| 1018 | endif( LLVM_COMMON_DEPENDS ) |
||
| 1019 | |||
| 1020 | if(NOT ARG_IGNORE_EXTERNALIZE_DEBUGINFO) |
||
| 1021 | llvm_externalize_debuginfo(${name}) |
||
| 1022 | endif() |
||
| 1023 | if (LLVM_PTHREAD_LIB) |
||
| 1024 | # libpthreads overrides some standard library symbols, so main |
||
| 1025 | # executable must be linked with it in order to provide consistent |
||
| 1026 | # API for all shared libaries loaded by this executable. |
||
| 1027 | target_link_libraries(${name} PRIVATE ${LLVM_PTHREAD_LIB}) |
||
| 1028 | endif() |
||
| 1029 | |||
| 1030 | llvm_codesign(${name} ENTITLEMENTS ${ARG_ENTITLEMENTS} BUNDLE_PATH ${ARG_BUNDLE_PATH}) |
||
| 1031 | endmacro(add_llvm_executable name) |
||
| 1032 | |||
| 1033 | # add_llvm_pass_plugin(name [NO_MODULE] ...) |
||
| 1034 | # Add ${name} as an llvm plugin. |
||
| 1035 | # If option LLVM_${name_upper}_LINK_INTO_TOOLS is set to ON, the plugin is registered statically. |
||
| 1036 | # Otherwise a pluggable shared library is registered. |
||
| 1037 | # |
||
| 1038 | # If NO_MODULE is specified, when option LLVM_${name_upper}_LINK_INTO_TOOLS is set to OFF, |
||
| 1039 | # only an object library is built, and no module is built. This is specific to the Polly use case. |
||
| 1040 | # |
||
| 1041 | # The SUBPROJECT argument contains the LLVM project the plugin belongs |
||
| 1042 | # to. If set, the plugin will link statically by default it if the |
||
| 1043 | # project was enabled. |
||
| 1044 | function(add_llvm_pass_plugin name) |
||
| 1045 | cmake_parse_arguments(ARG |
||
| 1046 | "NO_MODULE" "SUBPROJECT" "" |
||
| 1047 | ${ARGN}) |
||
| 1048 | |||
| 1049 | string(TOUPPER ${name} name_upper) |
||
| 1050 | |||
| 1051 | # Enable the plugin by default if it was explicitly enabled by the user. |
||
| 1052 | # Note: If was set to "all", LLVM's CMakeLists.txt replaces it with a |
||
| 1053 | # list of all projects, counting as explicitly enabled. |
||
| 1054 | set(link_into_tools_default OFF) |
||
| 1055 | if (ARG_SUBPROJECT AND LLVM_TOOL_${name_upper}_BUILD) |
||
| 1056 | set(link_into_tools_default ON) |
||
| 1057 | endif() |
||
| 1058 | option(LLVM_${name_upper}_LINK_INTO_TOOLS "Statically link ${name} into tools (if available)" ${link_into_tools_default}) |
||
| 1059 | |||
| 1060 | # If we statically link the plugin, don't use llvm dylib because we're going |
||
| 1061 | # to be part of it. |
||
| 1062 | if(LLVM_${name_upper}_LINK_INTO_TOOLS) |
||
| 1063 | list(APPEND ARG_UNPARSED_ARGUMENTS DISABLE_LLVM_LINK_LLVM_DYLIB) |
||
| 1064 | endif() |
||
| 1065 | |||
| 1066 | if(LLVM_${name_upper}_LINK_INTO_TOOLS) |
||
| 1067 | list(REMOVE_ITEM ARG_UNPARSED_ARGUMENTS BUILDTREE_ONLY) |
||
| 1068 | # process_llvm_pass_plugins takes care of the actual linking, just create an |
||
| 1069 | # object library as of now |
||
| 1070 | add_llvm_library(${name} OBJECT ${ARG_UNPARSED_ARGUMENTS}) |
||
| 1071 | target_compile_definitions(${name} PRIVATE LLVM_${name_upper}_LINK_INTO_TOOLS) |
||
| 1072 | set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS LLVM_LINK_INTO_TOOLS) |
||
| 1073 | if (TARGET intrinsics_gen) |
||
| 1074 | add_dependencies(obj.${name} intrinsics_gen) |
||
| 1075 | endif() |
||
| 1076 | if (TARGET omp_gen) |
||
| 1077 | add_dependencies(obj.${name} omp_gen) |
||
| 1078 | endif() |
||
| 1079 | if (TARGET acc_gen) |
||
| 1080 | add_dependencies(obj.${name} acc_gen) |
||
| 1081 | endif() |
||
| 1082 | set_property(GLOBAL APPEND PROPERTY LLVM_STATIC_EXTENSIONS ${name}) |
||
| 1083 | elseif(NOT ARG_NO_MODULE) |
||
| 1084 | add_llvm_library(${name} MODULE ${ARG_UNPARSED_ARGUMENTS}) |
||
| 1085 | else() |
||
| 1086 | add_llvm_library(${name} OBJECT ${ARG_UNPARSED_ARGUMENTS}) |
||
| 1087 | endif() |
||
| 1088 | message(STATUS "Registering ${name} as a pass plugin (static build: ${LLVM_${name_upper}_LINK_INTO_TOOLS})") |
||
| 1089 | |||
| 1090 | endfunction(add_llvm_pass_plugin) |
||
| 1091 | |||
| 1092 | # process_llvm_pass_plugins([GEN_CONFIG]) |
||
| 1093 | # |
||
| 1094 | # Correctly set lib dependencies between plugins and tools, based on tools |
||
| 1095 | # registered with the ENABLE_PLUGINS option. |
||
| 1096 | # |
||
| 1097 | # if GEN_CONFIG option is set, also generate X Macro file for extension |
||
| 1098 | # handling. It provides a HANDLE_EXTENSION(extension_namespace, ExtensionProject) |
||
| 1099 | # call for each extension allowing client code to define |
||
| 1100 | # HANDLE_EXTENSION to have a specific code be run for each extension. |
||
| 1101 | # |
||
| 1102 | function(process_llvm_pass_plugins) |
||
| 1103 | cmake_parse_arguments(ARG |
||
| 1104 | "GEN_CONFIG" "" "" |
||
| 1105 | ${ARGN}) |
||
| 1106 | |||
| 1107 | if(ARG_GEN_CONFIG) |
||
| 1108 | get_property(LLVM_STATIC_EXTENSIONS GLOBAL PROPERTY LLVM_STATIC_EXTENSIONS) |
||
| 1109 | else() |
||
| 1110 | include(LLVMConfigExtensions) |
||
| 1111 | endif() |
||
| 1112 | |||
| 1113 | # Add static plugins to the Extension component |
||
| 1114 | foreach(llvm_extension ${LLVM_STATIC_EXTENSIONS}) |
||
| 1115 | set_property(TARGET LLVMExtensions APPEND PROPERTY LINK_LIBRARIES ${llvm_extension}) |
||
| 1116 | set_property(TARGET LLVMExtensions APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${llvm_extension}) |
||
| 1117 | endforeach() |
||
| 1118 | |||
| 1119 | # Eventually generate the extension headers, and store config to a cmake file |
||
| 1120 | # for usage in third-party configuration. |
||
| 1121 | if(ARG_GEN_CONFIG) |
||
| 1122 | |||
| 1123 | ## Part 1: Extension header to be included whenever we need extension |
||
| 1124 | # processing. |
||
| 1125 | if(NOT DEFINED LLVM_INSTALL_PACKAGE_DIR) |
||
| 1126 | message(FATAL_ERROR "LLVM_INSTALL_PACKAGE_DIR must be defined and writable. GEN_CONFIG should only be passe when building LLVM proper.") |
||
| 1127 | endif() |
||
| 1128 | # LLVM_INSTALL_PACKAGE_DIR might be absolute, so don't reuse below. |
||
| 1129 | string(REPLACE "${CMAKE_CFG_INTDIR}" "." llvm_cmake_builddir "${LLVM_LIBRARY_DIR}") |
||
| 1130 | set(llvm_cmake_builddir "${llvm_cmake_builddir}/cmake/llvm") |
||
| 1131 | file(WRITE |
||
| 1132 | "${llvm_cmake_builddir}/LLVMConfigExtensions.cmake" |
||
| 1133 | "set(LLVM_STATIC_EXTENSIONS ${LLVM_STATIC_EXTENSIONS})") |
||
| 1134 | install(FILES |
||
| 1135 | ${llvm_cmake_builddir}/LLVMConfigExtensions.cmake |
||
| 1136 | DESTINATION ${LLVM_INSTALL_PACKAGE_DIR} |
||
| 1137 | COMPONENT cmake-exports) |
||
| 1138 | |||
| 1139 | set(ExtensionDef "${LLVM_BINARY_DIR}/include/llvm/Support/Extension.def") |
||
| 1140 | file(WRITE "${ExtensionDef}.tmp" "//extension handlers\n") |
||
| 1141 | foreach(llvm_extension ${LLVM_STATIC_EXTENSIONS}) |
||
| 1142 | file(APPEND "${ExtensionDef}.tmp" "HANDLE_EXTENSION(${llvm_extension})\n") |
||
| 1143 | endforeach() |
||
| 1144 | file(APPEND "${ExtensionDef}.tmp" "#undef HANDLE_EXTENSION\n") |
||
| 1145 | |||
| 1146 | # only replace if there's an actual change |
||
| 1147 | execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different |
||
| 1148 | "${ExtensionDef}.tmp" |
||
| 1149 | "${ExtensionDef}") |
||
| 1150 | file(REMOVE "${ExtensionDef}.tmp") |
||
| 1151 | |||
| 1152 | ## Part 2: Extension header that captures each extension dependency, to be |
||
| 1153 | # used by llvm-config. |
||
| 1154 | set(ExtensionDeps "${LLVM_BINARY_DIR}/tools/llvm-config/ExtensionDependencies.inc") |
||
| 1155 | |||
| 1156 | # Max needed to correctly size the required library array. |
||
| 1157 | set(llvm_plugin_max_deps_length 0) |
||
| 1158 | foreach(llvm_extension ${LLVM_STATIC_EXTENSIONS}) |
||
| 1159 | get_property(llvm_plugin_deps TARGET ${llvm_extension} PROPERTY LINK_LIBRARIES) |
||
| 1160 | list(LENGTH llvm_plugin_deps llvm_plugin_deps_length) |
||
| 1161 | if(llvm_plugin_deps_length GREATER llvm_plugin_max_deps_length) |
||
| 1162 | set(llvm_plugin_max_deps_length ${llvm_plugin_deps_length}) |
||
| 1163 | endif() |
||
| 1164 | endforeach() |
||
| 1165 | |||
| 1166 | list(LENGTH LLVM_STATIC_EXTENSIONS llvm_static_extension_count) |
||
| 1167 | file(WRITE |
||
| 1168 | "${ExtensionDeps}.tmp" |
||
| 1169 | "#include <array>\n\ |
||
| 1170 | struct ExtensionDescriptor {\n\ |
||
| 1171 | const char* Name;\n\ |
||
| 1172 | const char* RequiredLibraries[1 + 1 + ${llvm_plugin_max_deps_length}];\n\ |
||
| 1173 | };\n\ |
||
| 1174 | std::array<ExtensionDescriptor, ${llvm_static_extension_count}> AvailableExtensions{\n") |
||
| 1175 | |||
| 1176 | foreach(llvm_extension ${LLVM_STATIC_EXTENSIONS}) |
||
| 1177 | get_property(llvm_plugin_deps TARGET ${llvm_extension} PROPERTY LINK_LIBRARIES) |
||
| 1178 | |||
| 1179 | file(APPEND "${ExtensionDeps}.tmp" "ExtensionDescriptor{\"${llvm_extension}\", {") |
||
| 1180 | foreach(llvm_plugin_dep ${llvm_plugin_deps}) |
||
| 1181 | # Turn library dependency back to component name, if possible. |
||
| 1182 | # That way llvm-config can avoid redundant dependencies. |
||
| 1183 | STRING(REGEX REPLACE "^-l" "" plugin_dep_name ${llvm_plugin_dep}) |
||
| 1184 | STRING(REGEX MATCH "^LLVM" is_llvm_library ${plugin_dep_name}) |
||
| 1185 | if(is_llvm_library) |
||
| 1186 | STRING(REGEX REPLACE "^LLVM" "" plugin_dep_name ${plugin_dep_name}) |
||
| 1187 | STRING(TOLOWER ${plugin_dep_name} plugin_dep_name) |
||
| 1188 | endif() |
||
| 1189 | file(APPEND "${ExtensionDeps}.tmp" "\"${plugin_dep_name}\", ") |
||
| 1190 | endforeach() |
||
| 1191 | |||
| 1192 | # Self + mandatory trailing null, because the number of RequiredLibraries differs between extensions. |
||
| 1193 | file(APPEND "${ExtensionDeps}.tmp" \"${llvm_extension}\", "nullptr}},\n") |
||
| 1194 | endforeach() |
||
| 1195 | file(APPEND "${ExtensionDeps}.tmp" "};\n") |
||
| 1196 | |||
| 1197 | # only replace if there's an actual change |
||
| 1198 | execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different |
||
| 1199 | "${ExtensionDeps}.tmp" |
||
| 1200 | "${ExtensionDeps}") |
||
| 1201 | file(REMOVE "${ExtensionDeps}.tmp") |
||
| 1202 | endif() |
||
| 1203 | endfunction() |
||
| 1204 | |||
| 1205 | function(export_executable_symbols target) |
||
| 1206 | if (LLVM_EXPORTED_SYMBOL_FILE) |
||
| 1207 | # The symbol file should contain the symbols we want the executable to |
||
| 1208 | # export |
||
| 1209 | set_target_properties(${target} PROPERTIES ENABLE_EXPORTS 1) |
||
| 1210 | elseif (LLVM_EXPORT_SYMBOLS_FOR_PLUGINS) |
||
| 1211 | # Extract the symbols to export from the static libraries that the |
||
| 1212 | # executable links against. |
||
| 1213 | set_target_properties(${target} PROPERTIES ENABLE_EXPORTS 1) |
||
| 1214 | set(exported_symbol_file ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${target}.symbols) |
||
| 1215 | # We need to consider not just the direct link dependencies, but also the |
||
| 1216 | # transitive link dependencies. Do this by starting with the set of direct |
||
| 1217 | # dependencies, then the dependencies of those dependencies, and so on. |
||
| 1218 | get_target_property(new_libs ${target} LINK_LIBRARIES) |
||
| 1219 | set(link_libs ${new_libs}) |
||
| 1220 | while(NOT "${new_libs}" STREQUAL "") |
||
| 1221 | foreach(lib ${new_libs}) |
||
| 1222 | if(TARGET ${lib}) |
||
| 1223 | get_target_property(lib_type ${lib} TYPE) |
||
| 1224 | if("${lib_type}" STREQUAL "STATIC_LIBRARY") |
||
| 1225 | list(APPEND static_libs ${lib}) |
||
| 1226 | else() |
||
| 1227 | list(APPEND other_libs ${lib}) |
||
| 1228 | endif() |
||
| 1229 | get_target_property(transitive_libs ${lib} INTERFACE_LINK_LIBRARIES) |
||
| 1230 | foreach(transitive_lib ${transitive_libs}) |
||
| 1231 | if(TARGET ${transitive_lib} AND NOT ${transitive_lib} IN_LIST link_libs) |
||
| 1232 | list(APPEND newer_libs ${transitive_lib}) |
||
| 1233 | list(APPEND link_libs ${transitive_lib}) |
||
| 1234 | endif() |
||
| 1235 | endforeach(transitive_lib) |
||
| 1236 | endif() |
||
| 1237 | endforeach(lib) |
||
| 1238 | set(new_libs ${newer_libs}) |
||
| 1239 | set(newer_libs "") |
||
| 1240 | endwhile() |
||
| 1241 | list(REMOVE_DUPLICATES static_libs) |
||
| 1242 | if (MSVC) |
||
| 1243 | set(mangling microsoft) |
||
| 1244 | else() |
||
| 1245 | set(mangling itanium) |
||
| 1246 | endif() |
||
| 1247 | add_custom_command(OUTPUT ${exported_symbol_file} |
||
| 1248 | COMMAND "${Python3_EXECUTABLE}" ${LLVM_MAIN_SRC_DIR}/utils/extract_symbols.py ${LLVM_EXTRACT_SYMBOLS_FLAGS} --mangling=${mangling} ${static_libs} -o ${exported_symbol_file} |
||
| 1249 | WORKING_DIRECTORY ${LLVM_LIBRARY_OUTPUT_INTDIR} |
||
| 1250 | DEPENDS ${LLVM_MAIN_SRC_DIR}/utils/extract_symbols.py ${static_libs} |
||
| 1251 | VERBATIM |
||
| 1252 | COMMENT "Generating export list for ${target}") |
||
| 1253 | add_llvm_symbol_exports( ${target} ${exported_symbol_file} ) |
||
| 1254 | # If something links against this executable then we want a |
||
| 1255 | # transitive link against only the libraries whose symbols |
||
| 1256 | # we aren't exporting. |
||
| 1257 | set_target_properties(${target} PROPERTIES INTERFACE_LINK_LIBRARIES "${other_libs}") |
||
| 1258 | # The default import library suffix that cmake uses for cygwin/mingw is |
||
| 1259 | # ".dll.a", but for clang.exe that causes a collision with libclang.dll, |
||
| 1260 | # where the import libraries of both get named libclang.dll.a. Use a suffix |
||
| 1261 | # of ".exe.a" to avoid this. |
||
| 1262 | if(CYGWIN OR MINGW) |
||
| 1263 | set_target_properties(${target} PROPERTIES IMPORT_SUFFIX ".exe.a") |
||
| 1264 | endif() |
||
| 1265 | elseif(NOT (WIN32 OR CYGWIN)) |
||
| 1266 | # On Windows auto-exporting everything doesn't work because of the limit on |
||
| 1267 | # the size of the exported symbol table, but on other platforms we can do |
||
| 1268 | # it without any trouble. |
||
| 1269 | set_target_properties(${target} PROPERTIES ENABLE_EXPORTS 1) |
||
| 1270 | if (APPLE) |
||
| 1271 | set_property(TARGET ${target} APPEND_STRING PROPERTY |
||
| 1272 | LINK_FLAGS " -rdynamic") |
||
| 1273 | endif() |
||
| 1274 | endif() |
||
| 1275 | endfunction() |
||
| 1276 | |||
| 1277 | # Export symbols if LLVM plugins are enabled. |
||
| 1278 | function(export_executable_symbols_for_plugins target) |
||
| 1279 | if(LLVM_ENABLE_PLUGINS OR LLVM_EXPORT_SYMBOLS_FOR_PLUGINS) |
||
| 1280 | export_executable_symbols(${target}) |
||
| 1281 | endif() |
||
| 1282 | endfunction() |
||
| 1283 | |||
| 1284 | if(NOT LLVM_TOOLCHAIN_TOOLS) |
||
| 1285 | set (LLVM_TOOLCHAIN_TOOLS |
||
| 1286 | llvm-ar |
||
| 1287 | llvm-cov |
||
| 1288 | llvm-cxxfilt |
||
| 1289 | llvm-dwp |
||
| 1290 | llvm-ranlib |
||
| 1291 | llvm-lib |
||
| 1292 | llvm-ml |
||
| 1293 | llvm-nm |
||
| 1294 | llvm-objcopy |
||
| 1295 | llvm-objdump |
||
| 1296 | llvm-pdbutil |
||
| 1297 | llvm-rc |
||
| 1298 | llvm-readobj |
||
| 1299 | llvm-size |
||
| 1300 | llvm-strings |
||
| 1301 | llvm-strip |
||
| 1302 | llvm-profdata |
||
| 1303 | llvm-symbolizer |
||
| 1304 | # symlink version of some of above tools that are enabled by |
||
| 1305 | # LLVM_INSTALL_BINUTILS_SYMLINKS. |
||
| 1306 | addr2line |
||
| 1307 | ar |
||
| 1308 | c++filt |
||
| 1309 | ranlib |
||
| 1310 | nm |
||
| 1311 | objcopy |
||
| 1312 | objdump |
||
| 1313 | readelf |
||
| 1314 | size |
||
| 1315 | strings |
||
| 1316 | strip |
||
| 1317 | ) |
||
| 1318 | endif() |
||
| 1319 | |||
| 1320 | macro(llvm_add_tool project name) |
||
| 1321 | cmake_parse_arguments(ARG "DEPENDS;GENERATE_DRIVER" "" "" ${ARGN}) |
||
| 1322 | if( NOT LLVM_BUILD_TOOLS ) |
||
| 1323 | set(EXCLUDE_FROM_ALL ON) |
||
| 1324 | endif() |
||
| 1325 | if(ARG_GENERATE_DRIVER |
||
| 1326 | AND LLVM_TOOL_LLVM_DRIVER_BUILD |
||
| 1327 | AND (NOT LLVM_DISTRIBUTION_COMPONENTS OR ${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS) |
||
| 1328 | ) |
||
| 1329 | generate_llvm_objects(${name} ${ARGN}) |
||
| 1330 | add_custom_target(${name} DEPENDS llvm-driver) |
||
| 1331 | else() |
||
| 1332 | add_llvm_executable(${name} ${ARGN}) |
||
| 1333 | |||
| 1334 | if ( ${name} IN_LIST LLVM_TOOLCHAIN_TOOLS OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY) |
||
| 1335 | if( LLVM_BUILD_TOOLS ) |
||
| 1336 | get_target_export_arg(${name} LLVM export_to_llvmexports) |
||
| 1337 | install(TARGETS ${name} |
||
| 1338 | ${export_to_llvmexports} |
||
| 1339 | RUNTIME DESTINATION ${${project}_TOOLS_INSTALL_DIR} |
||
| 1340 | COMPONENT ${name}) |
||
| 1341 | |||
| 1342 | if (NOT LLVM_ENABLE_IDE) |
||
| 1343 | add_llvm_install_targets(install-${name} |
||
| 1344 | DEPENDS ${name} |
||
| 1345 | COMPONENT ${name}) |
||
| 1346 | endif() |
||
| 1347 | endif() |
||
| 1348 | endif() |
||
| 1349 | if( LLVM_BUILD_TOOLS ) |
||
| 1350 | set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name}) |
||
| 1351 | endif() |
||
| 1352 | set_target_properties(${name} PROPERTIES FOLDER "Tools") |
||
| 1353 | endif() |
||
| 1354 | endmacro(llvm_add_tool project name) |
||
| 1355 | |||
| 1356 | macro(add_llvm_tool name) |
||
| 1357 | llvm_add_tool(LLVM ${ARGV}) |
||
| 1358 | endmacro() |
||
| 1359 | |||
| 1360 | |||
| 1361 | macro(add_llvm_example name) |
||
| 1362 | if( NOT LLVM_BUILD_EXAMPLES ) |
||
| 1363 | set(EXCLUDE_FROM_ALL ON) |
||
| 1364 | endif() |
||
| 1365 | add_llvm_executable(${name} ${ARGN}) |
||
| 1366 | if( LLVM_BUILD_EXAMPLES ) |
||
| 1367 | install(TARGETS ${name} RUNTIME DESTINATION "${LLVM_EXAMPLES_INSTALL_DIR}") |
||
| 1368 | endif() |
||
| 1369 | set_target_properties(${name} PROPERTIES FOLDER "Examples") |
||
| 1370 | endmacro(add_llvm_example name) |
||
| 1371 | |||
| 1372 | macro(add_llvm_example_library name) |
||
| 1373 | if( NOT LLVM_BUILD_EXAMPLES ) |
||
| 1374 | set(EXCLUDE_FROM_ALL ON) |
||
| 1375 | add_llvm_library(${name} BUILDTREE_ONLY ${ARGN}) |
||
| 1376 | else() |
||
| 1377 | add_llvm_library(${name} ${ARGN}) |
||
| 1378 | endif() |
||
| 1379 | |||
| 1380 | set_target_properties(${name} PROPERTIES FOLDER "Examples") |
||
| 1381 | endmacro(add_llvm_example_library name) |
||
| 1382 | |||
| 1383 | # This is a macro that is used to create targets for executables that are needed |
||
| 1384 | # for development, but that are not intended to be installed by default. |
||
| 1385 | macro(add_llvm_utility name) |
||
| 1386 | if ( NOT LLVM_BUILD_UTILS ) |
||
| 1387 | set(EXCLUDE_FROM_ALL ON) |
||
| 1388 | endif() |
||
| 1389 | |||
| 1390 | add_llvm_executable(${name} DISABLE_LLVM_LINK_LLVM_DYLIB ${ARGN}) |
||
| 1391 | set_target_properties(${name} PROPERTIES FOLDER "Utils") |
||
| 1392 | if ( ${name} IN_LIST LLVM_TOOLCHAIN_UTILITIES OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY) |
||
| 1393 | if (LLVM_INSTALL_UTILS AND LLVM_BUILD_UTILS) |
||
| 1394 | get_target_export_arg(${name} LLVM export_to_llvmexports) |
||
| 1395 | install(TARGETS ${name} |
||
| 1396 | ${export_to_llvmexports} |
||
| 1397 | RUNTIME DESTINATION ${LLVM_UTILS_INSTALL_DIR} |
||
| 1398 | COMPONENT ${name}) |
||
| 1399 | |||
| 1400 | if (NOT LLVM_ENABLE_IDE) |
||
| 1401 | add_llvm_install_targets(install-${name} |
||
| 1402 | DEPENDS ${name} |
||
| 1403 | COMPONENT ${name}) |
||
| 1404 | endif() |
||
| 1405 | set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name}) |
||
| 1406 | elseif(LLVM_BUILD_UTILS) |
||
| 1407 | set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS_BUILDTREE_ONLY ${name}) |
||
| 1408 | endif() |
||
| 1409 | endif() |
||
| 1410 | endmacro(add_llvm_utility name) |
||
| 1411 | |||
| 1412 | macro(add_llvm_fuzzer name) |
||
| 1413 | cmake_parse_arguments(ARG "" "DUMMY_MAIN" "" ${ARGN}) |
||
| 1414 | if( LLVM_LIB_FUZZING_ENGINE ) |
||
| 1415 | set(LLVM_OPTIONAL_SOURCES ${ARG_DUMMY_MAIN}) |
||
| 1416 | add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS}) |
||
| 1417 | target_link_libraries(${name} PRIVATE ${LLVM_LIB_FUZZING_ENGINE}) |
||
| 1418 | set_target_properties(${name} PROPERTIES FOLDER "Fuzzers") |
||
| 1419 | elseif( LLVM_USE_SANITIZE_COVERAGE ) |
||
| 1420 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer") |
||
| 1421 | set(LLVM_OPTIONAL_SOURCES ${ARG_DUMMY_MAIN}) |
||
| 1422 | add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS}) |
||
| 1423 | set_target_properties(${name} PROPERTIES FOLDER "Fuzzers") |
||
| 1424 | elseif( ARG_DUMMY_MAIN ) |
||
| 1425 | add_llvm_executable(${name} ${ARG_DUMMY_MAIN} ${ARG_UNPARSED_ARGUMENTS}) |
||
| 1426 | set_target_properties(${name} PROPERTIES FOLDER "Fuzzers") |
||
| 1427 | endif() |
||
| 1428 | endmacro() |
||
| 1429 | |||
| 1430 | macro(add_llvm_target target_name) |
||
| 1431 | include_directories(BEFORE |
||
| 1432 | ${CMAKE_CURRENT_BINARY_DIR} |
||
| 1433 | ${CMAKE_CURRENT_SOURCE_DIR}) |
||
| 1434 | add_llvm_component_library(LLVM${target_name} ${ARGN}) |
||
| 1435 | set( CURRENT_LLVM_TARGET LLVM${target_name} ) |
||
| 1436 | endmacro(add_llvm_target) |
||
| 1437 | |||
| 1438 | function(canonicalize_tool_name name output) |
||
| 1439 | string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" nameStrip ${name}) |
||
| 1440 | string(REPLACE "-" "_" nameUNDERSCORE ${nameStrip}) |
||
| 1441 | string(TOUPPER ${nameUNDERSCORE} nameUPPER) |
||
| 1442 | set(${output} "${nameUPPER}" PARENT_SCOPE) |
||
| 1443 | endfunction(canonicalize_tool_name) |
||
| 1444 | |||
| 1445 | # Custom add_subdirectory wrapper |
||
| 1446 | # Takes in a project name (i.e. LLVM), the subdirectory name, and an optional |
||
| 1447 | # path if it differs from the name. |
||
| 1448 | function(add_llvm_subdirectory project type name) |
||
| 1449 | set(add_llvm_external_dir "${ARGN}") |
||
| 1450 | if("${add_llvm_external_dir}" STREQUAL "") |
||
| 1451 | set(add_llvm_external_dir ${name}) |
||
| 1452 | endif() |
||
| 1453 | canonicalize_tool_name(${name} nameUPPER) |
||
| 1454 | set(canonical_full_name ${project}_${type}_${nameUPPER}) |
||
| 1455 | get_property(already_processed GLOBAL PROPERTY ${canonical_full_name}_PROCESSED) |
||
| 1456 | if(already_processed) |
||
| 1457 | return() |
||
| 1458 | endif() |
||
| 1459 | set_property(GLOBAL PROPERTY ${canonical_full_name}_PROCESSED YES) |
||
| 1460 | |||
| 1461 | if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}/CMakeLists.txt) |
||
| 1462 | # Treat it as in-tree subproject. |
||
| 1463 | option(${canonical_full_name}_BUILD |
||
| 1464 | "Whether to build ${name} as part of ${project}" On) |
||
| 1465 | mark_as_advanced(${project}_${type}_${name}_BUILD) |
||
| 1466 | if(${canonical_full_name}_BUILD) |
||
| 1467 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir} ${add_llvm_external_dir}) |
||
| 1468 | endif() |
||
| 1469 | else() |
||
| 1470 | set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR |
||
| 1471 | "${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}" |
||
| 1472 | CACHE PATH "Path to ${name} source directory") |
||
| 1473 | set(${canonical_full_name}_BUILD_DEFAULT ON) |
||
| 1474 | if(NOT LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR OR NOT EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}) |
||
| 1475 | set(${canonical_full_name}_BUILD_DEFAULT OFF) |
||
| 1476 | endif() |
||
| 1477 | if("${LLVM_EXTERNAL_${nameUPPER}_BUILD}" STREQUAL "OFF") |
||
| 1478 | set(${canonical_full_name}_BUILD_DEFAULT OFF) |
||
| 1479 | endif() |
||
| 1480 | option(${canonical_full_name}_BUILD |
||
| 1481 | "Whether to build ${name} as part of LLVM" |
||
| 1482 | ${${canonical_full_name}_BUILD_DEFAULT}) |
||
| 1483 | if (${canonical_full_name}_BUILD) |
||
| 1484 | if(EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}) |
||
| 1485 | add_subdirectory(${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR} ${add_llvm_external_dir}) |
||
| 1486 | elseif(NOT "${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}" STREQUAL "") |
||
| 1487 | message(WARNING "Nonexistent directory for ${name}: ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}") |
||
| 1488 | endif() |
||
| 1489 | endif() |
||
| 1490 | endif() |
||
| 1491 | endfunction() |
||
| 1492 | |||
| 1493 | # Add external project that may want to be built as part of llvm such as Clang, |
||
| 1494 | # lld, and Polly. This adds two options. One for the source directory of the |
||
| 1495 | # project, which defaults to ${CMAKE_CURRENT_SOURCE_DIR}/${name}. Another to |
||
| 1496 | # enable or disable building it with everything else. |
||
| 1497 | # Additional parameter can be specified as the name of directory. |
||
| 1498 | macro(add_llvm_external_project name) |
||
| 1499 | add_llvm_subdirectory(LLVM TOOL ${name} ${ARGN}) |
||
| 1500 | endmacro() |
||
| 1501 | |||
| 1502 | macro(add_llvm_tool_subdirectory name) |
||
| 1503 | add_llvm_external_project(${name}) |
||
| 1504 | endmacro(add_llvm_tool_subdirectory) |
||
| 1505 | |||
| 1506 | function(get_project_name_from_src_var var output) |
||
| 1507 | string(REGEX MATCH "LLVM_EXTERNAL_(.*)_SOURCE_DIR" |
||
| 1508 | MACHED_TOOL "${var}") |
||
| 1509 | if(MACHED_TOOL) |
||
| 1510 | set(${output} ${CMAKE_MATCH_1} PARENT_SCOPE) |
||
| 1511 | else() |
||
| 1512 | set(${output} PARENT_SCOPE) |
||
| 1513 | endif() |
||
| 1514 | endfunction() |
||
| 1515 | |||
| 1516 | function(create_subdirectory_options project type) |
||
| 1517 | file(GLOB sub-dirs "${CMAKE_CURRENT_SOURCE_DIR}/*") |
||
| 1518 | foreach(dir ${sub-dirs}) |
||
| 1519 | if(IS_DIRECTORY "${dir}" AND EXISTS "${dir}/CMakeLists.txt") |
||
| 1520 | canonicalize_tool_name(${dir} name) |
||
| 1521 | option(${project}_${type}_${name}_BUILD |
||
| 1522 | "Whether to build ${name} as part of ${project}" On) |
||
| 1523 | mark_as_advanced(${project}_${type}_${name}_BUILD) |
||
| 1524 | endif() |
||
| 1525 | endforeach() |
||
| 1526 | endfunction(create_subdirectory_options) |
||
| 1527 | |||
| 1528 | function(create_llvm_tool_options) |
||
| 1529 | create_subdirectory_options(LLVM TOOL) |
||
| 1530 | endfunction(create_llvm_tool_options) |
||
| 1531 | |||
| 1532 | function(llvm_add_implicit_projects project) |
||
| 1533 | set(list_of_implicit_subdirs "") |
||
| 1534 | file(GLOB sub-dirs "${CMAKE_CURRENT_SOURCE_DIR}/*") |
||
| 1535 | foreach(dir ${sub-dirs}) |
||
| 1536 | if(IS_DIRECTORY "${dir}" AND EXISTS "${dir}/CMakeLists.txt") |
||
| 1537 | canonicalize_tool_name(${dir} name) |
||
| 1538 | # I don't like special casing things by order, but the llvm-driver ends up |
||
| 1539 | # linking the object libraries from all the tools that opt-in, so adding |
||
| 1540 | # it separately at the end is probably the simplest case. |
||
| 1541 | if("${name}" STREQUAL "LLVM_DRIVER") |
||
| 1542 | continue() |
||
| 1543 | endif() |
||
| 1544 | if (${project}_TOOL_${name}_BUILD) |
||
| 1545 | get_filename_component(fn "${dir}" NAME) |
||
| 1546 | list(APPEND list_of_implicit_subdirs "${fn}") |
||
| 1547 | endif() |
||
| 1548 | endif() |
||
| 1549 | endforeach() |
||
| 1550 | |||
| 1551 | foreach(external_proj ${list_of_implicit_subdirs}) |
||
| 1552 | add_llvm_subdirectory(${project} TOOL "${external_proj}" ${ARGN}) |
||
| 1553 | endforeach() |
||
| 1554 | endfunction(llvm_add_implicit_projects) |
||
| 1555 | |||
| 1556 | function(add_llvm_implicit_projects) |
||
| 1557 | llvm_add_implicit_projects(LLVM) |
||
| 1558 | endfunction(add_llvm_implicit_projects) |
||
| 1559 | |||
| 1560 | # Generic support for adding a unittest. |
||
| 1561 | function(add_unittest test_suite test_name) |
||
| 1562 | if( NOT LLVM_BUILD_TESTS ) |
||
| 1563 | set(EXCLUDE_FROM_ALL ON) |
||
| 1564 | endif() |
||
| 1565 | |||
| 1566 | if (SUPPORTS_VARIADIC_MACROS_FLAG) |
||
| 1567 | list(APPEND LLVM_COMPILE_FLAGS "-Wno-variadic-macros") |
||
| 1568 | endif () |
||
| 1569 | # Some parts of gtest rely on this GNU extension, don't warn on it. |
||
| 1570 | if(SUPPORTS_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS_FLAG) |
||
| 1571 | list(APPEND LLVM_COMPILE_FLAGS "-Wno-gnu-zero-variadic-macro-arguments") |
||
| 1572 | endif() |
||
| 1573 | |||
| 1574 | if (NOT DEFINED LLVM_REQUIRES_RTTI) |
||
| 1575 | set(LLVM_REQUIRES_RTTI OFF) |
||
| 1576 | endif() |
||
| 1577 | |||
| 1578 | list(APPEND LLVM_LINK_COMPONENTS Support) # gtest needs it for raw_ostream |
||
| 1579 | add_llvm_executable(${test_name} IGNORE_EXTERNALIZE_DEBUGINFO NO_INSTALL_RPATH ${ARGN}) |
||
| 1580 | |||
| 1581 | # The runtime benefits of LTO don't outweight the compile time costs for tests. |
||
| 1582 | if(LLVM_ENABLE_LTO) |
||
| 1583 | if((UNIX OR MINGW) AND LINKER_IS_LLD) |
||
| 1584 | set_property(TARGET ${test_name} APPEND_STRING PROPERTY |
||
| 1585 | LINK_FLAGS " -Wl,--lto-O0") |
||
| 1586 | elseif(LINKER_IS_LLD_LINK) |
||
| 1587 | set_property(TARGET ${test_name} APPEND_STRING PROPERTY |
||
| 1588 | LINK_FLAGS " /opt:lldlto=0") |
||
| 1589 | elseif(APPLE AND NOT uppercase_LLVM_ENABLE_LTO STREQUAL "THIN") |
||
| 1590 | set_property(TARGET ${target_name} APPEND_STRING PROPERTY |
||
| 1591 | LINK_FLAGS " -Wl,-mllvm,-O0") |
||
| 1592 | endif() |
||
| 1593 | endif() |
||
| 1594 | |||
| 1595 | set(outdir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}) |
||
| 1596 | set_output_directory(${test_name} BINARY_DIR ${outdir} LIBRARY_DIR ${outdir}) |
||
| 1597 | # libpthreads overrides some standard library symbols, so main |
||
| 1598 | # executable must be linked with it in order to provide consistent |
||
| 1599 | # API for all shared libaries loaded by this executable. |
||
| 1600 | target_link_libraries(${test_name} PRIVATE llvm_gtest_main llvm_gtest ${LLVM_PTHREAD_LIB}) |
||
| 1601 | |||
| 1602 | add_dependencies(${test_suite} ${test_name}) |
||
| 1603 | get_target_property(test_suite_folder ${test_suite} FOLDER) |
||
| 1604 | if (test_suite_folder) |
||
| 1605 | set_property(TARGET ${test_name} PROPERTY FOLDER "${test_suite_folder}") |
||
| 1606 | endif () |
||
| 1607 | endfunction() |
||
| 1608 | |||
| 1609 | # Use for test binaries that call llvm::getInputFileDirectory(). Use of this |
||
| 1610 | # is discouraged. |
||
| 1611 | function(add_unittest_with_input_files test_suite test_name) |
||
| 1612 | set(LLVM_UNITTEST_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) |
||
| 1613 | configure_file( |
||
| 1614 | ${LLVM_MAIN_SRC_DIR}/unittests/unittest.cfg.in |
||
| 1615 | ${CMAKE_CURRENT_BINARY_DIR}/llvm.srcdir.txt) |
||
| 1616 | |||
| 1617 | add_unittest(${test_suite} ${test_name} ${ARGN}) |
||
| 1618 | endfunction() |
||
| 1619 | |||
| 1620 | # Generic support for adding a benchmark. |
||
| 1621 | function(add_benchmark benchmark_name) |
||
| 1622 | if( NOT LLVM_BUILD_BENCHMARKS ) |
||
| 1623 | set(EXCLUDE_FROM_ALL ON) |
||
| 1624 | endif() |
||
| 1625 | |||
| 1626 | add_llvm_executable(${benchmark_name} IGNORE_EXTERNALIZE_DEBUGINFO NO_INSTALL_RPATH ${ARGN}) |
||
| 1627 | set(outdir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}) |
||
| 1628 | set_output_directory(${benchmark_name} BINARY_DIR ${outdir} LIBRARY_DIR ${outdir}) |
||
| 1629 | set_property(TARGET ${benchmark_name} PROPERTY FOLDER "Utils") |
||
| 1630 | target_link_libraries(${benchmark_name} PRIVATE benchmark) |
||
| 1631 | endfunction() |
||
| 1632 | |||
| 1633 | # This function canonicalize the CMake variables passed by names |
||
| 1634 | # from CMake boolean to 0/1 suitable for passing into Python or C++, |
||
| 1635 | # in place. |
||
| 1636 | function(llvm_canonicalize_cmake_booleans) |
||
| 1637 | foreach(var ${ARGN}) |
||
| 1638 | if(${var}) |
||
| 1639 | set(${var} 1 PARENT_SCOPE) |
||
| 1640 | else() |
||
| 1641 | set(${var} 0 PARENT_SCOPE) |
||
| 1642 | endif() |
||
| 1643 | endforeach() |
||
| 1644 | endfunction(llvm_canonicalize_cmake_booleans) |
||
| 1645 | |||
| 1646 | macro(set_llvm_build_mode) |
||
| 1647 | # Configuration-time: See Unit/lit.site.cfg.in |
||
| 1648 | if (CMAKE_CFG_INTDIR STREQUAL ".") |
||
| 1649 | set(LLVM_BUILD_MODE ".") |
||
| 1650 | else () |
||
| 1651 | set(LLVM_BUILD_MODE "%(build_mode)s") |
||
| 1652 | endif () |
||
| 1653 | endmacro() |
||
| 1654 | |||
| 1655 | # Takes a list of path names in pathlist and a base directory, and returns |
||
| 1656 | # a list of paths relative to the base directory in out_pathlist. |
||
| 1657 | # Paths that are on a different drive than the basedir (on Windows) or that |
||
| 1658 | # contain symlinks are returned absolute. |
||
| 1659 | # Use with LLVM_LIT_PATH_FUNCTION below. |
||
| 1660 | function(make_paths_relative out_pathlist basedir pathlist) |
||
| 1661 | # Passing ARG_PATH_VALUES as-is to execute_process() makes cmake strip |
||
| 1662 | # empty list entries. So escape the ;s in the list and do the splitting |
||
| 1663 | # ourselves. cmake has no relpath function, so use Python for that. |
||
| 1664 | string(REPLACE ";" "\\;" pathlist_escaped "${pathlist}") |
||
| 1665 | execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "\n |
||
| 1666 | import os, sys\n |
||
| 1667 | base = sys.argv[1] |
||
| 1668 | def haslink(p):\n |
||
| 1669 | if not p or p == os.path.dirname(p): return False\n |
||
| 1670 | return os.path.islink(p) or haslink(os.path.dirname(p))\n |
||
| 1671 | def relpath(p):\n |
||
| 1672 | if not p: return ''\n |
||
| 1673 | if os.path.splitdrive(p)[0] != os.path.splitdrive(base)[0]: return p\n |
||
| 1674 | if haslink(p) or haslink(base): return p\n |
||
| 1675 | return os.path.relpath(p, base)\n |
||
| 1676 | if len(sys.argv) < 3: sys.exit(0)\n |
||
| 1677 | sys.stdout.write(';'.join(relpath(p) for p in sys.argv[2].split(';')))" |
||
| 1678 | ${basedir} |
||
| 1679 | ${pathlist_escaped} |
||
| 1680 | OUTPUT_VARIABLE pathlist_relative |
||
| 1681 | ERROR_VARIABLE error |
||
| 1682 | RESULT_VARIABLE result) |
||
| 1683 | if (NOT result EQUAL 0) |
||
| 1684 | message(FATAL_ERROR "make_paths_relative() failed due to error '${result}', with stderr\n${error}") |
||
| 1685 | endif() |
||
| 1686 | set(${out_pathlist} "${pathlist_relative}" PARENT_SCOPE) |
||
| 1687 | endfunction() |
||
| 1688 | |||
| 1689 | # Converts a file that's relative to the current python file to an absolute |
||
| 1690 | # path. Since this uses __file__, it has to be emitted into python files that |
||
| 1691 | # use it and can't be in a lit module. Use with make_paths_relative(). |
||
| 1692 | string(CONCAT LLVM_LIT_PATH_FUNCTION |
||
| 1693 | "# Allow generated file to be relocatable.\n" |
||
| 1694 | "from pathlib import Path\n" |
||
| 1695 | "def path(p):\n" |
||
| 1696 | " if not p: return ''\n" |
||
| 1697 | " return str((Path(__file__).parent / p).resolve())\n" |
||
| 1698 | ) |
||
| 1699 | |||
| 1700 | # This function provides an automatic way to 'configure'-like generate a file |
||
| 1701 | # based on a set of common and custom variables, specifically targeting the |
||
| 1702 | # variables needed for the 'lit.site.cfg' files. This function bundles the |
||
| 1703 | # common variables that any Lit instance is likely to need, and custom |
||
| 1704 | # variables can be passed in. |
||
| 1705 | # The keyword PATHS is followed by a list of cmake variable names that are |
||
| 1706 | # mentioned as `path("@varname@")` in the lit.cfg.py.in file. Variables in that |
||
| 1707 | # list are treated as paths that are relative to the directory the generated |
||
| 1708 | # lit.cfg.py file is in, and the `path()` function converts the relative |
||
| 1709 | # path back to absolute form. This makes it possible to move a build directory |
||
| 1710 | # containing lit.cfg.py files from one machine to another. |
||
| 1711 | function(configure_lit_site_cfg site_in site_out) |
||
| 1712 | cmake_parse_arguments(ARG "" "" "MAIN_CONFIG;PATHS" ${ARGN}) |
||
| 1713 | |||
| 1714 | if ("${ARG_MAIN_CONFIG}" STREQUAL "") |
||
| 1715 | get_filename_component(INPUT_DIR ${site_in} DIRECTORY) |
||
| 1716 | set(ARG_MAIN_CONFIG "${INPUT_DIR}/lit.cfg") |
||
| 1717 | endif() |
||
| 1718 | |||
| 1719 | foreach(c ${LLVM_TARGETS_TO_BUILD}) |
||
| 1720 | set(TARGETS_BUILT "${TARGETS_BUILT} ${c}") |
||
| 1721 | endforeach(c) |
||
| 1722 | set(TARGETS_TO_BUILD ${TARGETS_BUILT}) |
||
| 1723 | |||
| 1724 | set(SHLIBEXT "${LTDL_SHLIB_EXT}") |
||
| 1725 | |||
| 1726 | set_llvm_build_mode() |
||
| 1727 | |||
| 1728 | # For standalone builds of subprojects, these might not be the build tree but |
||
| 1729 | # a provided binary tree. |
||
| 1730 | set(LLVM_SOURCE_DIR ${LLVM_MAIN_SRC_DIR}) |
||
| 1731 | set(LLVM_BINARY_DIR ${LLVM_BINARY_DIR}) |
||
| 1732 | string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}") |
||
| 1733 | string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" LLVM_LIBS_DIR "${LLVM_LIBRARY_DIR}") |
||
| 1734 | # Like LLVM_{TOOLS,LIBS}_DIR, but pointing at the build tree. |
||
| 1735 | string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" CURRENT_TOOLS_DIR "${LLVM_RUNTIME_OUTPUT_INTDIR}") |
||
| 1736 | string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" CURRENT_LIBS_DIR "${LLVM_LIBRARY_OUTPUT_INTDIR}") |
||
| 1737 | string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" SHLIBDIR "${LLVM_SHLIB_OUTPUT_INTDIR}") |
||
| 1738 | |||
| 1739 | # FIXME: "ENABLE_SHARED" doesn't make sense, since it is used just for |
||
| 1740 | # plugins. We may rename it. |
||
| 1741 | if(LLVM_ENABLE_PLUGINS) |
||
| 1742 | set(ENABLE_SHARED "1") |
||
| 1743 | else() |
||
| 1744 | set(ENABLE_SHARED "0") |
||
| 1745 | endif() |
||
| 1746 | |||
| 1747 | if(LLVM_ENABLE_ASSERTIONS) |
||
| 1748 | set(ENABLE_ASSERTIONS "1") |
||
| 1749 | else() |
||
| 1750 | set(ENABLE_ASSERTIONS "0") |
||
| 1751 | endif() |
||
| 1752 | |||
| 1753 | set(HOST_OS ${CMAKE_SYSTEM_NAME}) |
||
| 1754 | set(HOST_ARCH ${CMAKE_SYSTEM_PROCESSOR}) |
||
| 1755 | |||
| 1756 | set(HOST_CC "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}") |
||
| 1757 | set(HOST_CXX "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}") |
||
| 1758 | set(HOST_LDFLAGS "${CMAKE_EXE_LINKER_FLAGS}") |
||
| 1759 | |||
| 1760 | string(CONCAT LIT_SITE_CFG_IN_HEADER |
||
| 1761 | "# Autogenerated from ${site_in}\n# Do not edit!\n\n" |
||
| 1762 | "${LLVM_LIT_PATH_FUNCTION}" |
||
| 1763 | ) |
||
| 1764 | |||
| 1765 | # Override config_target_triple (and the env) |
||
| 1766 | if(LLVM_TARGET_TRIPLE_ENV) |
||
| 1767 | # This is expanded into the heading. |
||
| 1768 | string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}" |
||
| 1769 | "import os\n" |
||
| 1770 | "target_env = \"${LLVM_TARGET_TRIPLE_ENV}\"\n" |
||
| 1771 | "config.target_triple = config.environment[target_env] = os.environ.get(target_env, \"${LLVM_TARGET_TRIPLE}\")\n" |
||
| 1772 | ) |
||
| 1773 | |||
| 1774 | # This is expanded to; config.target_triple = ""+config.target_triple+"" |
||
| 1775 | set(LLVM_TARGET_TRIPLE "\"+config.target_triple+\"") |
||
| 1776 | endif() |
||
| 1777 | |||
| 1778 | if (ARG_PATHS) |
||
| 1779 | # Walk ARG_PATHS and collect the current value of the variables in there. |
||
| 1780 | # list(APPEND) ignores empty elements exactly if the list is empty, |
||
| 1781 | # so start the list with a dummy element and drop it, to make sure that |
||
| 1782 | # even empty values make it into the values list. |
||
| 1783 | set(ARG_PATH_VALUES "dummy") |
||
| 1784 | foreach(path ${ARG_PATHS}) |
||
| 1785 | list(APPEND ARG_PATH_VALUES "${${path}}") |
||
| 1786 | endforeach() |
||
| 1787 | list(REMOVE_AT ARG_PATH_VALUES 0) |
||
| 1788 | |||
| 1789 | get_filename_component(OUTPUT_DIR ${site_out} DIRECTORY) |
||
| 1790 | make_paths_relative( |
||
| 1791 | ARG_PATH_VALUES_RELATIVE "${OUTPUT_DIR}" "${ARG_PATH_VALUES}") |
||
| 1792 | |||
| 1793 | list(LENGTH ARG_PATHS len_paths) |
||
| 1794 | list(LENGTH ARG_PATH_VALUES len_path_values) |
||
| 1795 | list(LENGTH ARG_PATH_VALUES_RELATIVE len_path_value_rels) |
||
| 1796 | if ((NOT ${len_paths} EQUAL ${len_path_values}) OR |
||
| 1797 | (NOT ${len_paths} EQUAL ${len_path_value_rels})) |
||
| 1798 | message(SEND_ERROR "PATHS lengths got confused") |
||
| 1799 | endif() |
||
| 1800 | |||
| 1801 | # Transform variables mentioned in ARG_PATHS to relative paths for |
||
| 1802 | # the configure_file() call. Variables are copied to subscopeds by cmake, |
||
| 1803 | # so this only modifies the local copy of the variables. |
||
| 1804 | math(EXPR arg_path_limit "${len_paths} - 1") |
||
| 1805 | foreach(i RANGE ${arg_path_limit}) |
||
| 1806 | list(GET ARG_PATHS ${i} val1) |
||
| 1807 | list(GET ARG_PATH_VALUES_RELATIVE ${i} val2) |
||
| 1808 | set(${val1} ${val2}) |
||
| 1809 | endforeach() |
||
| 1810 | endif() |
||
| 1811 | |||
| 1812 | configure_file(${site_in} ${site_out} @ONLY) |
||
| 1813 | |||
| 1814 | if (EXISTS "${ARG_MAIN_CONFIG}") |
||
| 1815 | # Remember main config / generated site config for llvm-lit.in. |
||
| 1816 | get_property(LLVM_LIT_CONFIG_FILES GLOBAL PROPERTY LLVM_LIT_CONFIG_FILES) |
||
| 1817 | list(APPEND LLVM_LIT_CONFIG_FILES "${ARG_MAIN_CONFIG}" "${site_out}") |
||
| 1818 | set_property(GLOBAL PROPERTY LLVM_LIT_CONFIG_FILES ${LLVM_LIT_CONFIG_FILES}) |
||
| 1819 | endif() |
||
| 1820 | endfunction() |
||
| 1821 | |||
| 1822 | function(dump_all_cmake_variables) |
||
| 1823 | get_cmake_property(_variableNames VARIABLES) |
||
| 1824 | foreach (_variableName ${_variableNames}) |
||
| 1825 | message(STATUS "${_variableName}=${${_variableName}}") |
||
| 1826 | endforeach() |
||
| 1827 | endfunction() |
||
| 1828 | |||
| 1829 | function(get_llvm_lit_path base_dir file_name) |
||
| 1830 | cmake_parse_arguments(ARG "ALLOW_EXTERNAL" "" "" ${ARGN}) |
||
| 1831 | |||
| 1832 | if (ARG_ALLOW_EXTERNAL) |
||
| 1833 | set (LLVM_EXTERNAL_LIT "" CACHE STRING "Command used to spawn lit") |
||
| 1834 | if ("${LLVM_EXTERNAL_LIT}" STREQUAL "") |
||
| 1835 | set(LLVM_EXTERNAL_LIT "${LLVM_DEFAULT_EXTERNAL_LIT}") |
||
| 1836 | endif() |
||
| 1837 | |||
| 1838 | if (NOT "${LLVM_EXTERNAL_LIT}" STREQUAL "") |
||
| 1839 | if (EXISTS ${LLVM_EXTERNAL_LIT}) |
||
| 1840 | get_filename_component(LIT_FILE_NAME ${LLVM_EXTERNAL_LIT} NAME) |
||
| 1841 | get_filename_component(LIT_BASE_DIR ${LLVM_EXTERNAL_LIT} DIRECTORY) |
||
| 1842 | set(${file_name} ${LIT_FILE_NAME} PARENT_SCOPE) |
||
| 1843 | set(${base_dir} ${LIT_BASE_DIR} PARENT_SCOPE) |
||
| 1844 | return() |
||
| 1845 | elseif (NOT DEFINED CACHE{LLVM_EXTERNAL_LIT_MISSING_WARNED_ONCE}) |
||
| 1846 | message(WARNING "LLVM_EXTERNAL_LIT set to ${LLVM_EXTERNAL_LIT}, but the path does not exist.") |
||
| 1847 | set(LLVM_EXTERNAL_LIT_MISSING_WARNED_ONCE YES CACHE INTERNAL "") |
||
| 1848 | endif() |
||
| 1849 | endif() |
||
| 1850 | endif() |
||
| 1851 | |||
| 1852 | set(lit_file_name "llvm-lit") |
||
| 1853 | if (CMAKE_HOST_WIN32 AND NOT CYGWIN) |
||
| 1854 | # llvm-lit needs suffix.py for multiprocess to find a main module. |
||
| 1855 | set(lit_file_name "${lit_file_name}.py") |
||
| 1856 | endif () |
||
| 1857 | set(${file_name} ${lit_file_name} PARENT_SCOPE) |
||
| 1858 | |||
| 1859 | get_property(LLVM_LIT_BASE_DIR GLOBAL PROPERTY LLVM_LIT_BASE_DIR) |
||
| 1860 | if (NOT "${LLVM_LIT_BASE_DIR}" STREQUAL "") |
||
| 1861 | set(${base_dir} ${LLVM_LIT_BASE_DIR} PARENT_SCOPE) |
||
| 1862 | endif() |
||
| 1863 | |||
| 1864 | # Allow individual projects to provide an override |
||
| 1865 | if (NOT "${LLVM_LIT_OUTPUT_DIR}" STREQUAL "") |
||
| 1866 | set(LLVM_LIT_BASE_DIR ${LLVM_LIT_OUTPUT_DIR}) |
||
| 1867 | elseif(NOT "${LLVM_RUNTIME_OUTPUT_INTDIR}" STREQUAL "") |
||
| 1868 | set(LLVM_LIT_BASE_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR}) |
||
| 1869 | else() |
||
| 1870 | set(LLVM_LIT_BASE_DIR "") |
||
| 1871 | endif() |
||
| 1872 | |||
| 1873 | # Cache this so we don't have to do it again and have subsequent calls |
||
| 1874 | # potentially disagree on the value. |
||
| 1875 | set_property(GLOBAL PROPERTY LLVM_LIT_BASE_DIR ${LLVM_LIT_BASE_DIR}) |
||
| 1876 | set(${base_dir} ${LLVM_LIT_BASE_DIR} PARENT_SCOPE) |
||
| 1877 | endfunction() |
||
| 1878 | |||
| 1879 | # A raw function to create a lit target. This is used to implement the testuite |
||
| 1880 | # management functions. |
||
| 1881 | function(add_lit_target target comment) |
||
| 1882 | cmake_parse_arguments(ARG "" "" "PARAMS;DEPENDS;ARGS" ${ARGN}) |
||
| 1883 | set(LIT_ARGS "${ARG_ARGS} ${LLVM_LIT_ARGS}") |
||
| 1884 | separate_arguments(LIT_ARGS) |
||
| 1885 | if (NOT CMAKE_CFG_INTDIR STREQUAL ".") |
||
| 1886 | list(APPEND LIT_ARGS --param build_mode=${CMAKE_CFG_INTDIR}) |
||
| 1887 | endif () |
||
| 1888 | |||
| 1889 | # Get the path to the lit to *run* tests with. This can be overriden by |
||
| 1890 | # the user by specifying -DLLVM_EXTERNAL_LIT=<path-to-lit.py> |
||
| 1891 | get_llvm_lit_path( |
||
| 1892 | lit_base_dir |
||
| 1893 | lit_file_name |
||
| 1894 | ALLOW_EXTERNAL |
||
| 1895 | ) |
||
| 1896 | |||
| 1897 | set(LIT_COMMAND "${Python3_EXECUTABLE};${lit_base_dir}/${lit_file_name}") |
||
| 1898 | list(APPEND LIT_COMMAND ${LIT_ARGS}) |
||
| 1899 | foreach(param ${ARG_PARAMS}) |
||
| 1900 | list(APPEND LIT_COMMAND --param ${param}) |
||
| 1901 | endforeach() |
||
| 1902 | if (ARG_UNPARSED_ARGUMENTS) |
||
| 1903 | add_custom_target(${target} |
||
| 1904 | COMMAND ${LIT_COMMAND} ${ARG_UNPARSED_ARGUMENTS} |
||
| 1905 | COMMENT "${comment}" |
||
| 1906 | USES_TERMINAL |
||
| 1907 | ) |
||
| 1908 | else() |
||
| 1909 | add_custom_target(${target} |
||
| 1910 | COMMAND ${CMAKE_COMMAND} -E echo "${target} does nothing, no tools built.") |
||
| 1911 | message(STATUS "${target} does nothing.") |
||
| 1912 | endif() |
||
| 1913 | |||
| 1914 | if (ARG_DEPENDS) |
||
| 1915 | add_dependencies(${target} ${ARG_DEPENDS}) |
||
| 1916 | endif() |
||
| 1917 | |||
| 1918 | # Tests should be excluded from "Build Solution". |
||
| 1919 | set_target_properties(${target} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD ON) |
||
| 1920 | endfunction() |
||
| 1921 | |||
| 1922 | # Convert a target name like check-clang to a variable name like CLANG. |
||
| 1923 | function(umbrella_lit_testsuite_var target outvar) |
||
| 1924 | if (NOT target MATCHES "^check-") |
||
| 1925 | message(FATAL_ERROR "umbrella lit suites must be check-*, not '${target}'") |
||
| 1926 | endif() |
||
| 1927 | string(SUBSTRING "${target}" 6 -1 var) |
||
| 1928 | string(REPLACE "-" "_" var ${var}) |
||
| 1929 | string(TOUPPER "${var}" var) |
||
| 1930 | set(${outvar} "${var}" PARENT_SCOPE) |
||
| 1931 | endfunction() |
||
| 1932 | |||
| 1933 | # Start recording all lit test suites for a combined 'check-foo' target. |
||
| 1934 | # The recording continues until umbrella_lit_testsuite_end() creates the target. |
||
| 1935 | function(umbrella_lit_testsuite_begin target) |
||
| 1936 | umbrella_lit_testsuite_var(${target} name) |
||
| 1937 | set_property(GLOBAL APPEND PROPERTY LLVM_LIT_UMBRELLAS ${name}) |
||
| 1938 | endfunction() |
||
| 1939 | |||
| 1940 | # Create a combined 'check-foo' target for a set of related test suites. |
||
| 1941 | # It runs all suites added since the matching umbrella_lit_testsuite_end() call. |
||
| 1942 | # Tests marked EXCLUDE_FROM_CHECK_ALL are not gathered. |
||
| 1943 | function(umbrella_lit_testsuite_end target) |
||
| 1944 | umbrella_lit_testsuite_var(${target} name) |
||
| 1945 | |||
| 1946 | get_property(testsuites GLOBAL PROPERTY LLVM_${name}_LIT_TESTSUITES) |
||
| 1947 | get_property(params GLOBAL PROPERTY LLVM_${name}_LIT_PARAMS) |
||
| 1948 | get_property(depends GLOBAL PROPERTY LLVM_${name}_LIT_DEPENDS) |
||
| 1949 | get_property(extra_args GLOBAL PROPERTY LLVM_${name}_LIT_EXTRA_ARGS) |
||
| 1950 | # Additional test targets are not gathered, but may be set externally. |
||
| 1951 | get_property(additional_test_targets |
||
| 1952 | GLOBAL PROPERTY LLVM_${name}_ADDITIONAL_TEST_TARGETS) |
||
| 1953 | |||
| 1954 | string(TOLOWER ${name} name) |
||
| 1955 | add_lit_target(${target} |
||
| 1956 | "Running ${name} regression tests" |
||
| 1957 | ${testsuites} |
||
| 1958 | PARAMS ${params} |
||
| 1959 | DEPENDS ${depends} ${additional_test_targets} |
||
| 1960 | ARGS ${extra_args} |
||
| 1961 | ) |
||
| 1962 | endfunction() |
||
| 1963 | |||
| 1964 | # A function to add a set of lit test suites to be driven through 'check-*' targets. |
||
| 1965 | function(add_lit_testsuite target comment) |
||
| 1966 | cmake_parse_arguments(ARG "EXCLUDE_FROM_CHECK_ALL" "" "PARAMS;DEPENDS;ARGS" ${ARGN}) |
||
| 1967 | |||
| 1968 | # EXCLUDE_FROM_ALL excludes the test ${target} out of check-all. |
||
| 1969 | if(NOT ARG_EXCLUDE_FROM_CHECK_ALL) |
||
| 1970 | get_property(gather_names GLOBAL PROPERTY LLVM_LIT_UMBRELLAS) |
||
| 1971 | foreach(name ${gather_names}) |
||
| 1972 | # Register the testsuites, params and depends for the umbrella check rule. |
||
| 1973 | set_property(GLOBAL APPEND PROPERTY LLVM_${name}_LIT_TESTSUITES ${ARG_UNPARSED_ARGUMENTS}) |
||
| 1974 | set_property(GLOBAL APPEND PROPERTY LLVM_${name}_LIT_PARAMS ${ARG_PARAMS}) |
||
| 1975 | set_property(GLOBAL APPEND PROPERTY LLVM_${name}_LIT_DEPENDS ${ARG_DEPENDS}) |
||
| 1976 | set_property(GLOBAL APPEND PROPERTY LLVM_${name}_LIT_EXTRA_ARGS ${ARG_ARGS}) |
||
| 1977 | endforeach() |
||
| 1978 | endif() |
||
| 1979 | |||
| 1980 | # Produce a specific suffixed check rule. |
||
| 1981 | add_lit_target(${target} ${comment} |
||
| 1982 | ${ARG_UNPARSED_ARGUMENTS} |
||
| 1983 | PARAMS ${ARG_PARAMS} |
||
| 1984 | DEPENDS ${ARG_DEPENDS} |
||
| 1985 | ARGS ${ARG_ARGS} |
||
| 1986 | ) |
||
| 1987 | endfunction() |
||
| 1988 | |||
| 1989 | function(add_lit_testsuites project directory) |
||
| 1990 | if (NOT LLVM_ENABLE_IDE) |
||
| 1991 | cmake_parse_arguments(ARG "EXCLUDE_FROM_CHECK_ALL" "FOLDER" "PARAMS;DEPENDS;ARGS" ${ARGN}) |
||
| 1992 | |||
| 1993 | if (NOT ARG_FOLDER) |
||
| 1994 | set(ARG_FOLDER "Test Subdirectories") |
||
| 1995 | endif() |
||
| 1996 | |||
| 1997 | # Search recursively for test directories by assuming anything not |
||
| 1998 | # in a directory called Inputs contains tests. |
||
| 1999 | file(GLOB_RECURSE to_process LIST_DIRECTORIES true ${directory}/*) |
||
| 2000 | foreach(lit_suite ${to_process}) |
||
| 2001 | if(NOT IS_DIRECTORY ${lit_suite}) |
||
| 2002 | continue() |
||
| 2003 | endif() |
||
| 2004 | string(FIND ${lit_suite} Inputs is_inputs) |
||
| 2005 | string(FIND ${lit_suite} Output is_output) |
||
| 2006 | if (NOT (is_inputs EQUAL -1 AND is_output EQUAL -1)) |
||
| 2007 | continue() |
||
| 2008 | endif() |
||
| 2009 | |||
| 2010 | # Create a check- target for the directory. |
||
| 2011 | string(REPLACE ${directory} "" name_slash ${lit_suite}) |
||
| 2012 | if (name_slash) |
||
| 2013 | string(REPLACE "/" "-" name_slash ${name_slash}) |
||
| 2014 | string(REPLACE "\\" "-" name_dashes ${name_slash}) |
||
| 2015 | string(TOLOWER "${project}${name_dashes}" name_var) |
||
| 2016 | add_lit_target("check-${name_var}" "Running lit suite ${lit_suite}" |
||
| 2017 | ${lit_suite} |
||
| 2018 | ${EXCLUDE_FROM_CHECK_ALL} |
||
| 2019 | PARAMS ${ARG_PARAMS} |
||
| 2020 | DEPENDS ${ARG_DEPENDS} |
||
| 2021 | ARGS ${ARG_ARGS} |
||
| 2022 | ) |
||
| 2023 | set_target_properties(check-${name_var} PROPERTIES FOLDER ${ARG_FOLDER}) |
||
| 2024 | endif() |
||
| 2025 | endforeach() |
||
| 2026 | endif() |
||
| 2027 | endfunction() |
||
| 2028 | |||
| 2029 | function(llvm_install_library_symlink name dest type) |
||
| 2030 | cmake_parse_arguments(ARG "" "COMPONENT" "" ${ARGN}) |
||
| 2031 | foreach(path ${CMAKE_MODULE_PATH}) |
||
| 2032 | if(EXISTS ${path}/LLVMInstallSymlink.cmake) |
||
| 2033 | set(INSTALL_SYMLINK ${path}/LLVMInstallSymlink.cmake) |
||
| 2034 | break() |
||
| 2035 | endif() |
||
| 2036 | endforeach() |
||
| 2037 | |||
| 2038 | set(component ${ARG_COMPONENT}) |
||
| 2039 | if(NOT component) |
||
| 2040 | set(component ${name}) |
||
| 2041 | endif() |
||
| 2042 | |||
| 2043 | set(full_name ${CMAKE_${type}_LIBRARY_PREFIX}${name}${CMAKE_${type}_LIBRARY_SUFFIX}) |
||
| 2044 | set(full_dest ${CMAKE_${type}_LIBRARY_PREFIX}${dest}${CMAKE_${type}_LIBRARY_SUFFIX}) |
||
| 2045 | |||
| 2046 | set(output_dir lib${LLVM_LIBDIR_SUFFIX}) |
||
| 2047 | if(WIN32 AND "${type}" STREQUAL "SHARED") |
||
| 2048 | set(output_dir "${CMAKE_INSTALL_BINDIR}") |
||
| 2049 | endif() |
||
| 2050 | |||
| 2051 | install(SCRIPT ${INSTALL_SYMLINK} |
||
| 2052 | CODE "install_symlink(\"${full_name}\" \"${full_dest}\" \"${output_dir}\")" |
||
| 2053 | COMPONENT ${component}) |
||
| 2054 | |||
| 2055 | endfunction() |
||
| 2056 | |||
| 2057 | function(llvm_install_symlink project name dest) |
||
| 2058 | get_property(LLVM_DRIVER_TOOLS GLOBAL PROPERTY LLVM_DRIVER_TOOLS) |
||
| 2059 | if(LLVM_TOOL_LLVM_DRIVER_BUILD |
||
| 2060 | AND ${dest} IN_LIST LLVM_DRIVER_TOOLS |
||
| 2061 | AND (NOT LLVM_DISTRIBUTION_COMPONENTS OR ${dest} IN_LIST LLVM_DISTRIBUTION_COMPONENTS) |
||
| 2062 | ) |
||
| 2063 | return() |
||
| 2064 | endif() |
||
| 2065 | cmake_parse_arguments(ARG "ALWAYS_GENERATE" "COMPONENT" "" ${ARGN}) |
||
| 2066 | foreach(path ${CMAKE_MODULE_PATH}) |
||
| 2067 | if(EXISTS ${path}/LLVMInstallSymlink.cmake) |
||
| 2068 | set(INSTALL_SYMLINK ${path}/LLVMInstallSymlink.cmake) |
||
| 2069 | break() |
||
| 2070 | endif() |
||
| 2071 | endforeach() |
||
| 2072 | |||
| 2073 | if(ARG_COMPONENT) |
||
| 2074 | set(component ${ARG_COMPONENT}) |
||
| 2075 | else() |
||
| 2076 | if(ARG_ALWAYS_GENERATE) |
||
| 2077 | set(component ${dest}) |
||
| 2078 | else() |
||
| 2079 | set(component ${name}) |
||
| 2080 | endif() |
||
| 2081 | endif() |
||
| 2082 | |||
| 2083 | set(full_name ${name}${CMAKE_EXECUTABLE_SUFFIX}) |
||
| 2084 | set(full_dest ${dest}${CMAKE_EXECUTABLE_SUFFIX}) |
||
| 2085 | if (${dest} STREQUAL "llvm-driver") |
||
| 2086 | set(full_dest llvm${CMAKE_EXECUTABLE_SUFFIX}) |
||
| 2087 | endif() |
||
| 2088 | |||
| 2089 | set(output_dir "${${project}_TOOLS_INSTALL_DIR}") |
||
| 2090 | |||
| 2091 | install(SCRIPT ${INSTALL_SYMLINK} |
||
| 2092 | CODE "install_symlink(\"${full_name}\" \"${full_dest}\" \"${output_dir}\")" |
||
| 2093 | COMPONENT ${component}) |
||
| 2094 | |||
| 2095 | if (NOT LLVM_ENABLE_IDE AND NOT ARG_ALWAYS_GENERATE) |
||
| 2096 | add_llvm_install_targets(install-${name} |
||
| 2097 | DEPENDS ${name} ${dest} |
||
| 2098 | COMPONENT ${name} |
||
| 2099 | SYMLINK ${dest}) |
||
| 2100 | endif() |
||
| 2101 | endfunction() |
||
| 2102 | |||
| 2103 | function(llvm_add_tool_symlink project link_name target) |
||
| 2104 | cmake_parse_arguments(ARG "ALWAYS_GENERATE" "OUTPUT_DIR" "" ${ARGN}) |
||
| 2105 | |||
| 2106 | get_property(LLVM_DRIVER_TOOLS GLOBAL PROPERTY LLVM_DRIVER_TOOLS) |
||
| 2107 | |||
| 2108 | if (${target} IN_LIST LLVM_DRIVER_TOOLS) |
||
| 2109 | set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_TOOL_ALIASES_${target} ${link_name}) |
||
| 2110 | endif() |
||
| 2111 | set(dest_binary "$<TARGET_FILE:${target}>") |
||
| 2112 | |||
| 2113 | # This got a bit gross... For multi-configuration generators the target |
||
| 2114 | # properties return the resolved value of the string, not the build system |
||
| 2115 | # expression. To reconstruct the platform-agnostic path we have to do some |
||
| 2116 | # magic. First we grab one of the types, and a type-specific path. Then from |
||
| 2117 | # the type-specific path we find the last occurrence of the type in the path, |
||
| 2118 | # and replace it with CMAKE_CFG_INTDIR. This allows the build step to be type |
||
| 2119 | # agnostic again. |
||
| 2120 | if(NOT ARG_OUTPUT_DIR) |
||
| 2121 | # If you're not overriding the OUTPUT_DIR, we can make the link relative in |
||
| 2122 | # the same directory. |
||
| 2123 | if(LLVM_USE_SYMLINKS) |
||
| 2124 | set(dest_binary "$<TARGET_FILE_NAME:${target}>") |
||
| 2125 | endif() |
||
| 2126 | if(CMAKE_CONFIGURATION_TYPES) |
||
| 2127 | list(GET CMAKE_CONFIGURATION_TYPES 0 first_type) |
||
| 2128 | string(TOUPPER ${first_type} first_type_upper) |
||
| 2129 | set(first_type_suffix _${first_type_upper}) |
||
| 2130 | endif() |
||
| 2131 | get_target_property(target_type ${target} TYPE) |
||
| 2132 | if(${target_type} STREQUAL "STATIC_LIBRARY") |
||
| 2133 | get_target_property(ARG_OUTPUT_DIR ${target} ARCHIVE_OUTPUT_DIRECTORY${first_type_suffix}) |
||
| 2134 | elseif(UNIX AND ${target_type} STREQUAL "SHARED_LIBRARY") |
||
| 2135 | get_target_property(ARG_OUTPUT_DIR ${target} LIBRARY_OUTPUT_DIRECTORY${first_type_suffix}) |
||
| 2136 | else() |
||
| 2137 | get_target_property(ARG_OUTPUT_DIR ${target} RUNTIME_OUTPUT_DIRECTORY${first_type_suffix}) |
||
| 2138 | endif() |
||
| 2139 | if(CMAKE_CONFIGURATION_TYPES) |
||
| 2140 | string(FIND "${ARG_OUTPUT_DIR}" "/${first_type}/" type_start REVERSE) |
||
| 2141 | string(SUBSTRING "${ARG_OUTPUT_DIR}" 0 ${type_start} path_prefix) |
||
| 2142 | string(SUBSTRING "${ARG_OUTPUT_DIR}" ${type_start} -1 path_suffix) |
||
| 2143 | string(REPLACE "/${first_type}/" "/${CMAKE_CFG_INTDIR}/" |
||
| 2144 | path_suffix ${path_suffix}) |
||
| 2145 | set(ARG_OUTPUT_DIR ${path_prefix}${path_suffix}) |
||
| 2146 | endif() |
||
| 2147 | endif() |
||
| 2148 | |||
| 2149 | if(LLVM_USE_SYMLINKS) |
||
| 2150 | set(LLVM_LINK_OR_COPY create_symlink) |
||
| 2151 | else() |
||
| 2152 | set(LLVM_LINK_OR_COPY copy) |
||
| 2153 | endif() |
||
| 2154 | |||
| 2155 | set(output_path "${ARG_OUTPUT_DIR}/${link_name}${CMAKE_EXECUTABLE_SUFFIX}") |
||
| 2156 | |||
| 2157 | set(target_name ${link_name}) |
||
| 2158 | if(TARGET ${link_name}) |
||
| 2159 | set(target_name ${link_name}-link) |
||
| 2160 | endif() |
||
| 2161 | |||
| 2162 | |||
| 2163 | if(ARG_ALWAYS_GENERATE) |
||
| 2164 | set_property(DIRECTORY APPEND PROPERTY |
||
| 2165 | ADDITIONAL_MAKE_CLEAN_FILES ${dest_binary}) |
||
| 2166 | add_custom_command(TARGET ${target} POST_BUILD |
||
| 2167 | COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${dest_binary}" "${output_path}") |
||
| 2168 | else() |
||
| 2169 | add_custom_command(OUTPUT ${output_path} |
||
| 2170 | COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${dest_binary}" "${output_path}" |
||
| 2171 | DEPENDS ${target}) |
||
| 2172 | |||
| 2173 | # TODO: Make use of generator expressions below once CMake 3.19 or higher is the minimum supported version. |
||
| 2174 | set(should_build_all) |
||
| 2175 | get_target_property(target_excluded_from_all ${target} EXCLUDE_FROM_ALL) |
||
| 2176 | if (NOT target_excluded_from_all) |
||
| 2177 | set(should_build_all ALL) |
||
| 2178 | endif() |
||
| 2179 | add_custom_target(${target_name} ${should_build_all} DEPENDS ${target} ${output_path}) |
||
| 2180 | set_target_properties(${target_name} PROPERTIES FOLDER Tools) |
||
| 2181 | |||
| 2182 | # Make sure both the link and target are toolchain tools |
||
| 2183 | if (${link_name} IN_LIST LLVM_TOOLCHAIN_TOOLS AND ${target} IN_LIST LLVM_TOOLCHAIN_TOOLS) |
||
| 2184 | set(TOOL_IS_TOOLCHAIN ON) |
||
| 2185 | endif() |
||
| 2186 | |||
| 2187 | if ((TOOL_IS_TOOLCHAIN OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY) AND LLVM_BUILD_TOOLS) |
||
| 2188 | llvm_install_symlink("${project}" ${link_name} ${target}) |
||
| 2189 | endif() |
||
| 2190 | endif() |
||
| 2191 | endfunction() |
||
| 2192 | |||
| 2193 | function(add_llvm_tool_symlink link_name target) |
||
| 2194 | llvm_add_tool_symlink(LLVM ${ARGV}) |
||
| 2195 | endfunction() |
||
| 2196 | |||
| 2197 | function(llvm_externalize_debuginfo name) |
||
| 2198 | if(NOT LLVM_EXTERNALIZE_DEBUGINFO) |
||
| 2199 | return() |
||
| 2200 | endif() |
||
| 2201 | |||
| 2202 | if(NOT LLVM_EXTERNALIZE_DEBUGINFO_SKIP_STRIP) |
||
| 2203 | if(APPLE) |
||
| 2204 | if(NOT CMAKE_STRIP) |
||
| 2205 | set(CMAKE_STRIP xcrun strip) |
||
| 2206 | endif() |
||
| 2207 | set(strip_command COMMAND ${CMAKE_STRIP} -S -x $<TARGET_FILE:${name}>) |
||
| 2208 | else() |
||
| 2209 | set(strip_command COMMAND ${CMAKE_STRIP} -g -x $<TARGET_FILE:${name}>) |
||
| 2210 | endif() |
||
| 2211 | endif() |
||
| 2212 | |||
| 2213 | if(APPLE) |
||
| 2214 | if(LLVM_EXTERNALIZE_DEBUGINFO_EXTENSION) |
||
| 2215 | set(file_ext ${LLVM_EXTERNALIZE_DEBUGINFO_EXTENSION}) |
||
| 2216 | else() |
||
| 2217 | set(file_ext dSYM) |
||
| 2218 | endif() |
||
| 2219 | |||
| 2220 | set(output_name "$<TARGET_FILE_NAME:${name}>.${file_ext}") |
||
| 2221 | |||
| 2222 | if(LLVM_EXTERNALIZE_DEBUGINFO_OUTPUT_DIR) |
||
| 2223 | set(output_path "-o=${LLVM_EXTERNALIZE_DEBUGINFO_OUTPUT_DIR}/${output_name}") |
||
| 2224 | else() |
||
| 2225 | set(output_path "-o=${output_name}") |
||
| 2226 | endif() |
||
| 2227 | |||
| 2228 | if(CMAKE_CXX_FLAGS MATCHES "-flto" |
||
| 2229 | OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto") |
||
| 2230 | |||
| 2231 | set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o) |
||
| 2232 | set_property(TARGET ${name} APPEND_STRING PROPERTY |
||
| 2233 | LINK_FLAGS " -Wl,-object_path_lto,${lto_object}") |
||
| 2234 | endif() |
||
| 2235 | if(NOT CMAKE_DSYMUTIL) |
||
| 2236 | set(CMAKE_DSYMUTIL xcrun dsymutil) |
||
| 2237 | endif() |
||
| 2238 | add_custom_command(TARGET ${name} POST_BUILD |
||
| 2239 | COMMAND ${CMAKE_DSYMUTIL} ${output_path} $<TARGET_FILE:${name}> |
||
| 2240 | ${strip_command} |
||
| 2241 | ) |
||
| 2242 | else() |
||
| 2243 | add_custom_command(TARGET ${name} POST_BUILD |
||
| 2244 | COMMAND ${CMAKE_OBJCOPY} --only-keep-debug $<TARGET_FILE:${name}> $<TARGET_FILE:${name}>.debug |
||
| 2245 | ${strip_command} -R .gnu_debuglink |
||
| 2246 | COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE:${name}>.debug $<TARGET_FILE:${name}> |
||
| 2247 | ) |
||
| 2248 | endif() |
||
| 2249 | endfunction() |
||
| 2250 | |||
| 2251 | # Usage: llvm_codesign(name [FORCE] [ENTITLEMENTS file] [BUNDLE_PATH path]) |
||
| 2252 | function(llvm_codesign name) |
||
| 2253 | cmake_parse_arguments(ARG "FORCE" "ENTITLEMENTS;BUNDLE_PATH" "" ${ARGN}) |
||
| 2254 | |||
| 2255 | if(NOT LLVM_CODESIGNING_IDENTITY) |
||
| 2256 | return() |
||
| 2257 | endif() |
||
| 2258 | |||
| 2259 | if(CMAKE_GENERATOR STREQUAL "Xcode") |
||
| 2260 | set_target_properties(${name} PROPERTIES |
||
| 2261 | XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ${LLVM_CODESIGNING_IDENTITY} |
||
| 2262 | ) |
||
| 2263 | if(DEFINED ARG_ENTITLEMENTS) |
||
| 2264 | set_target_properties(${name} PROPERTIES |
||
| 2265 | XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${ARG_ENTITLEMENTS} |
||
| 2266 | ) |
||
| 2267 | endif() |
||
| 2268 | elseif(APPLE AND CMAKE_HOST_SYSTEM_NAME MATCHES Darwin) |
||
| 2269 | if(NOT CMAKE_CODESIGN) |
||
| 2270 | set(CMAKE_CODESIGN xcrun codesign) |
||
| 2271 | endif() |
||
| 2272 | if(NOT CMAKE_CODESIGN_ALLOCATE) |
||
| 2273 | execute_process( |
||
| 2274 | COMMAND xcrun -f codesign_allocate |
||
| 2275 | OUTPUT_STRIP_TRAILING_WHITESPACE |
||
| 2276 | OUTPUT_VARIABLE CMAKE_CODESIGN_ALLOCATE |
||
| 2277 | ) |
||
| 2278 | endif() |
||
| 2279 | if(DEFINED ARG_ENTITLEMENTS) |
||
| 2280 | set(pass_entitlements --entitlements ${ARG_ENTITLEMENTS}) |
||
| 2281 | endif() |
||
| 2282 | |||
| 2283 | if (NOT ARG_BUNDLE_PATH) |
||
| 2284 | set(ARG_BUNDLE_PATH $<TARGET_FILE:${name}>) |
||
| 2285 | endif() |
||
| 2286 | |||
| 2287 | # ld64 now always codesigns the binaries it creates. Apply the force arg |
||
| 2288 | # unconditionally so that we can - for example - add entitlements to the |
||
| 2289 | # targets that need it. |
||
| 2290 | set(force_flag "-f") |
||
| 2291 | |||
| 2292 | add_custom_command( |
||
| 2293 | TARGET ${name} POST_BUILD |
||
| 2294 | COMMAND ${CMAKE_COMMAND} -E |
||
| 2295 | env CODESIGN_ALLOCATE=${CMAKE_CODESIGN_ALLOCATE} |
||
| 2296 | ${CMAKE_CODESIGN} -s ${LLVM_CODESIGNING_IDENTITY} |
||
| 2297 | ${pass_entitlements} ${force_flag} ${ARG_BUNDLE_PATH} |
||
| 2298 | ) |
||
| 2299 | endif() |
||
| 2300 | endfunction() |
||
| 2301 | |||
| 2302 | function(llvm_setup_rpath name) |
||
| 2303 | if(CMAKE_INSTALL_RPATH) |
||
| 2304 | return() |
||
| 2305 | endif() |
||
| 2306 | |||
| 2307 | if(LLVM_INSTALL_PREFIX AND NOT (LLVM_INSTALL_PREFIX STREQUAL CMAKE_INSTALL_PREFIX)) |
||
| 2308 | set(extra_libdir ${LLVM_LIBRARY_DIR}) |
||
| 2309 | elseif(LLVM_BUILD_LIBRARY_DIR) |
||
| 2310 | set(extra_libdir ${LLVM_LIBRARY_DIR}) |
||
| 2311 | endif() |
||
| 2312 | |||
| 2313 | if (APPLE) |
||
| 2314 | set(_install_name_dir INSTALL_NAME_DIR "@rpath") |
||
| 2315 | set(_install_rpath "@loader_path/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) |
||
| 2316 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "AIX" AND BUILD_SHARED_LIBS) |
||
| 2317 | # $ORIGIN is not interpreted at link time by aix ld. |
||
| 2318 | # Since BUILD_SHARED_LIBS is only recommended for use by developers, |
||
| 2319 | # hardcode the rpath to build/install lib dir first in this mode. |
||
| 2320 | # FIXME: update this when there is better solution. |
||
| 2321 | set(_install_rpath "${LLVM_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) |
||
| 2322 | elseif(UNIX) |
||
| 2323 | set(_build_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) |
||
| 2324 | set(_install_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}") |
||
| 2325 | if(${CMAKE_SYSTEM_NAME} MATCHES "(FreeBSD|DragonFly)") |
||
| 2326 | set_property(TARGET ${name} APPEND_STRING PROPERTY |
||
| 2327 | LINK_FLAGS " -Wl,-z,origin ") |
||
| 2328 | endif() |
||
| 2329 | if(LLVM_LINKER_IS_GNULD) |
||
| 2330 | # $ORIGIN is not interpreted at link time by ld.bfd |
||
| 2331 | set_property(TARGET ${name} APPEND_STRING PROPERTY |
||
| 2332 | LINK_FLAGS " -Wl,-rpath-link,${LLVM_LIBRARY_OUTPUT_INTDIR} ") |
||
| 2333 | endif() |
||
| 2334 | else() |
||
| 2335 | return() |
||
| 2336 | endif() |
||
| 2337 | |||
| 2338 | # Enable BUILD_WITH_INSTALL_RPATH unless CMAKE_BUILD_RPATH is set and not |
||
| 2339 | # building for macOS or AIX, as those platforms seemingly require it. |
||
| 2340 | # On AIX, the tool chain doesn't support modifying rpaths/libpaths for XCOFF |
||
| 2341 | # on install at the moment, so BUILD_WITH_INSTALL_RPATH is required. |
||
| 2342 | if("${CMAKE_BUILD_RPATH}" STREQUAL "") |
||
| 2343 | if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin|AIX") |
||
| 2344 | set_property(TARGET ${name} PROPERTY BUILD_WITH_INSTALL_RPATH ON) |
||
| 2345 | else() |
||
| 2346 | set_property(TARGET ${name} APPEND PROPERTY BUILD_RPATH "${_build_rpath}") |
||
| 2347 | endif() |
||
| 2348 | endif() |
||
| 2349 | |||
| 2350 | set_target_properties(${name} PROPERTIES |
||
| 2351 | INSTALL_RPATH "${_install_rpath}" |
||
| 2352 | ${_install_name_dir}) |
||
| 2353 | endfunction() |
||
| 2354 | |||
| 2355 | function(setup_dependency_debugging name) |
||
| 2356 | if(NOT LLVM_DEPENDENCY_DEBUGGING) |
||
| 2357 | return() |
||
| 2358 | endif() |
||
| 2359 | |||
| 2360 | if("intrinsics_gen" IN_LIST ARGN) |
||
| 2361 | return() |
||
| 2362 | endif() |
||
| 2363 | |||
| 2364 | set(deny_attributes_inc "(deny file* (literal \"${LLVM_BINARY_DIR}/include/llvm/IR/Attributes.inc\"))") |
||
| 2365 | set(deny_intrinsics_inc "(deny file* (literal \"${LLVM_BINARY_DIR}/include/llvm/IR/Intrinsics.inc\"))") |
||
| 2366 | |||
| 2367 | set(sandbox_command "sandbox-exec -p '(version 1) (allow default) ${deny_attributes_inc} ${deny_intrinsics_inc}'") |
||
| 2368 | set_target_properties(${name} PROPERTIES RULE_LAUNCH_COMPILE ${sandbox_command}) |
||
| 2369 | endfunction() |
||
| 2370 | |||
| 2371 | # If the sources at the given `path` are under version control, set `out_var` |
||
| 2372 | # to the the path of a file which will be modified when the VCS revision |
||
| 2373 | # changes, attempting to create that file if it does not exist; if no such |
||
| 2374 | # file exists and one cannot be created, instead set `out_var` to the |
||
| 2375 | # empty string. |
||
| 2376 | # |
||
| 2377 | # If the sources are not under version control, do not define `out_var`. |
||
| 2378 | function(find_first_existing_vc_file path out_var) |
||
| 2379 | if(NOT EXISTS "${path}") |
||
| 2380 | return() |
||
| 2381 | endif() |
||
| 2382 | find_package(Git) |
||
| 2383 | if(GIT_FOUND) |
||
| 2384 | execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir |
||
| 2385 | WORKING_DIRECTORY ${path} |
||
| 2386 | RESULT_VARIABLE git_result |
||
| 2387 | OUTPUT_VARIABLE git_output |
||
| 2388 | ERROR_QUIET) |
||
| 2389 | if(git_result EQUAL 0) |
||
| 2390 | string(STRIP "${git_output}" git_output) |
||
| 2391 | get_filename_component(git_dir ${git_output} ABSOLUTE BASE_DIR ${path}) |
||
| 2392 | # Some branchless cases (e.g. 'repo') may not yet have .git/logs/HEAD |
||
| 2393 | if (NOT EXISTS "${git_dir}/logs/HEAD") |
||
| 2394 | execute_process(COMMAND ${CMAKE_COMMAND} -E touch HEAD |
||
| 2395 | WORKING_DIRECTORY "${git_dir}/logs" |
||
| 2396 | RESULT_VARIABLE touch_head_result |
||
| 2397 | ERROR_QUIET) |
||
| 2398 | if (NOT touch_head_result EQUAL 0) |
||
| 2399 | set(${out_var} "" PARENT_SCOPE) |
||
| 2400 | return() |
||
| 2401 | endif() |
||
| 2402 | endif() |
||
| 2403 | set(${out_var} "${git_dir}/logs/HEAD" PARENT_SCOPE) |
||
| 2404 | endif() |
||
| 2405 | endif() |
||
| 2406 | endfunction() |
||
| 2407 | |||
| 2408 | function(setup_host_tool tool_name setting_name exe_var_name target_var_name) |
||
| 2409 | set(${setting_name}_DEFAULT "${tool_name}") |
||
| 2410 | |||
| 2411 | if(LLVM_NATIVE_TOOL_DIR) |
||
| 2412 | if(EXISTS "${LLVM_NATIVE_TOOL_DIR}/${tool_name}${LLVM_HOST_EXECUTABLE_SUFFIX}") |
||
| 2413 | set(${setting_name}_DEFAULT "${LLVM_NATIVE_TOOL_DIR}/${tool_name}${LLVM_HOST_EXECUTABLE_SUFFIX}") |
||
| 2414 | endif() |
||
| 2415 | endif() |
||
| 2416 | |||
| 2417 | set(${setting_name} "${${setting_name}_DEFAULT}" CACHE |
||
| 2418 | STRING "Host ${tool_name} executable. Saves building if cross-compiling.") |
||
| 2419 | |||
| 2420 | if(NOT ${setting_name} STREQUAL "${tool_name}") |
||
| 2421 | set(exe_name ${${setting_name}}) |
||
| 2422 | set(target_name ${${setting_name}}) |
||
| 2423 | elseif(LLVM_USE_HOST_TOOLS) |
||
| 2424 | build_native_tool(${tool_name} exe_name DEPENDS ${tool_name}) |
||
| 2425 | set(target_name ${exe_name}) |
||
| 2426 | else() |
||
| 2427 | set(exe_name $<TARGET_FILE:${tool_name}>) |
||
| 2428 | set(target_name ${tool_name}) |
||
| 2429 | endif() |
||
| 2430 | set(${exe_var_name} "${exe_name}" CACHE STRING "") |
||
| 2431 | set(${target_var_name} "${target_name}" CACHE STRING "") |
||
| 2432 | endfunction() |