athena/atdna/FindLLVM.cmake

217 lines
9.5 KiB
CMake

# - Find LLVM headers and libraries.
# This module locates LLVM and adapts the llvm-config output for use with
# CMake.
#
# A given list of COMPONENTS is passed to llvm-config.
#
# The following variables are defined:
# LLVM_FOUND - true if LLVM was found
# LLVM_CXXFLAGS - C++ compiler flags for files that include LLVM headers.
# LLVM_HOST_TARGET - Target triple used to configure LLVM.
# LLVM_INCLUDE_DIRS - Directory containing LLVM include files.
# LLVM_LDFLAGS - Linker flags to add when linking against LLVM
# (includes -LLLVM_LIBRARY_DIRS).
# LLVM_LIBRARIES - Full paths to the library files to link against.
# LLVM_LIBRARY_DIRS - Directory containing LLVM libraries.
# LLVM_ROOT_DIR - The root directory of the LLVM installation.
# llvm-config is searched for in ${LLVM_ROOT_DIR}/bin.
# LLVM_VERSION_MAJOR - Major version of LLVM.
# LLVM_VERSION_MINOR - Minor version of LLVM.
# LLVM_VERSION_STRING - Full LLVM version string (e.g. 2.9).
#
# Note: The variable names were chosen in conformance with the offical CMake
# guidelines, see ${CMAKE_ROOT}/Modules/readme.txt.
# Try suffixed versions to pick up the newest LLVM install available on Debian
# derivatives.
# We also want an user-specified LLVM_ROOT_DIR to take precedence over the
# system default locations such as /usr/local/bin. Executing find_program()
# multiples times is the approach recommended in the docs.
set(LLVM_ROOT_DIR "" CACHE PATH "Location of LLVM development root")
set(LLVM_FIND_COMPONENTS "")
if(WIN32)
get_filename_component(LLVM_ROOT_DIR [HKEY_LOCAL_MACHINE\\Software\\LLVM\\LLVM] ABSOLUTE)
endif()
set(llvm_config_names llvm-config-3.9 llvm-config39
llvm-config-3.8 llvm-config38
llvm-config-3.7 llvm-config37
llvm-config-3.6 llvm-config36
llvm-config-3.5 llvm-config35
llvm-config-3.4 llvm-config34
llvm-config-3.3 llvm-config33
llvm-config-3.2 llvm-config32
llvm-config-3.1 llvm-config31 llvm-config)
if(APPLE AND CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
set(LLVM_HOMEBREW_PATH /usr/local/opt/llvm/bin)
elseif(APPLE AND CMAKE_SYSTEM_PROCESSOR STREQUAL arm64)
set(LLVM_HOMEBREW_PATH /opt/homebrew/opt/llvm/bin)
else()
set(LLVM_HOMEBREW_PATH "")
endif()
find_program(LLVM_CONFIG
NAMES ${llvm_config_names}
PATHS ${LLVM_ROOT_DIR}/bin ${LLVM_HOMEBREW_PATH} NO_DEFAULT_PATH
DOC "Path to llvm-config tool.")
find_program(LLVM_CONFIG NAMES ${llvm_config_names})
if ((WIN32 AND NOT(MINGW OR CYGWIN)) OR NOT LLVM_CONFIG)
if (WIN32)
# A bit of a sanity check:
if( NOT EXISTS ${LLVM_ROOT_DIR}/include/llvm )
message(FATAL_ERROR "LLVM_ROOT_DIR (${LLVM_ROOT_DIR}) is not a valid LLVM install")
endif()
# We incorporate the CMake features provided by LLVM:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
"${LLVM_ROOT_DIR}/share/llvm/cmake"
"${LLVM_ROOT_DIR}/lib/cmake/llvm")
include(LLVMConfig)
# Set properties
set(LLVM_HOST_TARGET ${TARGET_TRIPLE})
set(LLVM_VERSION_STRING ${LLVM_PACKAGE_VERSION})
set(LLVM_CXXFLAGS ${LLVM_DEFINITIONS})
set(LLVM_LDFLAGS "")
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "all-targets" index)
list(APPEND LLVM_FIND_COMPONENTS ${LLVM_TARGETS_TO_BUILD})
# Work around LLVM bug 21016
list(FIND LLVM_TARGETS_TO_BUILD "X86" TARGET_X86)
if(TARGET_X86 GREATER -1)
list(APPEND LLVM_FIND_COMPONENTS x86utils)
endif()
# Similar to the work around above, but for AArch64
list(FIND LLVM_TARGETS_TO_BUILD "AArch64" TARGET_AArch64)
if(TARGET_AArch64 GREATER -1)
list(APPEND LLVM_FIND_COMPONENTS AArch64Utils)
endif()
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "backend" index)
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-2][\\.0-9A-Za-z]*")
# Versions below 3.3 do not support components objcarcopts, option
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "objcarcopts" index)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "option" index)
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-4][\\.0-9A-Za-z]*")
# Versions below 3.5 do not support components lto, profiledata
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "lto" index)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "profiledata" index)
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-6][\\.0-9A-Za-z]*")
# Versions below 3.7 do not support components debuginfodwarf
# Only debuginfo is available
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfodwarf" index)
list(APPEND LLVM_FIND_COMPONENTS "debuginfo")
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-4][\\.0-9A-Za-z]*")
llvm_map_components_to_libraries(tmplibs ${LLVM_FIND_COMPONENTS})
else()
llvm_map_components_to_libnames(tmplibs ${LLVM_FIND_COMPONENTS})
endif()
if(MSVC)
foreach(lib ${tmplibs})
list(APPEND LLVM_LIBRARIES "${LLVM_LIBRARY_DIRS}/${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX}")
endforeach()
else()
# Rely on the library search path being set correctly via -L on
# MinGW and others, as the library list returned by
# llvm_map_components_to_libraries also includes imagehlp and psapi.
set(LLVM_LDFLAGS "-L${LLVM_LIBRARY_DIRS}")
set(LLVM_LIBRARIES ${tmplibs})
endif()
# When using the CMake LLVM module, LLVM_DEFINITIONS is a list
# instead of a string. Later, the list seperators would entirely
# disappear, replace them by spaces instead. A better fix would be
# to switch to add_definitions() instead of throwing strings around.
string(REPLACE ";" " " LLVM_CXXFLAGS "${LLVM_CXXFLAGS}")
else()
if (NOT FIND_LLVM_QUIETLY)
message(WARNING "Could not find llvm-config. Try manually setting LLVM_ROOT_DIR to the prebuilt LLVM prefix to use.")
endif()
endif()
else()
macro(llvm_set var flag)
if(LLVM_FIND_QUIETLY)
set(_quiet_arg ERROR_QUIET)
endif()
execute_process(
COMMAND ${LLVM_CONFIG} --${flag}
OUTPUT_VARIABLE LLVM_${var}
OUTPUT_STRIP_TRAILING_WHITESPACE
${_quiet_arg}
)
if(${ARGV2})
file(TO_CMAKE_PATH "${LLVM_${var}}" LLVM_${var})
endif()
endmacro()
macro(llvm_set_libs var flag prefix)
if(LLVM_FIND_QUIETLY)
set(_quiet_arg ERROR_QUIET)
endif()
execute_process(
COMMAND ${LLVM_CONFIG} --${flag} ${LLVM_FIND_COMPONENTS}
OUTPUT_VARIABLE tmplibs
OUTPUT_STRIP_TRAILING_WHITESPACE
${_quiet_arg}
)
file(TO_CMAKE_PATH "${tmplibs}" tmplibs)
string(REGEX REPLACE "([$^.[|*+?()]|])" "\\\\\\1" pattern "${prefix}/")
string(REGEX MATCHALL "${pattern}[^ ]+" "LLVM_${var}" "${tmplibs}")
endmacro()
llvm_set(VERSION_STRING version)
llvm_set(CXXFLAGS cxxflags)
llvm_set(HOST_TARGET host-target)
llvm_set(INCLUDE_DIRS includedir true)
llvm_set(ROOT_DIR prefix true)
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-2][\\.0-9A-Za-z]*")
# Versions below 3.3 do not support components objcarcopts, option
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "objcarcopts" index)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "option" index)
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-4][\\.0-9A-Za-z]*")
# Versions below 3.5 do not support components lto, profiledata
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "lto" index)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "profiledata" index)
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-6][\\.0-9A-Za-z]*")
# Versions below 3.7 do not support components debuginfodwarf
# Only debuginfo is available
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfodwarf" index)
list(APPEND LLVM_FIND_COMPONENTS "debuginfo")
endif()
llvm_set(LDFLAGS ldflags)
if(NOT ${LLVM_VERSION_STRING} MATCHES "^3\\.[0-4][\\.0-9A-Za-z]*")
# In LLVM 3.5+, the system library dependencies (e.g. "-lz") are accessed
# using the separate "--system-libs" flag.
llvm_set(SYSTEM_LIBS system-libs)
string(REPLACE "\n" " " LLVM_LDFLAGS "${LLVM_LDFLAGS} ${LLVM_SYSTEM_LIBS}")
endif()
llvm_set(LIBRARY_DIRS libdir true)
llvm_set_libs(LIBRARIES libfiles "${LLVM_LIBRARY_DIRS}")
endif()
# On CMake builds of LLVM, the output of llvm-config --cxxflags does not
# include -fno-rtti, leading to linker errors. Be sure to add it.
if(CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
if(NOT ${LLVM_CXXFLAGS} MATCHES "-fno-rtti")
set(LLVM_CXXFLAGS "${LLVM_CXXFLAGS} -fno-rtti")
endif()
endif()
string(REGEX REPLACE "([0-9]+).*" "\\1" LLVM_VERSION_MAJOR "${LLVM_VERSION_STRING}" )
string(REGEX REPLACE "[0-9]+\\.([0-9]+).*[A-Za-z]*" "\\1" LLVM_VERSION_MINOR "${LLVM_VERSION_STRING}" )
# Use the default CMake facilities for handling QUIET/REQUIRED.
include(FindPackageHandleStandardArgs)
if(${CMAKE_VERSION} VERSION_LESS "2.8.4")
# The VERSION_VAR argument is not supported on pre-2.8.4, work around this.
set(VERSION_VAR dummy)
endif()
find_package_handle_standard_args(LLVM
REQUIRED_VARS LLVM_ROOT_DIR LLVM_HOST_TARGET
VERSION_VAR LLVM_VERSION_STRING)