diff --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake --- a/llvm/cmake/config-ix.cmake +++ b/llvm/cmake/config-ix.cmake @@ -191,18 +191,13 @@ else() set(HAVE_LIBEDIT 0) endif() - if(LLVM_ENABLE_TERMINFO STREQUAL FORCE_ON) - set(MAYBE_REQUIRED REQUIRED) - else() - set(MAYBE_REQUIRED) - endif() if(LLVM_ENABLE_TERMINFO) - find_library(TERMINFO_LIB NAMES terminfo tinfo curses ncurses ncursesw ${MAYBE_REQUIRED}) - endif() - if(TERMINFO_LIB) - set(LLVM_ENABLE_TERMINFO 1) - else() - set(LLVM_ENABLE_TERMINFO 0) + if(LLVM_ENABLE_TERMINFO STREQUAL FORCE_ON) + find_package(Terminfo REQUIRED) + else() + find_package(Terminfo) + endif() + set(LLVM_ENABLE_TERMINFO "${Terminfo_FOUND}") endif() else() set(LLVM_ENABLE_TERMINFO 0) @@ -354,38 +349,19 @@ llvm_find_program(dot) endif () -if( LLVM_ENABLE_FFI ) - find_path(FFI_INCLUDE_PATH ffi.h PATHS ${FFI_INCLUDE_DIR}) - if( EXISTS "${FFI_INCLUDE_PATH}/ffi.h" ) - set(FFI_HEADER ffi.h CACHE INTERNAL "") - set(HAVE_FFI_H 1 CACHE INTERNAL "") +if(LLVM_ENABLE_FFI) + set(FFI_REQUIRE_INCLUDE On) + if(LLVM_ENABLE_FFI STREQUAL FORCE_ON) + find_package(FFI REQUIRED) else() - find_path(FFI_INCLUDE_PATH ffi/ffi.h PATHS ${FFI_INCLUDE_DIR}) - if( EXISTS "${FFI_INCLUDE_PATH}/ffi/ffi.h" ) - set(FFI_HEADER ffi/ffi.h CACHE INTERNAL "") - set(HAVE_FFI_FFI_H 1 CACHE INTERNAL "") - endif() + find_package(FFI) endif() - - if( NOT FFI_HEADER ) - message(FATAL_ERROR "libffi includes are not found.") - endif() - - find_library(FFI_LIBRARY_PATH ffi PATHS ${FFI_LIBRARY_DIR}) - if( NOT FFI_LIBRARY_PATH ) - message(FATAL_ERROR "libffi is not found.") - endif() - - list(APPEND CMAKE_REQUIRED_LIBRARIES ${FFI_LIBRARY_PATH}) - list(APPEND CMAKE_REQUIRED_INCLUDES ${FFI_INCLUDE_PATH}) - check_symbol_exists(ffi_call ${FFI_HEADER} HAVE_FFI_CALL) - list(REMOVE_ITEM CMAKE_REQUIRED_INCLUDES ${FFI_INCLUDE_PATH}) - list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES ${FFI_LIBRARY_PATH}) + set(LLVM_ENABLE_FFI "${FFI_FOUND}") else() unset(HAVE_FFI_FFI_H CACHE) unset(HAVE_FFI_H CACHE) unset(HAVE_FFI_CALL CACHE) -endif( LLVM_ENABLE_FFI ) +endif() check_symbol_exists(proc_pid_rusage "libproc.h" HAVE_PROC_PID_RUSAGE) diff --git a/llvm/cmake/modules/FindFFI.cmake b/llvm/cmake/modules/FindFFI.cmake new file mode 100644 --- /dev/null +++ b/llvm/cmake/modules/FindFFI.cmake @@ -0,0 +1,81 @@ +# Attempts to discover ffi library with a linkable ffi_call function. +# +# Example usage: +# +# find_package(FFI) +# +# FFI_REQUIRE_INCLUDE may be set to consider ffi found if the includes +# are present in addition to the library. This is useful to keep off +# for the imported package on platforms that install the library but +# not the headers. +# +# FFI_LIBRARY_DIR may be set to define search paths for the ffi library. +# +# If successful, the following variables will be defined: +# FFI_FOUND +# FFI_INCLUDE_DIRS +# FFI_LIBRARIES +# HAVE_FFI_CALL +# +# HAVE_FFI_H or HAVE_FFI_FFI_H is defined depending on the ffi.h include path. +# +# Additionally, the following import target will be defined: +# FFI::ffi + +find_path(FFI_INCLUDE_DIRS ffi.h PATHS ${FFI_INCLUDE_DIR}) +if( EXISTS "${FFI_INCLUDE_DIRS}/ffi.h" ) + set(FFI_HEADER ffi.h CACHE INTERNAL "") + set(HAVE_FFI_H 1 CACHE INTERNAL "") +else() + find_path(FFI_INCLUDE_DIRS ffi/ffi.h PATHS ${FFI_INCLUDE_DIR}) + if( EXISTS "${FFI_INCLUDE_DIRS}/ffi/ffi.h" ) + set(FFI_HEADER ffi/ffi.h CACHE INTERNAL "") + set(HAVE_FFI_FFI_H 1 CACHE INTERNAL "") + endif() +endif() + +find_library(FFI_LIBRARIES ffi PATHS ${FFI_LIBRARY_DIR}) + +if(FFI_LIBRARIES) + include(CMakePushCheckState) + include(CheckCSourceCompiles) + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_LIBRARIES ${FFI_LIBRARIES}) + check_c_source_compiles(" + struct ffi_cif; + typedef struct ffi_cif ffi_cif; + void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue); + int main() { ffi_call(0, 0, 0, 0); }" + HAVE_FFI_CALL) + cmake_pop_check_state() +endif() + +unset(required_includes) +if(FFI_REQUIRE_INCLUDE) + set(required_includes FFI_INCLUDE_DIRS) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(FFI + FOUND_VAR + FFI_FOUND + REQUIRED_VARS + FFI_LIBRARIES + ${required_includes} + HAVE_FFI_CALL) +mark_as_advanced(FFI_LIBRARIES + FFI_INCLUDE_DIRS + HAVE_FFI_CALL + FFI_HEADER + HAVE_FFI_H + HAVE_FFI_FFI_H) + +if(FFI_FOUND) + if(NOT TARGET FFI::ffi) + add_library(FFI::ffi UNKNOWN IMPORTED) + set_target_properties(FFI::ffi PROPERTIES IMPORTED_LOCATION "${FFI_LIBRARIES}") + if(FFI_INCLUDE_DIRS) + set_target_properties(FFI::ffi PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFI_INCLUDE_DIRS}") + endif() + endif() +endif() diff --git a/llvm/cmake/modules/FindTerminfo.cmake b/llvm/cmake/modules/FindTerminfo.cmake new file mode 100644 --- /dev/null +++ b/llvm/cmake/modules/FindTerminfo.cmake @@ -0,0 +1,43 @@ +# Attempts to discover terminfo library with a linkable setupterm function. +# +# Example usage: +# +# find_package(Terminfo) +# +# If successful, the following variables will be defined: +# Terminfo_FOUND +# Terminfo_LIBRARIES +# +# Additionally, the following import target will be defined: +# Terminfo::terminfo + +find_library(Terminfo_LIBRARIES NAMES terminfo tinfo curses ncurses ncursesw) + +if(Terminfo_LIBRARIES) + include(CMakePushCheckState) + include(CheckCSourceCompiles) + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_LIBRARIES ${Terminfo_LIBRARIES}) + check_c_source_compiles(" + int setupterm(char *term, int filedes, int *errret); + int main() { return setupterm(0, 0, 0); }" + Terminfo_LINKABLE) + cmake_pop_check_state() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Terminfo + FOUND_VAR + Terminfo_FOUND + REQUIRED_VARS + Terminfo_LIBRARIES + Terminfo_LINKABLE) +mark_as_advanced(Terminfo_LIBRARIES + Terminfo_LINKABLE) + +if(Terminfo_FOUND) + if(NOT TARGET Terminfo::terminfo) + add_library(Terminfo::terminfo UNKNOWN IMPORTED) + set_target_properties(Terminfo::terminfo PROPERTIES IMPORTED_LOCATION "${Terminfo_LIBRARIES}") + endif() +endif() diff --git a/llvm/cmake/modules/LLVMConfig.cmake.in b/llvm/cmake/modules/LLVMConfig.cmake.in --- a/llvm/cmake/modules/LLVMConfig.cmake.in +++ b/llvm/cmake/modules/LLVMConfig.cmake.in @@ -2,6 +2,9 @@ @LLVM_CONFIG_CODE@ +# For finding self-installed Find*.cmake packages. +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") + set(LLVM_VERSION_MAJOR @LLVM_VERSION_MAJOR@) set(LLVM_VERSION_MINOR @LLVM_VERSION_MINOR@) set(LLVM_VERSION_PATCH @LLVM_VERSION_PATCH@) @@ -48,9 +51,17 @@ set(LLVM_ENABLE_EH @LLVM_ENABLE_EH@) +set(LLVM_ENABLE_FFI @LLVM_ENABLE_FFI@) +if(LLVM_ENABLE_FFI) + find_package(FFI) +endif() + set(LLVM_ENABLE_RTTI @LLVM_ENABLE_RTTI@) set(LLVM_ENABLE_TERMINFO @LLVM_ENABLE_TERMINFO@) +if(LLVM_ENABLE_TERMINFO) + find_package(Terminfo) +endif() set(LLVM_ENABLE_THREADS @LLVM_ENABLE_THREADS@) diff --git a/llvm/lib/ExecutionEngine/Interpreter/CMakeLists.txt b/llvm/lib/ExecutionEngine/Interpreter/CMakeLists.txt --- a/llvm/lib/ExecutionEngine/Interpreter/CMakeLists.txt +++ b/llvm/lib/ExecutionEngine/Interpreter/CMakeLists.txt @@ -1,11 +1,3 @@ -# Make sure that the path to libffi headers is on the command -# line. That path can be a compiler's non-default path even when -# FFI_INCLUDE_DIR was not used, because cmake has its own paths for -# searching for headers (CMAKE_SYSTEM_INCLUDE_PATH, for instance): -if( FFI_INCLUDE_PATH ) - include_directories( ${FFI_INCLUDE_PATH} ) -endif() - add_llvm_component_library(LLVMInterpreter Execution.cpp ExternalFunctions.cpp @@ -22,5 +14,5 @@ ) if( LLVM_ENABLE_FFI ) - target_link_libraries( LLVMInterpreter PRIVATE ${FFI_LIBRARY_PATH} ) + target_link_libraries( LLVMInterpreter PRIVATE FFI::ffi ) endif() diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -45,7 +45,7 @@ set(system_libs ${system_libs} ${Backtrace_LIBFILE}) endif() if( LLVM_ENABLE_TERMINFO ) - set(imported_libs ${imported_libs} "${TERMINFO_LIB}") + set(imported_libs ${imported_libs} Terminfo::terminfo) endif() if( LLVM_ENABLE_THREADS AND (HAVE_LIBATOMIC OR HAVE_CXX_LIBATOMICS64) ) set(system_libs ${system_libs} atomic) @@ -281,7 +281,10 @@ endif() if(LLVM_ENABLE_TERMINFO) - get_library_name(${TERMINFO_LIB} terminfo_library) + if(NOT terminfo_library) + get_property(terminfo_library TARGET Terminfo::terminfo PROPERTY LOCATION) + endif() + get_library_name(${terminfo_library} terminfo_library) set(llvm_system_libs ${llvm_system_libs} "${terminfo_library}") endif()