]> The Tcpdump Group git mirrors - tcpdump/blobdiff - cmake/Modules/FindPCAP.cmake
Makefile.in: don't remove configure and config.h.in in make distclean.
[tcpdump] / cmake / Modules / FindPCAP.cmake
index 3b83c7a79fab45785ea6932df5f92251cab5d0b6..11074655f45763c7e4c1b468fd157e487a21e170 100644 (file)
@@ -1,6 +1,12 @@
 #
 # Try to find libpcap.
 #
+# To tell this module where to look, a user may set the environment variable
+# PCAP_ROOT to point cmake to the *root* of a directory with include and
+# lib subdirectories for pcap.dll (e.g WpdPack or npcap-sdk).
+# Alternatively, PCAP_ROOT may also be set from cmake command line or GUI
+# (e.g cmake -DPCAP_ROOT=C:\path\to\pcap [...])
+#
 
 if(WIN32)
   #
@@ -73,9 +79,106 @@ else(WIN32)
 
   #
   # First, try pkg-config.
+  # Before doing so, set the PKG_CONFIG_PATH environment variable
+  # to include all the directories in CMAKE_PREFIX_PATH.
+  #
+  # *If* we were to require CMake 3.1 or later on UN*X,
+  # pkg_search_module() would do this for us, but, for now,
+  # we're not doing that, in case somebody's building with
+  # CMake on some "long-term support" version, predating
+  # CMake 3.1, of an OS that supplies an earlier
+  # version as a package.
+  #
+  # If we ever set a minimum of 3.1 or later on UN*X, we should
+  # remove the environment variable changes.
+  #
+  # This is based on code in the CMake 3.12.4 FindPkgConfig.cmake,
+  # which is "Distributed under the OSI-approved BSD 3-Clause License."
   #
   find_package(PkgConfig)
