117e53983SLouis Dionne# Check if the compiler-rt library file path exists. 222acda48SPetr Hosek# If found, cache the path in: 322acda48SPetr Hosek# COMPILER_RT_LIBRARY-<name>-<target> 422acda48SPetr Hosek# If err_flag is true OR path not found, emit a message and set: 522acda48SPetr Hosek# COMPILER_RT_LIBRARY-<name>-<target> to NOTFOUND 622acda48SPetr Hosekfunction(cache_compiler_rt_library err_flag name target library_file) 722acda48SPetr Hosek if(err_flag OR NOT EXISTS "${library_file}") 8*cb445e8dSLouis Dionne message(WARNING "Failed to find compiler-rt ${name} library for ${target}") 922acda48SPetr Hosek set(COMPILER_RT_LIBRARY_${name}_${target} "NOTFOUND" CACHE INTERNAL 1022acda48SPetr Hosek "compiler-rt ${name} library for ${target}") 1122acda48SPetr Hosek else() 1222acda48SPetr Hosek message(STATUS "Found compiler-rt ${name} library: ${library_file}") 1322acda48SPetr Hosek set(COMPILER_RT_LIBRARY_${name}_${target} "${library_file}" CACHE INTERNAL 1422acda48SPetr Hosek "compiler-rt ${name} library for ${target}") 1522acda48SPetr Hosek endif() 1622acda48SPetr Hosekendfunction() 1722acda48SPetr Hosek 1822acda48SPetr Hosekfunction(get_component_name name variable) 1922acda48SPetr Hosek if(APPLE) 2022acda48SPetr Hosek if(NOT name MATCHES "builtins.*") 2122acda48SPetr Hosek set(component_name "${name}_") 2222acda48SPetr Hosek endif() 238907302fSLouis Dionne if (CMAKE_OSX_SYSROOT MATCHES ".+MacOSX.+") 2422acda48SPetr Hosek set(component_name "${component_name}osx") 258907302fSLouis Dionne 268907302fSLouis Dionne elseif (CMAKE_OSX_SYSROOT MATCHES ".+iPhoneOS.+") 278907302fSLouis Dionne set(component_name "${component_name}ios") 288907302fSLouis Dionne elseif (CMAKE_OSX_SYSROOT MATCHES ".+iPhoneSimulator.+") 298907302fSLouis Dionne set(component_name "${component_name}iossim") 308907302fSLouis Dionne 318907302fSLouis Dionne elseif (CMAKE_OSX_SYSROOT MATCHES ".+AppleTVOS.+") 328907302fSLouis Dionne set(component_name "${component_name}tvos") 338907302fSLouis Dionne elseif (CMAKE_OSX_SYSROOT MATCHES ".+AppleTVSimulator.+") 348907302fSLouis Dionne set(component_name "${component_name}tvossim") 358907302fSLouis Dionne 368907302fSLouis Dionne elseif (CMAKE_OSX_SYSROOT MATCHES ".+WatchOS.+") 378907302fSLouis Dionne set(component_name "${component_name}watchos") 388907302fSLouis Dionne elseif (CMAKE_OSX_SYSROOT MATCHES ".+WatchSimulator.+") 398907302fSLouis Dionne set(component_name "${component_name}watchossim") 408907302fSLouis Dionne else() 4101dbd551SLouis Dionne message(WARNING "Unknown Apple SDK ${CMAKE_OSX_SYSROOT}, we don't know which compiler-rt library suffix to use.") 428907302fSLouis Dionne endif() 4322acda48SPetr Hosek else() 4422acda48SPetr Hosek set(component_name "${name}") 4522acda48SPetr Hosek endif() 4622acda48SPetr Hosek set(${variable} "${component_name}" PARENT_SCOPE) 4722acda48SPetr Hosekendfunction() 4822acda48SPetr Hosek 4922acda48SPetr Hosek# Find the path to compiler-rt library `name` (e.g. "builtins") for the 5022acda48SPetr Hosek# specified `TARGET` (e.g. "x86_64-linux-gnu") and return it in `variable`. 5122acda48SPetr Hosek# This calls cache_compiler_rt_library that caches the path to speed up 5222acda48SPetr Hosek# repeated invocations with the same `name` and `target`. 5322acda48SPetr Hosekfunction(find_compiler_rt_library name variable) 5426a4edf6SPetr Hosek cmake_parse_arguments(ARG "SHARED" "TARGET;FLAGS" "" ${ARGN}) 5522acda48SPetr Hosek # While we can use compiler-rt runtimes with other compilers, we need to 5622acda48SPetr Hosek # query the compiler for runtime location and thus we require Clang. 5722acda48SPetr Hosek if(NOT CMAKE_CXX_COMPILER_ID MATCHES Clang) 5822acda48SPetr Hosek set(${variable} "NOTFOUND" PARENT_SCOPE) 5922acda48SPetr Hosek return() 6022acda48SPetr Hosek endif() 6122acda48SPetr Hosek set(target "${ARG_TARGET}") 6222acda48SPetr Hosek if(NOT target AND CMAKE_CXX_COMPILER_TARGET) 6322acda48SPetr Hosek set(target "${CMAKE_CXX_COMPILER_TARGET}") 6422acda48SPetr Hosek endif() 6522acda48SPetr Hosek if(NOT DEFINED COMPILER_RT_LIBRARY_builtins_${target}) 6622acda48SPetr Hosek # If the cache variable is not defined, invoke Clang and then 6722acda48SPetr Hosek # set it with cache_compiler_rt_library. 6822acda48SPetr Hosek set(clang_command ${CMAKE_CXX_COMPILER} "${ARG_FLAGS}") 6922acda48SPetr Hosek if(target) 7022acda48SPetr Hosek list(APPEND clang_command "--target=${target}") 7122acda48SPetr Hosek endif() 7222acda48SPetr Hosek get_property(cxx_flags CACHE CMAKE_CXX_FLAGS PROPERTY VALUE) 7322acda48SPetr Hosek string(REPLACE " " ";" cxx_flags "${cxx_flags}") 7422acda48SPetr Hosek list(APPEND clang_command ${cxx_flags}) 7545ab1904STobias Hieta set(cmd_prefix "") 7645ab1904STobias Hieta if(MSVC AND ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") 7745ab1904STobias Hieta set(cmd_prefix "/clang:") 7845ab1904STobias Hieta endif() 7922acda48SPetr Hosek execute_process( 8045ab1904STobias Hieta COMMAND ${clang_command} "${cmd_prefix}--rtlib=compiler-rt" "${cmd_prefix}-print-libgcc-file-name" 8122acda48SPetr Hosek RESULT_VARIABLE had_error 8222acda48SPetr Hosek OUTPUT_VARIABLE library_file 8322acda48SPetr Hosek ) 8422acda48SPetr Hosek string(STRIP "${library_file}" library_file) 8522acda48SPetr Hosek file(TO_CMAKE_PATH "${library_file}" library_file) 8622acda48SPetr Hosek get_filename_component(dirname ${library_file} DIRECTORY) 8722acda48SPetr Hosek if(APPLE) 8822acda48SPetr Hosek execute_process( 8922acda48SPetr Hosek COMMAND ${clang_command} "--print-resource-dir" 9022acda48SPetr Hosek RESULT_VARIABLE had_error 9122acda48SPetr Hosek OUTPUT_VARIABLE resource_dir 9222acda48SPetr Hosek ) 9322acda48SPetr Hosek string(STRIP "${resource_dir}" resource_dir) 9422acda48SPetr Hosek set(dirname "${resource_dir}/lib/darwin") 9522acda48SPetr Hosek endif() 9622acda48SPetr Hosek get_filename_component(basename ${library_file} NAME) 9745ab1904STobias Hieta if(basename MATCHES ".*clang_rt\.([a-z0-9_\-]+)\.(a|lib)") 9822acda48SPetr Hosek set(from_name ${CMAKE_MATCH_1}) 9922acda48SPetr Hosek get_component_name(${CMAKE_MATCH_1} to_name) 10022acda48SPetr Hosek string(REPLACE "${from_name}" "${to_name}" basename "${basename}") 10122acda48SPetr Hosek set(library_file "${dirname}/${basename}") 10222acda48SPetr Hosek cache_compiler_rt_library(${had_error} builtins "${target}" "${library_file}") 10322acda48SPetr Hosek endif() 10422acda48SPetr Hosek endif() 10522acda48SPetr Hosek if(NOT COMPILER_RT_LIBRARY_builtins_${target}) 10622acda48SPetr Hosek set(${variable} "NOTFOUND" PARENT_SCOPE) 10722acda48SPetr Hosek return() 10822acda48SPetr Hosek endif() 10922acda48SPetr Hosek if(NOT DEFINED COMPILER_RT_LIBRARY_${name}_${target}) 11022acda48SPetr Hosek # Clang gives only the builtins library path. Other library paths are 11122acda48SPetr Hosek # obtained by substituting "builtins" with ${name} in the builtins 11222acda48SPetr Hosek # path and then checking if the resultant path exists. The result of 11322acda48SPetr Hosek # this check is also cached by cache_compiler_rt_library. 11422acda48SPetr Hosek set(library_file "${COMPILER_RT_LIBRARY_builtins_${target}}") 11526a4edf6SPetr Hosek get_component_name("builtins" from_name) 11622acda48SPetr Hosek get_component_name(${name} to_name) 11726a4edf6SPetr Hosek get_filename_component(basename ${library_file} NAME) 11826a4edf6SPetr Hosek string(REPLACE "${from_name}" "${to_name}" basename "${basename}") 11926a4edf6SPetr Hosek if (ARG_SHARED) 12026a4edf6SPetr Hosek string(REGEX REPLACE "\.(a|lib)$" ".so" basename "${basename}") 12122acda48SPetr Hosek endif() 12226a4edf6SPetr Hosek get_filename_component(dirname ${library_file} DIRECTORY) 12326a4edf6SPetr Hosek set(library_file "${dirname}/${basename}") 12426a4edf6SPetr Hosek cache_compiler_rt_library(FALSE "${name}" "${target}" "${library_file}") 12522acda48SPetr Hosek endif() 12622acda48SPetr Hosek set(${variable} "${COMPILER_RT_LIBRARY_${name}_${target}}" PARENT_SCOPE) 12722acda48SPetr Hosekendfunction() 128