--- Begin Message ---
Hello list.

Travis CI tcpdump builds have been failing for a while and I went to
see why. It is easy to see that only the jobs that have
"BUILD_LIBPCAP=yes CMAKE=yes" fail, for example [1], and the same jobs
built well before, for example [2].

The tcpdump build process fails in these cases because CMake detects
the presence and usability of particular libpcap elements before the
compilation, but during the compilation the compiler is not finding
these elements. For example:

tcpdump.c:1251:19: error: ‘PCAP_OPENFLAG_PROMISCUOUS’ undeclared (first
use in this function); did you mean ‘PCAP_WARNING_PROMISC_NOTSUP’?

(The above compiles only when HAVE_PCAP_OPEN is defined.)

I have spent some time trying to reproduce the amd64 Linux GCC case on
my desktop. Initially I though it was a regression in libpcap because
tcpdump had no meaningful changes between the successful and the failed
jobs, and the job always clones the current master branch of libpcap.

As it turned out, the reason for failure was not because of a change in
tcpdump or libpcap, but because of a change in the Travis CI build
environment, which is Ubuntu 18.04 and which recently started to include
a pkg-config file in the libpcap package:

libpcap (1.8.1-6ubuntu1.18.04.2) bionic; urgency=medium

  * Install pkg-config file for libpcap (LP: #1865501).
    - d/p/set-package-name-with-ac-init.patch: Set the PACKAGE_NAME
      variable using autoconf's AC_INIT macro, so that we can use it
      in the libpcap.pc.in file.
    - d/p/use-m4-macro-to-get-version.patch: Use an M4 macro to
      execute a "cat" command and obtain the version from the VERSION
      file.
    - d/p/install-pkg-config-file.patch: New patch from upstream,
      which creates a libpcap.pc.in file and adjusts the Makefile to
      install it.
    - d/libpcap0.8-dev.install: Install libpcap.pc pkg-config file.
      Thanks to Luca Boccassi for the Debian patch (Closes #922219).

 -- Sergio Durigan Junior <sergio.duri...@canonical.com>  Mon, 29 Jun
 2020 17:49:04 -0400


If you examine the provided example jobs closely (the "Raw log" button
returns the full output in plain text), here is the difference in CMake
output when the job changes from good to bad:

@@ -71,9 +71,8 @@
 -- Check size of struct in6_addr - done
 -- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1") 
 -- Checking for one of the modules 'libpcap'
--- Found pcap-config
 -- Looking for pcap/pcap-inttypes.h
--- Looking for pcap/pcap-inttypes.h - found
+-- Looking for pcap/pcap-inttypes.h - not found
 -- Looking for pcap_list_datalinks
 -- Looking for pcap_list_datalinks - found
 -- Looking for pcap_free_datalinks

The "Found pcap-config" message means that FindPCAP.cmake has not found
libpcap by means of pkg-config, and the lack of the message means the
pkg-config method worked. A few weeks ago Ubuntu 18.04 systems started
to have the libpcap.pc file in the libpcap0.8-dev package, so on such a
system "pkg-config --libs libpcap" now prints "-lpcap" and "pkg-config
--cflags libpcap" prints an empty string, which makes sense.

What does not make sense is that CMake seems to use non-pkg-config
flags to tell if a specific feature is available, but uses pkg-config
flags to compile and link the source, and when the system has one
libpcap version installed as a package and another version that the
user wants to build with, that very easily breaks (and even if it does
not, the end result is not what the user was expecting).

Here are my steps to reproduce:

libpcap$ ./configure --enable-remote --prefix=/tmp/libpcap
libpcap$ make
libpcap$ make install
tcpdumpbuild$ cmake -DWITH_CRYPTO="yes"
-DCMAKE_PREFIX_PATH=/tmp/libpcap -DCMAKE_INSTALL_PREFIX=/tmp/libpcap
/path/to/tcpdump_git_clone

The above fails if the package libpcap0.8-dev is installed. After
removing the package the above works and tcpdump links
with /tmp/libpcap/lib/libpcap.so.1 as expected.

Clearly, there are cases where using pkg-config would be the right
thing to do. But is seems wrong to try it always as the first choice.
Perhaps it would be better to try pkg-config after the user-specified
prefix did not result in a usable libpcap.

Autoconf is not entirely consistent with CMake, in that it tries
pkg-config before libpcap in the specified prefix directory too, but
there are differences:
* Before these two methods autoconf checks for libpcap in ../libpcap
  and links it statically if it is available. CMake does not do that.
* If the above was not the case, the pkg-config method works in
  autoconf, so tcpdump is linked with the system libpcap. CMake build
  breaks in this case.
* If the above was not the case and ./configure is given a prefix, it
  fails to find libpcap under that prefix. CMake gets that right.

To me right now it looks as if the best first thing to do would be
fixing pkg-config in CMake, that should recover Travis CI. Then the
next best thing to do would be reordering the steps in both autoconf and
CMake to try pkg-config after pcap-config, not before (that should
prevent unexpected build results as libpcap.pc is propagating
through Linux systems). After that it would be nice to have ../libpcap
support in CMake and a full --prefix support in ./configure for full
consistency.

Does it make sense?

1: https://travis-ci.org/github/the-tcpdump-group/tcpdump/jobs/724717360
2: https://travis-ci.org/github/the-tcpdump-group/tcpdump/jobs/721706654

-- 
    Denis Ovsienko

--- End Message ---
_______________________________________________
tcpdump-workers mailing list
tcpdump-workers@lists.tcpdump.org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers

Reply via email to