+
+  #
+  # Get the current PKG_CONFIG_PATH setting.
+  #
+  set(_pkg_config_path "$ENV{PKG_CONFIG_PATH}")
+
+  #
+  # Save it, so we can restore it after we run pkg-config.
+  #
+  set(_saved_pkg_config_path "${_pkg_config_path}")
+
+  if(NOT "${CMAKE_PREFIX_PATH}" STREQUAL "")
+    #
+    # Convert it to a CMake-style path, before we add additional
+    # values to it.
+    #
+    if(NOT "${_pkg_config_path}" STREQUAL "")
+      file(TO_CMAKE_PATH "${_pkg_config_path}" _pkg_config_path)
+    endif()
+
+    #
+    # Turn CMAKE_PREFIX_PATH into a list of extra paths to add
+    # to _pkg_config_path.
+    #
+    set(_extra_paths "")
+    list(APPEND _extra_paths ${CMAKE_PREFIX_PATH})
+
+    # Create a list of the possible pkgconfig subfolder (depending on
+    # the system
+    set(_lib_dirs)
+    if(NOT DEFINED CMAKE_SYSTEM_NAME
+        OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
+            AND NOT CMAKE_CROSSCOMPILING))
+      if(EXISTS "/etc/debian_version") # is this a debian system ?
+        if(CMAKE_LIBRARY_ARCHITECTURE)
+          list(APPEND _lib_dirs "lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig")
+        endif()
+      else()
+        # not debian, check the FIND_LIBRARY_USE_LIB32_PATHS and FIND_LIBRARY_USE_LIB64_PATHS properties
+        get_property(uselib32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS)
+        if(uselib32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
+          list(APPEND _lib_dirs "lib32/pkgconfig")
+        endif()
+        get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
+        if(uselib64 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+          list(APPEND _lib_dirs "lib64/pkgconfig")
+        endif()
+        get_property(uselibx32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIBX32_PATHS)
+        if(uselibx32 AND CMAKE_INTERNAL_PLATFORM_ABI STREQUAL "ELF X32")
+          list(APPEND _lib_dirs "libx32/pkgconfig")
+        endif()
+      endif()
+    endif()
+    if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" AND NOT CMAKE_CROSSCOMPILING)
+      list(APPEND _lib_dirs "libdata/pkgconfig")
+    endif()
+    list(APPEND _lib_dirs "lib/pkgconfig")
+    list(APPEND _lib_dirs "share/pkgconfig")
+
+    # Check if directories exist and eventually append them to the
+    # pkgconfig path list
+    foreach(_prefix_dir ${_extra_paths})
+      foreach(_lib_dir ${_lib_dirs})
+        if(EXISTS "${_prefix_dir}/${_lib_dir}")
+          list(APPEND _pkg_config_path "${_prefix_dir}/${_lib_dir}")
+          list(REMOVE_DUPLICATES _pkg_config_path)
+        endif()
+      endforeach()
+    endforeach()
+
+    if(NOT "${_pkg_config_path}" STREQUAL "")
+      # remove empty values from the list
+      list(REMOVE_ITEM _pkg_config_path "")
+      file(TO_NATIVE_PATH "${_pkg_config_path}" _pkg_config_path)
+      if(UNIX)
+        string(REPLACE ";" ":" _pkg_config_path "${_pkg_config_path}")
+        string(REPLACE "\\ " " " _pkg_config_path "${_pkg_config_path}")
+      endif()
+      set(ENV{PKG_CONFIG_PATH} "${_pkg_config_path}")
+    endif()
+  endif()
   pkg_search_module(CONFIG_PCAP ${_quiet} libpcap)
+  set(ENV{PKG_CONFIG_PATH} "${_saved_pkg_config_path}")
 
   if(NOT CONFIG_PCAP_FOUND)
     #
@@ -91,17 +194,57 @@ else(WIN32)
       endif()
 
       #
-      # if this is macOS or some other Darwin-based OS, check whether
-      # it's the system-supplied one.
+      # If this is a vendor-supplied pcap-config, which we define as
+      # being "a pcap-config in /usr/bin or /usr/ccs/bin" (the latter
+      # is for Solaris and Sun/Oracle Studio), there are some issues.
+      # Work around them.
       #
-      if(APPLE AND "${PCAP_CONFIG}" STREQUAL /usr/bin/pcap-config)
+      if("${PCAP_CONFIG}" STREQUAL /usr/bin/pcap-config OR
+         "${PCAP_CONFIG}" STREQUAL /usr/ccs/bin/pcap-config)
         #
-        # It is - remember that, so that if it provides -I/usr/local/include
-        # with --cflags, or -L/usr/local/lib with --libs, we ignore it;
-        # the macOS pcap-config does that even though the headers aren't
-        # under /usr/local/include and the library isn't in /usr/local/lib.
+        # It's vendor-supplied.
         #
-        set(_broken_apple_pcap_config TRUE)
+        if(APPLE)
+          #
+          # This is macOS or another Darwin-based OS.
+          #
+          # That means that /usr/bin/pcap-config it may provide
+          # -I/usr/local/include with --cflags and -L/usr/local/lib
+          # with --libs; if there's no pcap installed under /usr/local,
+          # that will cause the build to fail, and if there is a pcap
+          # installed there, you'll get that pcap even if you don't
+          # want it.  Remember that, so we ignore those values.
+          #
+          set(_broken_apple_pcap_config TRUE)
+        elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*")
+          #
+          # This is Solaris 2 or later, i.e. SunOS 5.x.
+          #
+          # At least on Solaris 11; there's /usr/bin/pcap-config, which
+          # reports -L/usr/lib with --libs, causing the 32-bit libraries
+          # to be found, and there's /usr/bin/{64bitarch}/pcap-config,
+          # where {64bitarch} is a name for the 64-bit version of the
+          # instruction set, which reports -L /usr/lib/{64bitarch},
+          # causing the 64-bit libraries to be found.
+          #
+          # So if we're building 64-bit targets, we replace PCAP_CONFIG
+          # with /usr/bin/{64bitarch}; we get {64bitarch} as the
+          # output of "isainfo -n".
+          #
+          if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+            execute_process(COMMAND "isainfo" "-n"
+              RESULT_VARIABLE ISAINFO_RESULT
+              OUTPUT_VARIABLE ISAINFO_OUTPUT
+              OUTPUT_STRIP_TRAILING_WHITESPACE
+            )
+            if(ISAINFO_RESULT EQUAL 0)
+              #
+              # Success - change PCAP_CONFIG.
+              #
+              string(REPLACE "/bin/" "/bin/${ISAINFO_OUTPUT}/" PCAP_CONFIG "${PCAP_CONFIG}")
+            endif()
+          endif()
+        endif()
       endif()
 
       #