]> The Tcpdump Group git mirrors - tcpdump/blob - cmake/Modules/FindPCAP.cmake
077405e53c3f938092aae53d12c849f8021a1e3d
[tcpdump] / cmake / Modules / FindPCAP.cmake
1 #
2 # Try to find libpcap.
3 #
4
5 #
6 # First, try pkg-config.
7 #
8 find_package(PkgConfig)
9 pkg_search_module(PCAP libpcap)
10
11 if(PCAP_FOUND)
12 #
13 # That worked.
14 # Now, for each library, try to find it, so we get its full path.
15 # CMake *really* doesn't like the notion of specifying "here are
16 # the directories in which to look for libraries" except in
17 # find_library() calls; it *really* prefers using full paths to
18 # library files, rather than library names.
19 #
20 set(_pcap_libraries "${PCAP_LIBRARIES}")
21 set(PCAP_LIBRARIES "")
22 foreach(_lib IN LISTS _pcap_libraries)
23 #
24 # Try to find that library.
25 #
26 find_library(_libfullpath ${_lib} HINTS ${PCAP_LIBRARY_DIRS})
27 list(APPEND PCAP_LIBRARIES ${_libfullpath})
28 #
29 # Remove that from the cache; we're using it as a local variable,
30 # but find_library insists on making it a cache variable.
31 #
32 unset(_libfullpath CACHE)
33 endforeach()
34
35 #
36 # Now find the static libraries.
37 # (XXX - what about AIX?)
38 #
39 set(_pcap_static_libraries "${PCAP_STATIC_LIBRARIES}")
40 set(PCAP_STATIC_LIBRARIES "")
41 set(SAVED_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}")
42 set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
43 foreach(_lib IN LISTS _pcap_static_libraries)
44 #
45 # Try to find that library, so we get its full path, as
46 # we do with dynamic libraries.
47 #
48 find_library(_libfullpath ${_lib} HINTS ${PCAP_LIBRARY_DIRS})
49 list(APPEND PCAP_STATIC_LIBRARIES ${_libfullpath})
50 #
51 # Remove that from the cache; we're using it as a local variable,
52 # but find_library insists on making it a cache variable.
53 #
54 unset(_libfullpath CACHE)
55 endforeach()
56 set(CMAKE_FIND_LIBRARY_SUFFIXES "${SAVED_CMAKE_FIND_LIBRARY_SUFFIXES}")
57 else(PCAP_FOUND)
58 #
59 # That didn't work. Try pcap-config.
60 #
61 find_program(PCAP_CONFIG pcap-config)
62 if(PCAP_CONFIG)
63 #
64 # We have pcap-config; use it.
65 # XXX - what if this is on Windows? If you're using, for example,
66 # MinGW, that might be the right thing to do, *if* pcap-config
67 # were made to work properly on Windows, but what about MSVC?
68 #
69 # First, get the include directory.
70 #
71 execute_process(COMMAND "${PCAP_CONFIG}" "--cflags"
72 RESULT_VARIABLE PCAP_CONFIG_RESULT
73 OUTPUT_VARIABLE PCAP_CONFIG_OUTPUT
74 OUTPUT_STRIP_TRAILING_WHITESPACE
75 )
76 if(NOT PCAP_CONFIG_RESULT EQUAL 0)
77 message(FATAL_ERROR "pcap-config --cflags failed")
78 endif()
79 #
80 # XXX - this assumes that there's only one -I flag in the output
81 # of pcap-config --cflags. That *should* be the case.
82 #
83 string(REGEX REPLACE "-I" "" _pcap_include_dir "${PCAP_CONFIG_OUTPUT}")
84
85 # Try to find the header
86 # We use what pcap-config provided as a hint, because the
87 # pcap-config that ships with macOS bogusly supplies
88 # -I/usr/local/include even though the header isn't
89 # there (it may be under /usr/include or it may be
90 # buried in the Xcode app bundle).
91 find_path(PCAP_INCLUDE_DIRS pcap.h HINTS ${_pcap_include_dir})
92
93 # Now, get the libraries.
94 execute_process(COMMAND "${PCAP_CONFIG}" "--libs"
95 RESULT_VARIABLE PCAP_CONFIG_RESULT
96 OUTPUT_VARIABLE PCAP_CONFIG_OUTPUT
97 OUTPUT_STRIP_TRAILING_WHITESPACE
98 )
99 if(NOT PCAP_CONFIG_RESULT EQUAL 0)
100 message(FATAL_ERROR "pcap-config --libs failed")
101 endif()
102 separate_arguments(LIBS_LIST UNIX_COMMAND ${PCAP_CONFIG_OUTPUT})
103 set(_pcap_library_dirs "")
104 set(PCAP_LIBRARIES "")
105 foreach(_arg IN LISTS LIBS_LIST)
106 if(_arg MATCHES "^-L")
107 # Add this directory to _pcap_library_dirs
108 string(REGEX REPLACE "-L" "" _dir ${_arg})
109 list(APPEND _pcap_library_dirs ${_dir})
110 elseif(_arg MATCHES "^-l")
111 string(REGEX REPLACE "-l" "" _lib ${_arg})
112 #
113 # Try to find that library, so we get its full path. See the
114 # comment above for why we do this.
115 #
116 # Furthermore, the pcap-config shipped with macOS reports
117 # -I/usr/local/include for --cflags and -L/usr/local/lib for
118 # --libs, rather than reporting the appropriate system (or
119 # Xcode application) directory.
120 #
121 find_library(_libfullpath ${_lib} HINTS ${__pcap_library_dirs})
122 list(APPEND PCAP_LIBRARIES ${_libfullpath})
123 #
124 # Remove that from the cache; we're using it as a local variable,
125 # but find_library insists on making it a cache variable.
126 #
127 unset(_libfullpath CACHE)
128 endif()
129 endforeach()
130
131 # Now, get the library directories and libraries for static linking.
132 # (XXX - what about AIX?)
133 execute_process(COMMAND "${PCAP_CONFIG}" "--libs" "--static"
134 RESULT_VARIABLE PCAP_CONFIG_RESULT
135 OUTPUT_VARIABLE PCAP_CONFIG_OUTPUT
136 )
137 if(NOT PCAP_CONFIG_RESULT EQUAL 0)
138 message(FATAL_ERROR "pcap-config --libs --static failed")
139 endif()
140 separate_arguments(LIBS_LIST UNIX_COMMAND ${PCAP_CONFIG_OUTPUT})
141 set(_pcap_static_library_dirs "")
142 set(PCAP_STATIC_LIBRARIES "")
143 set(SAVED_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}")
144 set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
145 foreach(_arg IN LISTS LIBS_LIST)
146 if(_arg MATCHES "^-L")
147 # Add this directory to _pcap_static_library_dirs
148 string(REGEX REPLACE "-L" "" _dir ${_arg})
149 list(APPEND _pcap_static_library_dirs ${_dir})
150 elseif(_arg MATCHES "^-l")
151 string(REGEX REPLACE "-l" "" _lib ${_arg})
152 #
153 # Try to find that library, so we get its full path, as
154 # we do with dynamic libraries.
155 #
156 find_library(_libfullpath ${_lib} HINTS ${__pcap_static_library_dirs})
157 list(APPEND PCAP_STATIC_LIBRARIES ${_libfullpath})
158 #
159 # Remove that from the cache; we're using it as a local variable,
160 # but find_library insists on making it a cache variable.
161 #
162 unset(_libfullpath CACHE)
163 endif()
164 endforeach()
165 set(CMAKE_FIND_LIBRARY_SUFFIXES "${SAVED_CMAKE_FIND_LIBRARY_SUFFIXES}")
166 else(PCAP_CONFIG)
167 #
168 # We don't have pcap-config.
169 # Try to find the header by just looking for it in whatever
170 # directories find_path() uses by default.
171 #
172 find_path(PCAP_INCLUDE_DIRS pcap.h)
173
174 # Try to find the library
175 if(WIN32)
176 # The 64-bit Packet.lib is located under /x64
177 if(CMAKE_SIZEOF_VOID_P EQUAL 8)
178 #
179 # For the WinPcap and Npcap SDKs, the Lib subdirectory of the top-level
180 # directory contains 32-bit libraries; the 64-bit libraries are in the
181 # Lib/x64 directory.
182 #
183 # The only way to *FORCE* CMake to look in the Lib/x64 directory
184 # without searching in the Lib directory first appears to be to set
185 # CMAKE_LIBRARY_ARCHITECTURE to "x64".
186 #
187 set(CMAKE_LIBRARY_ARCHITECTURE "x64")
188 endif()
189 endif()
190
191 find_library(PCAP_LIBRARIES pcap)
192 if(WIN32)
193 if(NOT PCAP_LIBRARIES)
194 #
195 # OK, look for it under the name wpcap.
196 #
197 find_library(PCAP_LIBRARIES wpcap)
198 endif(NOT PCAP_LIBRARIES)
199 endif(WIN32)
200
201 if(NOT WIN32)
202 # Try to find the static library (XXX - what about AIX?)
203 set(SAVED_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}")
204 set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
205 find_library(PCAP_STATIC_LIBRARIES pcap)
206 set(CMAKE_FIND_LIBRARY_SUFFIXES "${SAVED_CMAKE_FIND_LIBRARY_SUFFIXES}")
207 endif(NOT WIN32)
208 endif(PCAP_CONFIG)
209 endif(PCAP_FOUND)
210
211 include(FindPackageHandleStandardArgs)
212 find_package_handle_standard_args(PCAP
213 DEFAULT_MSG
214 PCAP_INCLUDE_DIRS
215 PCAP_LIBRARIES
216 )
217
218 mark_as_advanced(
219 PCAP_INCLUDE_DIR
220 PCAP_LIBRARY
221 PCAP_STATIC_LIBRARY
222 )