mirror of
https://github.com/rspamd/rspamd.git
synced 2024-08-05 08:17:09 +02:00
251 lines
11 KiB
CMake
251 lines
11 KiB
CMake
#===------------------------------------------------------------------------===#
|
|
#
|
|
# The KLEE Symbolic Virtual Machine
|
|
#
|
|
# This file is distributed under the University of Illinois Open Source
|
|
# License. See LICENSE.TXT for details.
|
|
#
|
|
#===------------------------------------------------------------------------===#
|
|
#
|
|
# This file provides multiple methods to detect LLVM.
|
|
#
|
|
# * llvm-config executable. This method is portable across LLVM build systems
|
|
# (i.e. works if LLVM was built with autoconf/Makefile or with CMake).
|
|
#
|
|
# * find_package(LLVM CONFIG). This method only works if LLVM was built with
|
|
# CMake or with LLVM >= 3.5 when built with the autoconf/Makefile build system
|
|
# This method relies on the `LLVMConfig.cmake` file generated to be generated
|
|
# by LLVM's build system.
|
|
#
|
|
#===------------------------------------------------------------------------===#
|
|
|
|
function(string_to_list s output_var)
|
|
string(REPLACE " " ";" _output "${s}")
|
|
set(${output_var} ${_output} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
option(USE_CMAKE_FIND_PACKAGE_LLVM "Use find_package(LLVM CONFIG) to find LLVM" OFF)
|
|
|
|
if (USE_CMAKE_FIND_PACKAGE_LLVM)
|
|
find_package(LLVM CONFIG REQUIRED)
|
|
|
|
# Provide function to map LLVM components to libraries.
|
|
function(klee_get_llvm_libs output_var)
|
|
if (${LLVM_PACKAGE_VERSION} VERSION_LESS "3.5")
|
|
llvm_map_components_to_libraries(${output_var} ${ARGN})
|
|
else()
|
|
llvm_map_components_to_libnames(${output_var} ${ARGN})
|
|
endif()
|
|
set(${output_var} ${${output_var}} PARENT_SCOPE)
|
|
endfunction()
|
|
# HACK: This information is not exported so just pretend its OFF for now.
|
|
set(LLVM_ENABLE_VISIBILITY_INLINES_HIDDEN OFF)
|
|
else()
|
|
# Use the llvm-config binary to get the information needed.
|
|
# Try to detect it in the user's environment. The user can
|
|
# force a particular binary by passing `-DLLVM_CONFIG_BINARY=/path/to/llvm-config`
|
|
# to CMake.
|
|
find_program(LLVM_CONFIG_BINARY
|
|
NAMES llvm-config)
|
|
message(STATUS "LLVM_CONFIG_BINARY: ${LLVM_CONFIG_BINARY}")
|
|
|
|
if (NOT LLVM_CONFIG_BINARY)
|
|
message(FATAL_ERROR
|
|
"Failed to find llvm-config.\n"
|
|
"Try passing -DLLVM_CONFIG_BINARY=/path/to/llvm-config to cmake")
|
|
endif()
|
|
|
|
function(_run_llvm_config output_var)
|
|
set(_command "${LLVM_CONFIG_BINARY}" ${ARGN})
|
|
execute_process(COMMAND ${_command}
|
|
RESULT_VARIABLE _exit_code
|
|
OUTPUT_VARIABLE ${output_var}
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
ERROR_STRIP_TRAILING_WHITESPACE
|
|
)
|
|
if (NOT ("${_exit_code}" EQUAL "0"))
|
|
message(FATAL_ERROR "Failed running ${_command}")
|
|
endif()
|
|
set(${output_var} ${${output_var}} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Get LLVM version
|
|
_run_llvm_config(LLVM_PACKAGE_VERSION "--version")
|
|
# Try x.y.z patern
|
|
set(_llvm_version_regex "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(svn)?$")
|
|
if ("${LLVM_PACKAGE_VERSION}" MATCHES "${_llvm_version_regex}")
|
|
string(REGEX REPLACE
|
|
"${_llvm_version_regex}"
|
|
"\\1"
|
|
LLVM_VERSION_MAJOR
|
|
"${LLVM_PACKAGE_VERSION}")
|
|
string(REGEX REPLACE
|
|
"${_llvm_version_regex}"
|
|
"\\2"
|
|
LLVM_VERSION_MINOR
|
|
"${LLVM_PACKAGE_VERSION}")
|
|
string(REGEX REPLACE
|
|
"${_llvm_version_regex}"
|
|
"\\3"
|
|
LLVM_VERSION_PATCH
|
|
"${LLVM_PACKAGE_VERSION}")
|
|
else()
|
|
# try x.y pattern
|
|
set(_llvm_version_regex "^([0-9]+)\\.([0-9]+)(svn)?$")
|
|
if ("${LLVM_PACKAGE_VERSION}" MATCHES "${_llvm_version_regex}")
|
|
string(REGEX REPLACE
|
|
"${_llvm_version_regex}"
|
|
"\\1"
|
|
LLVM_VERSION_MAJOR
|
|
"${LLVM_PACKAGE_VERSION}")
|
|
string(REGEX REPLACE
|
|
"${_llvm_version_regex}"
|
|
"\\2"
|
|
LLVM_VERSION_MINOR
|
|
"${LLVM_PACKAGE_VERSION}")
|
|
set(LLVM_VERSION_PATCH 0)
|
|
else()
|
|
message(FATAL_ERROR
|
|
"Failed to parse LLVM version from \"${LLVM_PACKAGE_VERSION}\"")
|
|
endif()
|
|
endif()
|
|
|
|
set(LLVM_DEFINITIONS "")
|
|
_run_llvm_config(_llvm_cpp_flags "--cppflags")
|
|
string_to_list("${_llvm_cpp_flags}" _llvm_cpp_flags_list)
|
|
foreach (flag ${_llvm_cpp_flags_list})
|
|
# Filter out -I flags by only looking for -D flags.
|
|
if ("${flag}" MATCHES "^-D" AND NOT ("${flag}" STREQUAL "-D_DEBUG"))
|
|
list(APPEND LLVM_DEFINITIONS "${flag}")
|
|
endif()
|
|
endforeach()
|
|
|
|
set(LLVM_ENABLE_ASSERTIONS ON)
|
|
set(LLVM_ENABLE_EH ON)
|
|
set(LLVM_ENABLE_RTTI ON)
|
|
set(LLVM_ENABLE_VISIBILITY_INLINES_HIDDEN OFF)
|
|
_run_llvm_config(_llvm_cxx_flags "--cxxflags")
|
|
string_to_list("${_llvm_cxx_flags}" _llvm_cxx_flags_list)
|
|
foreach (flag ${_llvm_cxx_flags_list})
|
|
if ("${flag}" STREQUAL "-DNDEBUG")
|
|
# Note we don't rely on `llvm-config --build-mode` because
|
|
# that seems broken when LLVM is built with CMake.
|
|
set(LLVM_ENABLE_ASSERTIONS OFF)
|
|
elseif ("${flag}" STREQUAL "-fno-exceptions")
|
|
set(LLVM_ENABLE_EH OFF)
|
|
elseif ("${flag}" STREQUAL "-fno-rtti")
|
|
set(LLVM_ENABLE_RTTI OFF)
|
|
elseif ("${flag}" STREQUAL "-fvisibility-inlines-hidden")
|
|
set(LLVM_ENABLE_VISIBILITY_INLINES_HIDDEN ON)
|
|
endif()
|
|
endforeach()
|
|
|
|
set(LLVM_INCLUDE_DIRS "")
|
|
foreach (flag ${_llvm_cpp_flags_list})
|
|
# Filter out -D flags by only looking for -I flags.
|
|
if ("${flag}" MATCHES "^-I")
|
|
string(REGEX REPLACE "^-I(.+)$" "\\1" _include_dir "${flag}")
|
|
list(APPEND LLVM_INCLUDE_DIRS "${_include_dir}")
|
|
endif()
|
|
endforeach()
|
|
|
|
_run_llvm_config(LLVM_LIBRARY_DIRS "--libdir")
|
|
_run_llvm_config(LLVM_TOOLS_BINARY_DIR "--bindir")
|
|
_run_llvm_config(TARGET_TRIPLE "--host-target")
|
|
|
|
# Provide function to map LLVM components to libraries.
|
|
function(klee_get_llvm_libs OUTPUT_VAR)
|
|
_run_llvm_config(_llvm_libs "--libfiles" ${ARGN})
|
|
string_to_list("${_llvm_libs}" _llvm_libs_list)
|
|
|
|
# Now find the system libs that are needed.
|
|
if (${LLVM_PACKAGE_VERSION} VERSION_LESS "3.5")
|
|
# For LLVM 3.4 and older system libraries
|
|
# appeared in the output of `--ldflags`.
|
|
_run_llvm_config(_system_libs "--ldflags")
|
|
# TODO: Filter out `-L<path>` flag.
|
|
else()
|
|
_run_llvm_config(_system_libs "--system-libs")
|
|
endif()
|
|
string_to_list("${_system_libs}" _system_libs_list)
|
|
|
|
# Create an imported target for each LLVM library
|
|
# if it doesn't already exist. We need to do this
|
|
# so we can tell CMake that these libraries depend
|
|
# on the necessary libraries so that CMake
|
|
# can get the link order right.
|
|
set(targets_to_return "")
|
|
set(created_targets "")
|
|
foreach (llvm_lib ${_llvm_libs_list})
|
|
# a bug in llvm-config from LLVM 3.9
|
|
string(REGEX REPLACE "lib(libLLVM[-.a-zA-Z0-9]+\\.so)\\.so$" "\\1" llvm_lib "${llvm_lib}")
|
|
|
|
get_filename_component(llvm_lib_file_name "${llvm_lib}" NAME)
|
|
|
|
string(REGEX REPLACE "^(lib)?(LLVM[-.a-zA-Z0-9]+)\\..+$" "\\2" target_name "${llvm_lib_file_name}")
|
|
list(APPEND targets_to_return "${target_name}")
|
|
if (NOT TARGET "${target_name}")
|
|
# DEBUG: message(STATUS "Creating imported target \"${target_name}\"" " for \"${llvm_lib}\"")
|
|
list(APPEND created_targets "${target_name}")
|
|
|
|
set(import_library_type "STATIC")
|
|
if ("${llvm_lib_file_name}" MATCHES "(so|dylib|dll)$")
|
|
set(import_library_type "SHARED")
|
|
endif()
|
|
# Create an imported target for the library
|
|
add_library("${target_name}" "${import_library_type}" IMPORTED GLOBAL)
|
|
set_property(TARGET "${target_name}" PROPERTY
|
|
IMPORTED_LOCATION "${llvm_lib}"
|
|
)
|
|
endif()
|
|
endforeach()
|
|
|
|
# Now state the dependencies of the created imported targets which we
|
|
# assume to be for each imported target the libraries which appear after
|
|
# the library in `{_llvm_libs_list}` and then finally the system libs.
|
|
# It is **essential** that we do this otherwise CMake will get the
|
|
# link order of the imported targets wrong.
|
|
list(LENGTH targets_to_return length_targets_to_return)
|
|
if ("${length_targets_to_return}" GREATER 0)
|
|
math(EXPR targets_to_return_last_index "${length_targets_to_return} -1")
|
|
foreach (llvm_target_lib ${created_targets})
|
|
# DEBUG: message(STATUS "Adding deps for target ${llvm_target_lib}")
|
|
# Find position in `targets_to_return`
|
|
list(FIND targets_to_return "${llvm_target_lib}" position)
|
|
if ("${position}" EQUAL "-1")
|
|
message(FATAL_ERROR "couldn't find \"${llvm_target_lib}\" in list of targets")
|
|
endif()
|
|
if ("${position}" LESS "${targets_to_return_last_index}")
|
|
math(EXPR position_plus_one "${position} + 1")
|
|
foreach (index RANGE ${position_plus_one} ${targets_to_return_last_index})
|
|
# Get the target for this index
|
|
list(GET targets_to_return ${index} target_for_index)
|
|
# DEBUG: message(STATUS "${llvm_target_libs} depends on ${target_for_index}")
|
|
set_property(TARGET "${llvm_target_lib}" APPEND PROPERTY
|
|
INTERFACE_LINK_LIBRARIES "${target_for_index}"
|
|
)
|
|
endforeach()
|
|
endif()
|
|
# Now finally add the system library dependencies. These must be last.
|
|
set_property(TARGET "${target_name}" APPEND PROPERTY
|
|
INTERFACE_LINK_LIBRARIES "${_system_libs_list}"
|
|
)
|
|
endforeach()
|
|
endif()
|
|
|
|
set(${OUTPUT_VAR} ${targets_to_return} PARENT_SCOPE)
|
|
endfunction()
|
|
endif()
|
|
|
|
# Filter out `-DNEBUG` from LLVM_DEFINITIONS. The caller can use
|
|
# `LLVM_ENABLE_ASSERTIONS` to decide how to set their defines.
|
|
set(_new_llvm_definitions "")
|
|
foreach (llvm_define ${LLVM_DEFINITIONS})
|
|
if ("${llvm_define}" STREQUAL "-DNDEBUG")
|
|
# Skip
|
|
else()
|
|
list(APPEND _new_llvm_definitions "${llvm_define}")
|
|
endif()
|
|
endforeach()
|
|
set(LLVM_DEFINITIONS "${_new_llvm_definitions}")
|
|
unset(_new_llvm_definitions) |