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() |