Skip to content

Commit e75541c

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. (backported from commit c02b47d)
1 parent b7d5074 commit e75541c

File tree

3 files changed

+110
-3
lines changed

3 files changed

+110
-3
lines changed

CMakeLists.txt

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -794,8 +794,55 @@ endif(NOT HAVE_PCAP_LIB_VERSION)
794794
check_function_exists(pcap_setdirection HAVE_PCAP_SETDIRECTION)
795795
check_function_exists(pcap_set_immediate_mode HAVE_PCAP_SET_IMMEDIATE_MODE)
796796
check_function_exists(pcap_dump_ftell64 HAVE_PCAP_DUMP_FTELL64)
797-
check_function_exists(pcap_open HAVE_PCAP_OPEN)
798-
check_function_exists(pcap_findalldevs_ex HAVE_PCAP_FINDALLDEVS_EX)
797+
#
798+
# macOS Sonoma's libpcap includes stub versions of the remote-
799+
# capture APIs. They are exported as "weakly linked symbols".
800+
#
801+
# Xcode 15 offers only a macOS Sonoma SDK, which has a .tbd
802+
# file for libpcap that claims it includes those APIs. (Newer
803+
# versions of macOS don't provide the system shared libraries,
804+
# they only provide the dyld shared cache containing those
805+
# libraries, so the OS provides SDKs that include a .tbd file
806+
# to use when linking.)
807+
#
808+
# This means that check_function_exists() will think that
809+
# the remote-capture APIs are present, including pcap_open().
810+
#
811+
# However, they are *not* present in macOS Ventura and earlier,
812+
# which means that building on Ventura with Xcode 15 produces
813+
# executables that fail to start because one of those APIs
814+
# isn't found in the system libpcap.
815+
#
816+
# Protecting calls to those APIs with __builtin_available()
817+
# does not prevent this, because the libpcap header files
818+
# in the Sonoma SDK mark them as being first available
819+
# in macOS 10.13, just like all the other routines introduced
820+
# in libpcap 1.9, even though they're only available if libpcap
821+
# is built with remote capture enabled or stub routines are
822+
# provided. (A fix to enable this has been checked into the
823+
# libpcap repository, and may end up in a later version of
824+
# the SDK.)
825+
#
826+
# Given all that, and given that the versions of the
827+
# remote-capture APIs in Sonoma are stubs that always fail,
828+
# there doesn't seem to be any point in checking for pcap_open()
829+
# if we're linking against the Apple libpcap.
830+
#
831+
# However, if we're *not* linking against the Apple libpcap,
832+
# we should check for it, so that we can use it if it's present.
833+
#
834+
# So we check for pcap_open if 1) this isn't macOS or 2) the
835+
# the libpcap we found is not a system library, meaning that
836+
# its path begins neither with /usr/lib (meaning it's a system
837+
# dylib) nor /Application/Xcode.app (meaning it's a file in
838+
# the Xcode SDK).
839+
#
840+
if(NOT APPLE OR NOT
841+
(PCAP_LIBRARIES MATCHES "/usr/lib/.*" OR
842+
PCAP_LIBRARIES MATCHES "/Application/Xcode.app/.*"))
843+
check_function_exists(pcap_open HAVE_PCAP_OPEN)
844+
check_function_exists(pcap_findalldevs_ex HAVE_PCAP_FINDALLDEVS_EX)
845+
endif()
799846

800847
#
801848
# 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
@@ -599,6 +599,59 @@ AC_DEFUN(AC_LBL_LIBPCAP,
599599
# ignore those values.
600600
#
601601
_broken_apple_pcap_config=yes
602+
603+
#
604+
# Furthermore:
605+
#
606+
# macOS Sonoma's libpcap includes stub versions
607+
# of the remote-capture APIs. They are exported
608+
# as "weakly linked symbols".
609+
#
610+
# Xcode 15 offers only a macOS Sonoma SDK, which
611+
# has a .tbd file for libpcap that claims it
612+
# includes those APIs. (Newer versions of macOS
613+
# don't provide the system shared libraries,
614+
# they only provide the dyld shared cache
615+
# containing those libraries, so the OS provides
616+
# SDKs that include a .tbd file to use when
617+
# linking.)
618+
#
619+
# This means that AC_CHECK_FUNCS() will think
620+
# that the remote-capture APIs are present,
621+
# including pcap_open() and
622+
# pcap_findalldevs_ex().
623+
#
624+
# However, they are *not* present in macOS
625+
# Ventura and earlier, which means that building
626+
# on Ventura with Xcode 15 produces executables
627+
# that fail to start because one of those APIs
628+
# isn't found in the system libpcap.
629+
#
630+
# Protecting calls to those APIs with
631+
# __builtin_available() does not appear to
632+
# prevent this, for some unknown reason, and it
633+
# doesn't even allow the program to compile with
634+
# versions of Xcode prior to Xcode 15, as the
635+
# pcap.h file doesn't specify minimum OS
636+
# versions for those functions.
637+
#
638+
# Given all that, and given that the versions of
639+
# the remote-capture APIs in Sonoma are stubs
640+
# that always fail, there doesn't seem to be any
641+
# point in checking for pcap_open() if we're
642+
# linking against the Apple libpcap.
643+
#
644+
# However, if we're *not* linking against the
645+
# Apple libpcap, we should check for it, so that
646+
# we can use it if it's present.
647+
#
648+
# We know this is macOS and that we're using
649+
# the system-provided pcap-config to find
650+
# libpcap, so we know it'll be the system
651+
# libpcap, and note that we should not search
652+
# for remote-capture APIs.
653+
#
654+
_dont_check_for_remote_apis=yes
602655
;;
603656
604657
solaris*)

configure.ac

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,14 @@ if test $ac_cv_func_pcap_lib_version = "no" ; then
810810
fi
811811
fi
812812
AC_CHECK_FUNCS(pcap_setdirection pcap_set_immediate_mode pcap_dump_ftell64)
813-
AC_CHECK_FUNCS(pcap_open pcap_findalldevs_ex)
813+
#
814+
# See the comment in AC_LBL_LIBPCAP in aclocal.m4 for the reason
815+
# why we don't check for remote-capture APIs if we're building
816+
# with the system libpcap on macOS.
817+
#
818+
if test "$_dont_check_for_remote_apis" != "yes"; then
819+
AC_CHECK_FUNCS(pcap_open pcap_findalldevs_ex)
820+
fi
814821
AC_REPLACE_FUNCS(pcap_dump_ftell)
815822

816823
#

0 commit comments

Comments
 (0)