]> The Tcpdump Group git mirrors - tcpdump/blobdiff - CMakeLists.txt
Detect OS IPv6 support using AF_INET6 only.
[tcpdump] / CMakeLists.txt
index 63a7e5eeee4e7511236ae660d45151a0b97b5e83..fa865703b6c49bb84fca4d9d67703814f40d482f 100644 (file)
@@ -2,6 +2,7 @@ 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)
     #
@@ -85,7 +86,13 @@ 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
@@ -111,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)
 
 #
@@ -278,23 +282,6 @@ if(MSVC)
     add_definitions(-D_CRT_SECURE_NO_WARNINGS)
 endif(MSVC)
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Haiku")
-    #
-    # On Haiku, all executables are built as shared objects,
-    # and must have their code build as PIC.
-    #
-    # At least some versions of Haiku's GCC default to PIC,
-    # with a -fno-pic option for cases where that's not desired.
-    #
-    # Clang hasn't been modified in that fashion, so Clang
-    # builds of tcpdump fail.
-    #
-    # Force the use of -fPIC (even for GCC; adding -fPIC for GCC
-    # won't break anything).
-    #
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
-endif(CMAKE_SYSTEM_NAME STREQUAL "Haiku")
-
 if(MSVC)
     if (USE_STATIC_RT)
         MESSAGE(STATUS "Use STATIC runtime")
@@ -352,7 +339,6 @@ endif(HAVE_RPC_RPC_H)
 #
 check_function_exists(strlcat HAVE_STRLCAT)
 check_function_exists(strlcpy HAVE_STRLCPY)
-check_function_exists(strdup HAVE_STRDUP)
 check_function_exists(strsep HAVE_STRSEP)
 
 #
@@ -418,20 +404,68 @@ 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 <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/types.h>
+
+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(setlinebuf HAVE_SETLINEBUF)
 #
@@ -599,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
@@ -1226,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})