Skip to content

Commit c02b47d

Browse files
committed
autotools, cmake: work around an Xcode 15+ issue.
There appears to be no way to build tcpdump on macOS Ventura with Xcode 15 with the system libpcap and have the resulting program run without getting an error due to failing to find pcap_open() or pcap_findalldevs_ex() at startup. In particular, there appears to be no way to use __builtin_available() to protect accesses to the routines that showed up in Sonoma, so that the run-time linker doesn't fail if the routine in question isn't present. Perhaps it requires more compiler command-line arguments. So, instead, only check for pcap_open() and pcap_findalldevs_ex() if 1) this isn't macOS or 2) we're not building with the system libpcap.
1 parent 8e12b7f commit c02b47d

File tree

3 files changed

+109
-2
lines changed

3 files changed

+109
-2
lines changed

CMakeLists.txt

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,54 @@ check_function_exists(pcap_set_tstamp_precision HAVE_PCAP_SET_TSTAMP_PRECISION)
713713
#
714714
check_function_exists(pcap_set_immediate_mode HAVE_PCAP_SET_IMMEDIATE_MODE)
715715
check_function_exists(pcap_dump_ftell64 HAVE_PCAP_DUMP_FTELL64)
716-
check_function_exists(pcap_open HAVE_PCAP_OPEN)
716+
#
717+
# macOS Sonoma's libpcap includes stub versions of the remote-
718+
# capture APIs. They are exported as "weakly linked symbols".
719+
#
720+
# Xcode 15 offers only a macOS Sonoma SDK, which has a .tbd
721+
# file for libpcap that claims it includes those APIs. (Newer
722+
# versions of macOS don't provide the system shared libraries,
723+
# they only provide the dyld shared cache containing those
724+
# libraries, so the OS provides SDKs that include a .tbd file
725+
# to use when linking.)
726+
#
727+
# This means that check_function_exists() will think that
728+
# the remote-capture APIs are present, including pcap_open().
729+
#
730+
# However, they are *not* present in macOS Ventura and earlier,
731+
# which means that building on Ventura with Xcode 15 produces
732+
# executables that fail to start because one of those APIs
733+
# isn't found in the system libpcap.
734+
#
735+
# Protecting calls to those APIs with __builtin_available()
736+
# does not prevent this, because the libpcap header files
737+
# in the Sonoma SDK mark them as being first available
738+
# in macOS 10.13, just like all the other routines introduced
739+
# in libpcap 1.9, even though they're only available if libpcap
740+
# is built with remote capture enabled or stub routines are
741+
# provided. (A fix to enable this has been checked into the
742+
# libpcap repository, and may end up in a later version of
743+
# the SDK.)
744+
#
745+
# Given all that, and given that the versions of the
746+
# remote-capture APIs in Sonoma are stubs that always fail,
747+
# there doesn't seem to be any point in checking for pcap_open()
748+
# if we're linking against the Apple libpcap.
749+
#
750+
# However, if we're *not* linking against the Apple libpcap,
751+
# we should check for it, so that we can use it if it's present.
752+
#
753+
# So we check for pcap_open if 1) this isn't macOS or 2) the
754+
# the libpcap we found is not a system library, meaning that
755+
# its path begins neither with /usr/lib (meaning it's a system
756+
# dylib) nor /Application/Xcode.app (meaning it's a file in
757+
# the Xcode SDK).
758+
#
759+
if(NOT APPLE OR NOT
760+
(PCAP_LIBRARIES MATCHES "/usr/lib/.*" OR
761+
PCAP_LIBRARIES MATCHES "/Application/Xcode.app/.*"))
762+
check_function_exists(pcap_open HAVE_PCAP_OPEN)
763+
endif()
717764

718765
#
719766
# On Windows, check for pcap_wsockinit(); if we don't have it, check for

aclocal.m4

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,59 @@ AC_DEFUN(AC_LBL_LIBPCAP,
454454
# ignore those values.
455455
#
456456
_broken_apple_pcap_config=yes
457+
458+
#
459+
# Furthermore:
460+
#
461+
# macOS Sonoma's libpcap includes stub versions
462+
# of the remote-capture APIs. They are exported
463+
# as "weakly linked symbols".
464+
#
465+
# Xcode 15 offers only a macOS Sonoma SDK, which
466+
# has a .tbd file for libpcap that claims it
467+
# includes those APIs. (Newer versions of macOS
468+
# don't provide the system shared libraries,
469+
# they only provide the dyld shared cache
470+
# containing those libraries, so the OS provides
471+
# SDKs that include a .tbd file to use when
472+
# linking.)
473+
#
474+
# This means that AC_CHECK_FUNCS() will think
475+
# that the remote-capture APIs are present,
476+
# including pcap_open() and
477+
# pcap_findalldevs_ex().
478+
#
479+
# However, they are *not* present in macOS
480+
# Ventura and earlier, which means that building
481+
# on Ventura with Xcode 15 produces executables
482+
# that fail to start because one of those APIs
483+
# isn't found in the system libpcap.
484+
#
485+
# Protecting calls to those APIs with
486+
# __builtin_available() does not appear to
487+
# prevent this, for some unknown reason, and it
488+
# doesn't even allow the program to compile with
489+
# versions of Xcode prior to Xcode 15, as the
490+
# pcap.h file doesn't specify minimum OS
491+
# versions for those functions.
492+
#
493+
# Given all that, and given that the versions of
494+
# the remote-capture APIs in Sonoma are stubs
495+
# that always fail, there doesn't seem to be any
496+
# point in checking for pcap_open() if we're
497+
# linking against the Apple libpcap.
498+
#
499+
# However, if we're *not* linking against the
500+
# Apple libpcap, we should check for it, so that
501+
# we can use it if it's present.
502+
#
503+
# We know this is macOS and that we're using
504+
# the system-provided pcap-config to find
505+
# libpcap, so we know it'll be the system
506+
# libpcap, and note that we should not search
507+
# for remote-capture APIs.
508+
#
509+
_dont_check_for_remote_apis=yes
457510
;;
458511
459512
solaris*)

configure.ac

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,14 @@ AC_CHECK_FUNCS(pcap_set_tstamp_precision)
580580
# if we have them.
581581
#
582582
AC_CHECK_FUNCS(pcap_set_immediate_mode pcap_dump_ftell64)
583-
AC_CHECK_FUNCS(pcap_open pcap_findalldevs_ex)
583+
#
584+
# See the comment in AC_LBL_LIBPCAP in aclocal.m4 for the reason
585+
# why we don't check for remote-capture APIs if we're building
586+
# with the system libpcap on macOS.
587+
#
588+
if test "$_dont_check_for_remote_apis" != "yes"; then
589+
AC_CHECK_FUNCS(pcap_open pcap_findalldevs_ex)
590+
fi
584591

585592
#
586593
# Check for special debugging functions

0 commit comments

Comments
 (0)