diff options
author | Guy Harris <guy@alum.mit.edu> | 2019-04-26 19:42:33 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2019-04-27 03:15:51 +0000 |
commit | c602119bcf2d711348425f892d47aa2bcc9a17f8 (patch) | |
tree | 7a6b86eeeec58cad2af763aab16eae26e0041695 /cmake | |
parent | d0ce55289b92875e21069ddb36eda7214437e37b (diff) |
Use pkg-config if possible; if not, use pcap-config if present.
First try finding libpcap with pkg-config. If that fails (either because
the system doesn't have pkg-config or because it does but there's no .pc
file for libpcap), check for pcap-config and, if it's present, use that,
otherwise fall back on manually searching for it.
Pick up the code from tcpdump's FindPCAP.cmake.
Change-Id: I87963aaa7cccac0b5cd942f48eb5d08779695f92
Reviewed-on: https://code.wireshark.org/review/32992
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/modules/FindPCAP.cmake | 251 |
1 files changed, 219 insertions, 32 deletions
diff --git a/cmake/modules/FindPCAP.cmake b/cmake/modules/FindPCAP.cmake index 6fe2d0f4dc..aa478e7490 100644 --- a/cmake/modules/FindPCAP.cmake +++ b/cmake/modules/FindPCAP.cmake @@ -15,45 +15,234 @@ if( WIN32 AND "${WIRESHARK_TARGET_PLATFORM}" STREQUAL "win64" ) set ( _PLATFORM_SUBDIR "/x64" ) endif() -find_path( PCAP_INCLUDE_DIR - NAMES - pcap/pcap.h - pcap.h - HINTS - "${PCAP_HINTS}/include" -) - -find_library( PCAP_LIBRARY - NAMES - pcap - wpcap - HINTS - "${PCAP_HINTS}/lib${_PLATFORM_SUBDIR}" -) +# +# First, try pkg-config. +# +find_package( PkgConfig ) +pkg_search_module( PCAP libpcap ) + +if( PCAP_FOUND ) + # + # That worked. + # Now, for each library, try to find it, so we get its full path. + # CMake *really* doesn't like the notion of specifying "here are + # the directories in which to look for libraries" except in + # find_library() calls; it *really* prefers using full paths to + # library files, rather than library names. + # + set( _pcap_libraries "${PCAP_LIBRARIES}" ) + set( PCAP_LIBRARIES "" ) + foreach( _lib IN LISTS _pcap_libraries ) + # + # Try to find that library. + # + find_library( _libfullpath ${_lib} HINTS ${PCAP_LIBRARY_DIRS} ) + list( APPEND PCAP_LIBRARIES ${_libfullpath} ) + # + # Remove that from the cache; we're using it as a local variable, + # but find_library insists on making it a cache variable. + # + unset( _libfullpath CACHE ) + endforeach() + # + # Now find the static libraries. + # (XXX - what about AIX?) + # + set( _pcap_static_libraries "${PCAP_STATIC_LIBRARIES}" ) + set( PCAP_STATIC_LIBRARIES "" ) + set( SAVED_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}" ) + set( CMAKE_FIND_LIBRARY_SUFFIXES ".a" ) + foreach( _lib IN LISTS _pcap_static_libraries ) + # + # Try to find that library, so we get its full path, as + # we do with dynamic libraries. + # + find_library( _libfullpath ${_lib} HINTS ${PCAP_LIBRARY_DIRS} ) + list( APPEND PCAP_STATIC_LIBRARIES ${_libfullpath} ) + # + # Remove that from the cache; we're using it as a local variable, + # but find_library insists on making it a cache variable. + # + unset( _libfullpath CACHE ) + endforeach() + set( CMAKE_FIND_LIBRARY_SUFFIXES "${SAVED_CMAKE_FIND_LIBRARY_SUFFIXES}" ) +else( PCAP_FOUND ) + # + # That didn't work. Try pcap-config. + # + find_program( PCAP_CONFIG pcap-config ) + if( PCAP_CONFIG ) + # + # We have pcap-config; use it. + # XXX - what if this is on Windows? If you're using, for example, + # MinGW, that might be the right thing to do, *if* pcap-config + # were made to work properly on Windows, but what about MSVC? + # + # First, get the include directory. + # + execute_process( COMMAND "${PCAP_CONFIG}" "--cflags" + RESULT_VARIABLE PCAP_CONFIG_RESULT + OUTPUT_VARIABLE PCAP_CONFIG_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if( NOT PCAP_CONFIG_RESULT EQUAL 0 ) + message( FATAL_ERROR "pcap-config --cflags failed" ) + endif() + # + # XXX - this assumes that there's only one -I flag in the output + # of pcap-config --cflags. That *should* be the case. + # + string(REGEX REPLACE "-I" "" _pcap_include_dir "${PCAP_CONFIG_OUTPUT}") + + # Try to find the header + # We use what pcap-config provided as a hint, because the + # pcap-config that ships with macOS bogusly supplies + # -I/usr/local/include even though the header isn't + # there (it may be under /usr/include or it may be + # buried in the Xcode app bundle). + find_path(PCAP_INCLUDE_DIRS pcap.h HINTS ${_pcap_include_dir}) + + # Now, get the libraries. + execute_process( COMMAND "${PCAP_CONFIG}" "--libs" + RESULT_VARIABLE PCAP_CONFIG_RESULT + OUTPUT_VARIABLE PCAP_CONFIG_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if( NOT PCAP_CONFIG_RESULT EQUAL 0 ) + message( FATAL_ERROR "pcap-config --libs failed" ) + endif() + separate_arguments( LIBS_LIST UNIX_COMMAND ${PCAP_CONFIG_OUTPUT} ) + set( _pcap_library_dirs "" ) + set( PCAP_LIBRARIES "" ) + foreach( _arg IN LISTS LIBS_LIST ) + if( _arg MATCHES "^-L" ) + # Add this directory to _pcap_library_dirs + string( REGEX REPLACE "-L" "" _dir ${_arg} ) + list( APPEND _pcap_library_dirs ${_dir} ) + elseif( _arg MATCHES "^-l" ) + string( REGEX REPLACE "-l" "" _lib ${_arg} ) + # + # Try to find that library, so we get its full path. See the + # comment above for why we do this. + # + # Furthermore, the pcap-config shipped with macOS reports + # -I/usr/local/include for --cflags and -L/usr/local/lib for + # --libs, rather than reporting the appropriate system (or + # Xcode application) directory. + # + find_library( _libfullpath ${_lib} HINTS ${__pcap_library_dirs} ) + list( APPEND PCAP_LIBRARIES ${_libfullpath} ) + # + # Remove that from the cache; we're using it as a local variable, + # but find_library insists on making it a cache variable. + # + unset( _libfullpath CACHE ) + endif() + endforeach() + + # Now, get the library directories and libraries for static linking. + # (XXX - what about AIX?) + execute_process( COMMAND "${PCAP_CONFIG}" "--libs" "--static" + RESULT_VARIABLE PCAP_CONFIG_RESULT + OUTPUT_VARIABLE PCAP_CONFIG_OUTPUT + ) + if( NOT PCAP_CONFIG_RESULT EQUAL 0 ) + message( FATAL_ERROR "pcap-config --libs --static failed" ) + endif() + separate_arguments( LIBS_LIST UNIX_COMMAND ${PCAP_CONFIG_OUTPUT} ) + set( _pcap_static_library_dirs "" ) + set( PCAP_STATIC_LIBRARIES "" ) + set( SAVED_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}" ) + set( CMAKE_FIND_LIBRARY_SUFFIXES ".a" ) + foreach( _arg IN LISTS LIBS_LIST ) + if( _arg MATCHES "^-L" ) + # Add this directory to _pcap_static_library_dirs + string( REGEX REPLACE "-L" "" _dir ${_arg} ) + list( APPEND _pcap_static_library_dirs ${_dir} ) + elseif( _arg MATCHES "^-l" ) + string( REGEX REPLACE "-l" "" _lib ${_arg} ) + # + # Try to find that library, so we get its full path, as + # we do with dynamic libraries. + # + find_library( _libfullpath ${_lib} HINTS ${__pcap_static_library_dirs} ) + list( APPEND PCAP_STATIC_LIBRARIES ${_libfullpath} ) + # + # Remove that from the cache; we're using it as a local variable, + # but find_library insists on making it a cache variable. + # + unset( _libfullpath CACHE ) + endif() + endforeach() + + set( CMAKE_FIND_LIBRARY_SUFFIXES "${SAVED_CMAKE_FIND_LIBRARY_SUFFIXES}" ) + else( PCAP_CONFIG ) + # + # We don't have pcap-config. + # Try to find the header by just looking for it in whatever + # directories find_path() uses by default, plus ${PCAP_HINTS}. + # + find_path( PCAP_INCLUDE_DIRS + NAMES + pcap/pcap.h + pcap.h + HINTS + "${PCAP_HINTS}/include" + ) + + # Try to find the library + if( WIN32 ) + # The 64-bit Packet.lib is located under /x64 + if( "${WIRESHARK_TARGET_PLATFORM}" STREQUAL "win64" ) + # + # For the WinPcap and Npcap SDKs, the Lib subdirectory of the top-level + # directory contains 32-bit libraries; the 64-bit libraries are in the + # Lib/x64 directory. + # + # The only way to *FORCE* CMake to look in the Lib/x64 directory + # without searching in the Lib directory first appears to be to set + # CMAKE_LIBRARY_ARCHITECTURE to "x64". + # + set(CMAKE_LIBRARY_ARCHITECTURE "x64") + endif() + endif() + + find_library( PCAP_LIBRARIES + NAMES + pcap + wpcap + HINTS + "${PCAP_HINTS}/lib${_PLATFORM_SUBDIR}" + ) + + if( NOT WIN32 ) + # Try to find the static library (XXX - what about AIX?) + set( SAVED_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}") + set( CMAKE_FIND_LIBRARY_SUFFIXES ".a" ) + find_library( PCAP_STATIC_LIBRARIES + NAMES + pcap + wpcap + HINTS + "${PCAP_HINTS}/lib${_PLATFORM_SUBDIR}" + ) + set( CMAKE_FIND_LIBRARY_SUFFIXES "${SAVED_CMAKE_FIND_LIBRARY_SUFFIXES}") + endif( NOT WIN32 ) + endif( PCAP_CONFIG ) +endif( PCAP_FOUND ) include( FindPackageHandleStandardArgs ) -find_package_handle_standard_args( PCAP DEFAULT_MSG PCAP_LIBRARY PCAP_INCLUDE_DIR ) +find_package_handle_standard_args( PCAP DEFAULT_MSG PCAP_LIBRARIES PCAP_INCLUDE_DIRS ) -if( PCAP_FOUND ) - set( PCAP_INCLUDE_DIRS ${PCAP_INCLUDE_DIR} ) - set( PCAP_LIBRARIES ${PCAP_LIBRARY} ) +mark_as_advanced( PCAP_INCLUDE_DIR PCAP_LIBRARY PCAP_STATIC_LIBRARY ) +if( PCAP_FOUND ) # Include transitive dependencies for static linking. - # This requires: - # 1) a system with pkg-config installed - # 2) libpcap >= 1.9.0 with its .pc files installed if( UNIX AND CMAKE_FIND_LIBRARY_SUFFIXES STREQUAL ".a" ) - find_package( PkgConfig ) - pkg_search_module( PC_LIBPCAP libpcap ) - list( APPEND PCAP_LIBRARIES ${PC_LIBPCAP_LIBRARIES} ) + set( PCAP_LIBRARIES ${PCAP_STATIC_LIBRARIES} ) endif() -else() - set( PCAP_INCLUDE_DIRS ) - set( PCAP_LIBRARIES ) -endif() -if( PCAP_FOUND ) #Functions include( CMakePushCheckState ) include( CheckFunctionExists ) @@ -143,5 +332,3 @@ if( PCAP_FOUND ) cmake_pop_check_state() endif() - -mark_as_advanced( PCAP_LIBRARIES PCAP_INCLUDE_DIRS ) |