X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/cdca504371641e71ca82f4ae3e43c88d43287578..refs/pull/1036/head:/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 8fa04bcf..fa865703 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,10 +2,11 @@ if(WIN32) # # We need 3.12 or later, so that we can set policy CMP0074; see # below. + # cmake_minimum_required(VERSION 3.12) else(WIN32) # - # For now, require only 2.8.6, just in case somebody is + # For now, require only 2.8.12, just in case somebody is # configuring with CMake on a "long-term support" version # of some OS and that version supplies an older version of # CMake. @@ -16,7 +17,7 @@ else(WIN32) # environment variable when running pkg-config, to make sure # it finds any .pc file from there. # - cmake_minimum_required(VERSION 2.8.6) + cmake_minimum_required(VERSION 2.8.12) endif(WIN32) # @@ -28,10 +29,70 @@ if(POLICY CMP0074) cmake_policy(SET CMP0074 NEW) endif() +# +# OK, this is a pain. +# +# When building on NetBSD, with a libpcap installed from pkgsrc, +# a -Wl,-rpath,/usr/pkg/lib option is added to the options when +# linking tcpdump. This puts /usr/pkg/lib into the run-time path. +# +# However, by default, CMake adds a rule to the install CMake script +# a CMake command (using an undocumented subcommand of file()) that +# strips /usr/pkg/lib *out* of the run-time path; the message in the +# output for the "install" target is +# +# -- Set runtime path of "{target-directory}/tcpdump" to "" +# +# I am not certain what the rationale is for doing this, but a +# *consequence* of this is that, when you run the installed tcpdump, +# it fails to find libpcap.so: +# +# $ {target-directory}/tcpdump -h +# {target-directory}/tcpdump: Shared object "libpcap.so.0" not found +# +# It also appears to be the case that, on Ubuntu 22.04, FreeBSD 12, +# DragonFly BSD 5.8, OpenBSD 6.6, and Solaris 11.4, +# +# On Ubuntu and Solaris, even if you have a libpcap in /usr/local, you +# have to provide not only -I/usr/local/include and -L/usr/local/lib, +# you also must provide -Wl,-rpath,/usr/local/lib in order to have +# the run-time linker look in /usr/local/lib for libpcap. If it's not +# specified, then, if the shared library major version number of the +# libpcap in /usr/lib is the same as the shared major version number +# of the libpcap in /usr/local/lib, the run-time linker will find the +# libpcap in /usr/lib; if the versions are different, the run-time +# linker will fail to find the libpcap in /usr/lib, so the program will +# fail to run. +# +# We suppress this by setting CMAKE_INSTALL_RPATH_USE_LINK_PATH to TRUE; +# as the documentation for that variable says: +# +# Add paths to linker search and installed rpath. +# +# CMAKE_INSTALL_RPATH_USE_LINK_PATH is a boolean that if set to True +# will append to the runtime search path (rpath) of installed +# binaries any directories outside the project that are in the linker +# search path or contain linked library files. The directories are +# appended after the value of the INSTALL_RPATH target property. +# +# If, for whatever reason, directories in which we search for external +# libraries, other than the standard system library directories, are +# added to the executable's rpath in the build process, we most +# defintely want them in the installed image's rpath if they are +# necessary in order to find the libraries at run time. +# +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) # -# OK, this is a royal pain. +# We explicitly indicate what languages are used in tcpdump to avoid +# checking for a C++ compiler. +# +# One reason to avoid that check is that there's no need to waste +# configuration time performing it. +# +# Another reason is that: # # CMake will try to determine the sizes of some data types, including # void *, early in the process of configuration; apparently, it's done @@ -57,9 +118,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) # building 32-bit, the size for C++ will win, and, again, hilarity # will ensue. # -# So we *explicitly* state that only C is used; there is currently no -# C++ code in tcpdump. -# project(tcpdump C) # @@ -275,22 +333,12 @@ check_include_file(net/if.h HAVE_NET_IF_H) if(HAVE_RPC_RPC_H) check_include_files("rpc/rpc.h;rpc/rpcent.h" HAVE_RPC_RPCENT_H) endif(HAVE_RPC_RPC_H) -if(NOT WIN32) - check_include_files("sys/types.h;sys/socket.h;net/if.h;net/pfvar.h" HAVE_NET_PFVAR_H) - if(HAVE_NET_PFVAR_H) - check_include_files("sys/types.h;sys/socket.h;net/if.h;net/pfvar.h;net/if_pflog.h" HAVE_NET_IF_PFLOG_H) - if(HAVE_NET_IF_PFLOG_H) - set(LOCALSRC print-pflog.c ${LOCALSRC}) - endif(HAVE_NET_IF_PFLOG_H) - endif(HAVE_NET_PFVAR_H) -endif(NOT WIN32) # # Functions. # check_function_exists(strlcat HAVE_STRLCAT) check_function_exists(strlcpy HAVE_STRLCPY) -check_function_exists(strdup HAVE_STRDUP) check_function_exists(strsep HAVE_STRSEP) # @@ -323,7 +371,12 @@ else(WIN32) if(LIBNSL_HAS_GETHOSTBYADDR) set(TCPDUMP_LINK_LIBRARIES ${TCPDUMP_LINK_LIBRARIES} nsl) else(LIBNSL_HAS_GETHOSTBYADDR) - message(FATAL_ERROR "gethostbyaddr is required, but wasn't found") + check_library_exists(network gethostbyaddr "" LIBNETWORK_HAS_GETHOSTBYADDR) + if(LIBNETWORK_HAS_GETHOSTBYADDR) + set(TCPDUMP_LINK_LIBRARIES ${TCPDUMP_LINK_LIBRARIES} network) + else(LIBNETWORK_HAS_GETHOSTBYADDR) + message(FATAL_ERROR "gethostbyaddr is required, but wasn't found") + endif(LIBNETWORK_HAS_GETHOSTBYADDR) endif(LIBNSL_HAS_GETHOSTBYADDR) endif(LIBSOCKET_HAS_GETHOSTBYADDR) endif(NOT STDLIBS_HAVE_GETHOSTBYADDR) @@ -351,22 +404,69 @@ endif(STDLIBS_HAVE_GETSERVENT) cmake_pop_check_state() # -# Make sure we have vsnprintf() and snprintf(); we require them. -# We use check_symbol_exists(), as they aren't necessarily external -# functions - in Visual Studio, for example, they're inline functions -# calling a common external function. +# Make sure we have snprintf(); we require it. +# We use check_symbol_exists(), as it isn't necessarily an external +# function - in Visual Studio, for example, it is an inline function +# calling an external function. # -check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF) -if(NOT HAVE_VSNPRINTF) - message(FATAL_ERROR "vsnprintf() is required but wasn't found") -endif(NOT HAVE_VSNPRINTF) check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF) if(NOT HAVE_SNPRINTF) message(FATAL_ERROR "snprintf() is required but wasn't found") endif() +# +# Require a proof of suitable snprintf(3), same as in Autoconf. +# +include(CheckCSourceRuns) +check_c_source_runs(" +#include +#include +#include +#include + +int main() +{ + char buf[100]; + uint64_t t = (uint64_t)1 << 32; + + snprintf(buf, sizeof(buf), \"%zu\", sizeof(buf)); + if (strncmp(buf, \"100\", sizeof(buf))) + return 1; + + snprintf(buf, sizeof(buf), \"%zd\", -sizeof(buf)); + if (strncmp(buf, \"-100\", sizeof(buf))) + return 2; + + snprintf(buf, sizeof(buf), \"%\" PRId64, -t); + if (strncmp(buf, \"-4294967296\", sizeof(buf))) + return 3; + + snprintf(buf, sizeof(buf), \"0o%\" PRIo64, t); + if (strncmp(buf, \"0o40000000000\", sizeof(buf))) + return 4; + + snprintf(buf, sizeof(buf), \"0x%\" PRIx64, t); + if (strncmp(buf, \"0x100000000\", sizeof(buf))) + return 5; + + snprintf(buf, sizeof(buf), \"%\" PRIu64, t); + if (strncmp(buf, \"4294967296\", sizeof(buf))) + return 6; + + return 0; +} + +" + SUITABLE_SNPRINTF +) +if(NOT SUITABLE_SNPRINTF) + message(FATAL_ERROR +"The snprintf(3) implementation in this libc is not suitable, +tcpdump would not work correctly even if it managed to compile." + ) +endif() + check_function_exists(getopt_long HAVE_GETOPT_LONG) -check_function_exists(strftime HAVE_STRFTIME) check_function_exists(setlinebuf HAVE_SETLINEBUF) # # For Windows, don't need to waste time checking for fork() or vfork(). @@ -533,22 +633,10 @@ cmake_pop_check_state() # # -# Check for IPv6 support. -# We just check for AF_INET6 and struct in6_addr. +# FIXME: This check does not influence the build logic, but without it CMake +# 3.18.4 fails trying to make the next check_type_size() check later on. # -cmake_push_check_state() -if(WIN32) - set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h ws2tcpip.h) - check_symbol_exists(AF_INET6 "sys/types.h;ws2tcpip.h" HAVE_AF_INET6) -else(WIN32) - set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/socket.h netinet/in.h) - check_symbol_exists(AF_INET6 "sys/types.h;sys/socket.h;netinet/in.h" HAVE_AF_INET6) -endif(WIN32) check_type_size("struct in6_addr" HAVE_STRUCT_IN6_ADDR) -cmake_pop_check_state() -if(HAVE_AF_INET6 AND HAVE_STRUCT_IN6_ADDR) - set(HAVE_OS_IPV6_SUPPORT TRUE) -endif(HAVE_AF_INET6 AND HAVE_STRUCT_IN6_ADDR) ###################################### # External dependencies @@ -1093,6 +1181,7 @@ set(NETDISSECT_SOURCE_LIST_C print-ospf.c print-ospf6.c print-otv.c + print-pflog.c print-pgm.c print-pim.c print-pktap.c @@ -1101,13 +1190,14 @@ set(NETDISSECT_SOURCE_LIST_C print-pppoe.c print-pptp.c print-ptp.c + print-quic.c print-radius.c print-raw.c + print-realtek.c print-resp.c print-rip.c print-ripng.c print-rpki-rtr.c - print-rrcp.c print-rsvp.c print-rt6.c print-rtsp.c @@ -1145,6 +1235,7 @@ set(NETDISSECT_SOURCE_LIST_C print-vxlan-gpe.c print-vxlan.c print-wb.c + print-whois.c print-zep.c print-zephyr.c print-zeromq.c @@ -1157,7 +1248,7 @@ set(NETDISSECT_SOURCE_LIST_C # # Replace missing functions # -foreach(FUNC strlcat strlcpy strdup strsep getservent getopt_long) +foreach(FUNC strlcat strlcpy strsep getservent getopt_long) string(TOUPPER ${FUNC} FUNC_UPPERCASE) set(HAVE_FUNC_UPPERCASE HAVE_${FUNC_UPPERCASE}) if(NOT ${HAVE_FUNC_UPPERCASE}) @@ -1195,6 +1286,55 @@ file(GLOB PROJECT_SOURCE_LIST_H *.h ) +# +# Assume, by default, no support for shared libraries and V7/BSD +# convention for man pages (devices in section 4, file formats in +# section 5, miscellaneous info in section 7, administrative commands +# and daemons in section 8). Individual cases can override this. +# Individual cases can override this. +# +set(MAN_FILE_FORMATS 5) +set(MAN_MISC_INFO 7) +if(CMAKE_SYSTEM_NAME STREQUAL "AIX") + # Workaround to enable certain features + set(_SUN TRUE) +elseif(CMAKE_SYSTEM_NAME STREQUAL "HP-UX") + # + # Use System V conventions for man pages. + # + set(MAN_FILE_FORMATS 4) + set(MAN_MISC_INFO 5) +elseif(CMAKE_SYSTEM_NAME STREQUAL "IRIX" OR CMAKE_SYSTEM_NAME STREQUAL "IRIX64") + # + # Use IRIX conventions for man pages; they're the same as the + # System V conventions, except that they use section 8 for + # administrative commands and daemons. + # + set(MAN_FILE_FORMATS 4) + set(MAN_MISC_INFO 5) +elseif(CMAKE_SYSTEM_NAME STREQUAL "OSF1") + # + # DEC OSF/1, a/k/a Digital UNIX, a/k/a Tru64 UNIX. + # Use Tru64 UNIX conventions for man pages; they're the same as the + # System V conventions except that they use section 8 for + # administrative commands and daemons. + # + set(MAN_FILE_FORMATS 4) + set(MAN_MISC_INFO 5) +elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*") + # + # SunOS 5.x. + # + if(CMAKE_SYSTEM_VERSION STREQUAL "5.12") + else() + # + # Use System V conventions for man pages. + # + set(MAN_FILE_FORMATS 4) + set(MAN_MISC_INFO 5) + endif() +endif() + source_group("Source Files" FILES ${PROJECT_SOURCE_LIST_C}) source_group("Header Files" FILES ${PROJECT_SOURCE_LIST_H})