Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | # Attempts to discover ffi library with a linkable ffi_call function. |
| 2 | # |
||
| 3 | # Example usage: |
||
| 4 | # |
||
| 5 | # find_package(FFI) |
||
| 6 | # |
||
| 7 | # FFI_REQUIRE_INCLUDE may be set to consider ffi found if the includes |
||
| 8 | # are present in addition to the library. This is useful to keep off |
||
| 9 | # for the imported package on platforms that install the library but |
||
| 10 | # not the headers. |
||
| 11 | # |
||
| 12 | # FFI_LIBRARY_DIR may be set to define search paths for the ffi library. |
||
| 13 | # |
||
| 14 | # If successful, the following variables will be defined: |
||
| 15 | # FFI_FOUND |
||
| 16 | # FFI_INCLUDE_DIRS |
||
| 17 | # FFI_LIBRARIES |
||
| 18 | # HAVE_FFI_CALL |
||
| 19 | # |
||
| 20 | # HAVE_FFI_H or HAVE_FFI_FFI_H is defined depending on the ffi.h include path. |
||
| 21 | # |
||
| 22 | # Additionally, the following import target will be defined: |
||
| 23 | # FFI::ffi |
||
| 24 | |||
| 25 | find_path(FFI_INCLUDE_DIRS ffi.h PATHS ${FFI_INCLUDE_DIR}) |
||
| 26 | if( EXISTS "${FFI_INCLUDE_DIRS}/ffi.h" ) |
||
| 27 | set(FFI_HEADER ffi.h CACHE INTERNAL "") |
||
| 28 | set(HAVE_FFI_H 1 CACHE INTERNAL "") |
||
| 29 | else() |
||
| 30 | find_path(FFI_INCLUDE_DIRS ffi/ffi.h PATHS ${FFI_INCLUDE_DIR}) |
||
| 31 | if( EXISTS "${FFI_INCLUDE_DIRS}/ffi/ffi.h" ) |
||
| 32 | set(FFI_HEADER ffi/ffi.h CACHE INTERNAL "") |
||
| 33 | set(HAVE_FFI_FFI_H 1 CACHE INTERNAL "") |
||
| 34 | endif() |
||
| 35 | endif() |
||
| 36 | |||
| 37 | find_library(FFI_LIBRARIES ffi PATHS ${FFI_LIBRARY_DIR}) |
||
| 38 | |||
| 39 | if(FFI_LIBRARIES) |
||
| 40 | include(CMakePushCheckState) |
||
| 41 | include(CheckCSourceCompiles) |
||
| 42 | cmake_push_check_state() |
||
| 43 | list(APPEND CMAKE_REQUIRED_LIBRARIES ${FFI_LIBRARIES}) |
||
| 44 | check_c_source_compiles(" |
||
| 45 | struct ffi_cif; |
||
| 46 | typedef struct ffi_cif ffi_cif; |
||
| 47 | void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue); |
||
| 48 | int main(void) { ffi_call(0, 0, 0, 0); }" |
||
| 49 | HAVE_FFI_CALL) |
||
| 50 | cmake_pop_check_state() |
||
| 51 | endif() |
||
| 52 | |||
| 53 | unset(required_includes) |
||
| 54 | if(FFI_REQUIRE_INCLUDE) |
||
| 55 | set(required_includes FFI_INCLUDE_DIRS) |
||
| 56 | endif() |
||
| 57 | |||
| 58 | include(FindPackageHandleStandardArgs) |
||
| 59 | find_package_handle_standard_args(FFI |
||
| 60 | FOUND_VAR |
||
| 61 | FFI_FOUND |
||
| 62 | REQUIRED_VARS |
||
| 63 | FFI_LIBRARIES |
||
| 64 | ${required_includes} |
||
| 65 | HAVE_FFI_CALL) |
||
| 66 | mark_as_advanced(FFI_LIBRARIES |
||
| 67 | FFI_INCLUDE_DIRS |
||
| 68 | HAVE_FFI_CALL |
||
| 69 | FFI_HEADER |
||
| 70 | HAVE_FFI_H |
||
| 71 | HAVE_FFI_FFI_H) |
||
| 72 | |||
| 73 | if(FFI_FOUND) |
||
| 74 | if(NOT TARGET FFI::ffi) |
||
| 75 | add_library(FFI::ffi UNKNOWN IMPORTED) |
||
| 76 | set_target_properties(FFI::ffi PROPERTIES IMPORTED_LOCATION "${FFI_LIBRARIES}") |
||
| 77 | if(FFI_INCLUDE_DIRS) |
||
| 78 | set_target_properties(FFI::ffi PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFI_INCLUDE_DIRS}") |
||
| 79 | endif() |
||
| 80 | endif() |
||
| 81 | endif() |