packet-kerberos: add a hint to the used decryption key
[metze/wireshark/wip.git] / CMakeLists.txt
index 18145188a7a015043ab775669b6896a81fc4ce23..5e143c205e1d698cf983fdb87c53c8b8d358d901 100644 (file)
@@ -7,13 +7,22 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 #
 
+if(WIN32)
+       # Needed for GREATER_EQUAL operator
+       cmake_minimum_required(VERSION 3.7)
+else()
+       cmake_minimum_required(VERSION 3.5)
+endif()
+if(POLICY CMP0083)
+       cmake_policy(SET CMP0083 NEW)
+endif()
 project(Wireshark C CXX)
 
-# Updated by make-version.pl
+# Updated by tools/make-version.pl
 set(GIT_REVISION 0)
 set(PROJECT_MAJOR_VERSION 2)
 set(PROJECT_MINOR_VERSION 9)
-set(PROJECT_PATCH_VERSION 0)
+set(PROJECT_PATCH_VERSION 1)
 set(PROJECT_BUILD_VERSION ${GIT_REVISION})
 set(PROJECT_VERSION_EXTENSION "")
 set(PROJECT_RELEASE_VERSION "${PROJECT_MAJOR_VERSION}.${PROJECT_MINOR_VERSION}")
@@ -34,12 +43,6 @@ endif()
 set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
 
 message(STATUS "Generating build using CMake ${CMAKE_VERSION}")
-if(WIN32)
-       # Needed for GREATER_EQUAL operator
-       cmake_minimum_required(VERSION 3.7)
-else()
-       cmake_minimum_required(VERSION 3.5)
-endif()
 
 #Where to find local cmake scripts
 set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
@@ -110,9 +113,6 @@ if(WIN32)
 
        # XXX Add a dependency on ${_ws_lib_dir}/current_tag.txt?
 
-       # Head off any attempts to use Cygwin's Python.
-       include(LocatePythonExecutable)
-
        # Prepopulate some ConfigureChecks values. Compilation checks
        # on Windows can be slow.
        set(HAVE_FCNTL_H TRUE)
@@ -161,19 +161,57 @@ endif()
 # the Unix Makefile generator.
 #
 
-#Defines CMAKE_INSTALL_BINDIR, CMAKE_INSTALL_DATADIR, etc ...
+# Defines CMAKE_INSTALL_BINDIR, CMAKE_INSTALL_DATADIR, etc ...
+if(WIN32)
+       # Override some values on Windows, to match the existing
+       # convention of installing everything to a single root folder.
+       set(CMAKE_INSTALL_BINDIR ".")
+       set(CMAKE_INSTALL_LIBDIR ".")
+       set(CMAKE_INSTALL_INCLUDEDIR "include")
+       set(CMAKE_INSTALL_DATADIR ".")
+else()
+       # By default INSTALL_DATADIR is set to INSTALL_DATAROOTDIR, set the
+       # proper value here.
+       set(CMAKE_INSTALL_DATADIR "share/${CPACK_PACKAGE_NAME}"
+               CACHE PATH "Read-only architecture-independent data"
+       )
+endif()
 include(GNUInstallDirs)
+
 # Make sure our executables can can load our libraries if we install into
 # a non-default directory on Unix-like systems other than macOS.
-# https://cmake.org/Wiki/CMake_RPATH_handling
+# https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling
 if(NOT CMAKE_INSTALL_RPATH AND NOT (WIN32 OR APPLE))
-       LIST(FIND CMAKE_C_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_FULL_LIBDIR}" IS_SYSTEM_DIR)
-       if(IS_SYSTEM_DIR STREQUAL "-1")
-               SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}")
-               SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+       # Try to set a RPATH for installed binaries if the library directory is
+       # not already included in the default search list.
+       list(FIND CMAKE_C_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_FULL_LIBDIR}" IS_SYSTEM_DIR)
+       if(IS_SYSTEM_DIR EQUAL -1)
+               # Some systems support $ORIGIN in RPATH to enable relocatable
+               # binaries. In other cases, only absolute paths can be used.
+               # https://www.lekensteyn.nl/rpath.html
+               if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|SunOS|FreeBSD)$")
+                       set(ENABLE_RPATH_ORIGIN TRUE CACHE BOOL
+                               "Use $ORIGIN with INSTALL_RPATH")
+                       mark_as_advanced(ENABLE_RPATH_ORIGIN)
+               else()
+                       set(ENABLE_RPATH_ORIGIN FALSE)
+               endif()
+               if(ENABLE_RPATH_ORIGIN)
+                       set(CMAKE_INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
+               else()
+                       set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}")
+               endif()
+               # Include non-standard external libraries by default in RPATH.
+               if(NOT DEFINED CMAKE_INSTALL_RPATH_USE_LINK_PATH)
+                       set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+               endif()
        endif()
 endif()
 
+# Ensure that executables in the build directory always have the same RPATH.
+# This ensures relocatable binaries and reproducible builds (invariant of the
+# build directory location). (Requires CMake 3.14)
+set(CMAKE_BUILD_RPATH_USE_ORIGIN ON)
 
 if(WIN32)
     # Linking with wsetargv.obj enables "wildcard expansion" of
@@ -200,6 +238,7 @@ message(STATUS "V: ${PROJECT_VERSION}, MaV: ${PROJECT_MAJOR_VERSION}, MiV: ${PRO
 include(UseLemon)
 include(UseMakePluginReg)
 include(UseMakeTaps)
+include(UseExecutableResources)
 include(UseAsn2Wrs)
 
 # The following snippet has been taken from
@@ -257,24 +296,40 @@ if( NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" AND
        set( DUMPCAP_INSTALL_OPTION )
 endif()
 
-if(APPLE AND EXISTS /usr/local/opt/qt5)
-       # Homebrew installs Qt5 (up to at least 5.11.0) in
-       # /usr/local/qt5. Ensure that it can be found by CMake
-       # since it is not in the default /usr/local prefix.
-       # Add it to PATHS so that it doesn't override the
-       # CMAKE_PREFIX_PATH environment variable.
-       # QT_FIND_PACKAGE_OPTIONS should be passed to find_package,
-       # e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS})
-       set (QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5)
+set(OSS_FUZZ OFF CACHE BOOL "Whether building for oss-fuzz")
+mark_as_advanced(OSS_FUZZ)
+if(OSS_FUZZ)
+       if(ENABLE_FUZZER)
+               # In oss-fuzz mode, the fuzzing engine can be afl or libFuzzer.
+               message(FATAL_ERROR "Cannot force libFuzzer when using oss-fuzz")
+       endif()
+       # Must not depend on external dependencies so statically link all libs.
+       set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
+endif()
+
+#
+# Linking can consume a lot of memory, especially when built with ASAN and
+# static libraries (like oss-fuzz) or Debug mode. With Ninja, the number of
+# parallel linker processes is constrained by job parallelism (-j), but this can
+# be reduced further by setting "job pools" to a lower number.
+#
+if(CMAKE_MAKE_PROGRAM MATCHES "ninja" AND OSS_FUZZ)
+       # Assume oss-fuzz linker jobs do not require more than 1.2G per task
+       set(per_job_memory_mb 1200)
+       cmake_host_system_information(RESULT total_memory_mb QUERY TOTAL_PHYSICAL_MEMORY)
+       math(EXPR parallel_link_jobs "${total_memory_mb} / ${per_job_memory_mb}")
+       if(parallel_link_jobs LESS 1)
+               set(parallel_link_jobs 1)
+       endif()
+       set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${parallel_link_jobs})
+       set(CMAKE_JOB_POOL_LINK link_job_pool)
+       message(STATUS "Ninja job pool size: ${parallel_link_jobs}")
 endif()
 
 # Always enable position-independent code when compiling, even for
 # executables, so you can build position-independent executables.
-# -pie is added below for non-MSVC.
-# Needed when either:
-# - Qt5_POSITION_INDEPENDENT_CODE is set and CMake < 2.8.11
-# - PIE is wanted (-pie) and you want to add -fPIC/-fPIE automatically.
-# This option only has an effect on CMake >= 2.8.9
+# -pie is added below for non-MSVC, but requires objects to be built with
+# -fPIC/-fPIE (so set CMAKE_POSITION_INDEPENDENT_CODE to enable that).
 set(CMAKE_POSITION_INDEPENDENT_CODE ON)
 
 # Path to our generated executables (or wrapper scripts)
@@ -312,10 +367,6 @@ if( CMAKE_C_COMPILER_ID MATCHES "MSVC")
                add_definitions("/D_BIND_TO_CURRENT_CRT_VERSION=1")
        endif()
 
-       # FIXME: WINPCAP_VERSION cannot be determined from source or executable.
-       set(WINPCAP_VERSION "4_1_3")
-       add_definitions("/DWINPCAP_VERSION=${WINPCAP_VERSION}")
-
        set(LOCAL_CFLAGS
                /MP
        )
@@ -358,29 +409,17 @@ if( CMAKE_C_COMPILER_ID MATCHES "MSVC")
        set(CMAKE_CXX_FLAGS "${_flags} ${CMAKE_CXX_FLAGS}")
 
 else() # ! MSVC
-       if(CMAKE_OSX_DEPLOYMENT_TARGET)
-               if(APPLE)
-                       if(CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.0")
-                               message(FATAL_ERROR "We don't support building for Mac OS X 10.0")
-                       elseif(CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.1")
-                               message(FATAL_ERROR "We don't support building for Mac OS X 10.1")
-                       elseif(CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.2")
-                               message(FATAL_ERROR "We don't support building for Mac OS X 10.2")
-                       elseif(CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.4" OR CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.5")
-                               #
-                               # Only 32-bit builds are supported.  10.5
-                               # (and 10.4?) had a bug that causes some BPF
-                               # functions not to work with 64-bit userland
-                               # code, so capturing won't work.
-                               #
-                               set(CMAKE_C_FLAGS "-m32 ${CMAKE_C_FLAGS}")
-                               set(CMAKE_CXX_FLAGS "-m32 ${CMAKE_CXX_FLAGS}")
-                               set(WS_LINK_FLAGS "-m32 ${WS_LINK_FLAGS}")
+       if(APPLE)
+               set(MIN_MACOS_VERSION 10.6) # Arbitrary.
+               if(CMAKE_OSX_DEPLOYMENT_TARGET)
+                       if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS MIN_MACOS_VERSION)
+                               message(FATAL_ERROR "We don't support building for macOS < ${MIN_MACOS_VERSION}")
                        endif()
+                       set(MIN_MACOS_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET})
                        message(STATUS "Building for Mac OS X/OS X/macOS ${CMAKE_OSX_DEPLOYMENT_TARGET}")
-               else()
-                       message(FATAL_ERROR "CMAKE_OSX_DEPLOYMENT_TARGET only applies when building for macOS")
                endif()
+       elseif(CMAKE_OSX_DEPLOYMENT_TARGET)
+               message(FATAL_ERROR "CMAKE_OSX_DEPLOYMENT_TARGET only applies when building for macOS")
        endif()
 
        #
@@ -482,7 +521,6 @@ else() # ! MSVC
                # -O<X> and -g get set by the CMAKE_BUILD_TYPE
                -Wall
                -Wextra
-               -Wextra-semi
                -Wendif-labels
                -Wpointer-arith
                -Wformat-security
@@ -547,7 +585,25 @@ else() # ! MSVC
                -Werror=implicit
        )
 
+       #
+       # The universal zero initializer (in C: struct s x = { 0 };) for
+       # structures with multiple members is perfectly legal, but some older
+       # compilers warn about it. Silence those older compilers.
+       #
+       if((CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "5.1") OR
+          (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "6.0") OR
+          (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "10.0"))
+               if(NOT CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_VERSION VERSION_LESS "4.7")
+                       list(APPEND WIRESHARK_C_ONLY_FLAGS -Wno-missing-field-initializers)
+               endif()
+               # Silence warnings for initialization of nested structs like
+               # struct { struct { int a, b; } s; int c; } v = { 0 };
+               list(APPEND WIRESHARK_C_ONLY_FLAGS -Wno-missing-braces)
+       endif()
+
+
        list(APPEND WIRESHARK_CXX_ONLY_FLAGS
+               -Wextra-semi
        )
 
        #
@@ -644,8 +700,6 @@ else() # ! MSVC
                # -flto
                # -fwhopr
                # -fwhole-program
-               # XXX: This is applicable only when linking executables.
-               -pie
        )
 endif() # ! MSVC
 
@@ -734,6 +788,21 @@ if(ENABLE_UBSAN)
        set(CMAKE_CXX_FLAGS "-fsanitize=undefined ${CMAKE_CXX_FLAGS}")
 endif()
 
+if(ENABLE_FUZZER)
+       # Available since Clang >= 6
+       # Will enable coverage flags which can be used by the fuzzshark target.
+       cmake_push_check_state()
+       set(CMAKE_REQUIRED_LIBRARIES "-fsanitize=fuzzer-no-link")
+       check_c_compiler_flag(-fsanitize=fuzzer C__fsanitize_fuzzer_no_link_VALID)
+       check_cxx_compiler_flag(-fsanitize=fuzzer CXX__fsanitize_fuzzer_no_link_VALID)
+       cmake_pop_check_state()
+       if(NOT C__fsanitize_fuzzer_no_link_VALID OR NOT CXX__fsanitize_fuzzer_no_link_VALID)
+               message(FATAL_ERROR "ENABLE_FUZZER was requested, but not supported!")
+       endif()
+       set(CMAKE_C_FLAGS "-fsanitize=fuzzer-no-link ${CMAKE_C_FLAGS}")
+       set(CMAKE_CXX_FLAGS "-fsanitize=fuzzer-no-link ${CMAKE_CXX_FLAGS}")
+endif()
+
 set(WERROR_COMMON_FLAGS "")
 if(NOT DISABLE_WERROR AND NOT ENABLE_EXTRA_COMPILER_WARNINGS)
        if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
@@ -797,6 +866,27 @@ endif()
 
 include(CheckCLinkerFlag)
 
+if(NOT CMAKE_C_COMPILER_ID MATCHES "MSVC" AND NOT OSS_FUZZ)
+       #
+       # The -pie linker option produces a position-independent executable.
+       # Some Linux distributions have this enabled by default in the compiler,
+       # so setting it here will be superfluous though.
+       #
+       # Note that linking with static libraries that are not position
+       # independent may fail, the user can set CMAKE_EXE_LINKER_FLAGS=-no-pie
+       # as a workaround.
+       #
+       if(CMAKE_VERSION VERSION_GREATER "3.13.999")
+               include(CheckPIESupported)
+               check_pie_supported()
+       else()
+               check_c_linker_flag(-pie LINK_pie_VALID)
+               if(LINK_pie_VALID)
+                       set(CMAKE_EXE_LINKER_FLAGS "-pie ${CMAKE_EXE_LINKER_FLAGS}")
+               endif()
+       endif()
+endif()
+
 foreach(THIS_FLAG ${WIRESHARK_LD_FLAGS})
        string(MAKE_C_IDENTIFIER "LINK${THIS_FLAG}_VALID" _flag_var)
        check_c_linker_flag(${THIS_FLAG} ${_flag_var})
@@ -813,58 +903,79 @@ if(APPLE AND EXISTS /usr/local/opt/gettext)
        link_directories(/usr/local/opt/gettext/lib)
 endif()
 
-# The packagelist is doing some magic: If we add XXX to the packagelist, we
-# - may optionally set XXX_OPTIONS to pass to the find_package command
-# - will call FindXXX.cmake or find_package
-# - return found libraries in XXX_LIBRARIES
-# - return found include in XXX_INCLUDE_DIRS
-# - set HAVE_XXX
+# ws_find_package(<PackageName>
+#             <CMakeOptions.txt boolean variable>
+#             <cmakeconfig.h.in macro definition>
+#             [remaining find_package() arguments])
+macro(ws_find_package _package_name _enable_package _package_cmakedefine)
+       if(${_enable_package})
+               find_package(${_package_name} ${ARGN})
+               if(${_package_name}_FOUND)
+                       set(${_package_cmakedefine} 1)
+               endif()
+       endif()
+endmacro()
 
 # The minimum package list
-set(PACKAGELIST Git GLIB2 GMODULE2 GTHREAD2 GCRYPT LEX YACC Perl PythonInterp)
-set(LEX_OPTIONS REQUIRED)
-set(GLIB2_OPTIONS REQUIRED)
-set(GLIB2_FIND_OPTIONS REQUIRED)
+find_package(Git)
 set(GLIB2_MIN_VERSION 2.32.0)
-set(GTHREAD2_OPTIONS REQUIRED)
-set(GCRYPT_OPTIONS "1.4.2" REQUIRED)
-set(Perl_OPTIONS REQUIRED)
-set(PythonInterp_FIND_VERSION 2)
-set(Python_ADDITIONAL_VERSIONS 3)
-set(YACC_OPTIONS REQUIRED)
-
-if (NOT WIN32)
-       set(PACKAGELIST ${PACKAGELIST} Gettext M)
-       set(M_OPTIONS REQUIRED)
+find_package(GLIB2 REQUIRED)
+include_directories(SYSTEM ${GLIB2_INCLUDE_DIRS})
+find_package(GMODULE2)
+find_package(GTHREAD2 REQUIRED)
+find_package(GCRYPT "1.4.2" REQUIRED)
+find_package(LEX REQUIRED)
+find_package(YACC REQUIRED)
+find_package(Perl REQUIRED)
+
+if(CMAKE_VERSION VERSION_LESS "3.12")
+       # Locate the Python interpreter. Finds the wrong (Python 2) version if:
+       # - PATH contains python3.6, but not python3 (3.4). Affects RHEL7+EPEL.
+       # - Path contains C:\Python27 but not C:\Python37 (which is installed,
+       #   but not present in PATH).
+       find_package(PythonInterp 3.4 REQUIRED)
+else()
+       find_package(Python3 3.4 REQUIRED)
+       # Several files (including LocatePythonModule) still use the old name
+       # from FindPythonInterp, let's stick to it for now.
+       set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
 endif()
 
-set(PACKAGELIST ${PACKAGELIST} LIBSSH)
-set(LIBSSH_OPTIONS "0.6")
-
-set(PACKAGELIST ${PACKAGELIST} JSONGLIB)
-
-if(ENABLE_PCAP)
-       set(PACKAGELIST ${PACKAGELIST} PCAP)
+if (NOT WIN32)
+       find_package(Gettext)
+       find_package(M REQUIRED)
 endif()
 
-if(ENABLE_AIRPCAP)
-       set(PACKAGELIST ${PACKAGELIST} AIRPCAP)
+if(BUILD_sshdump OR BUILD_ciscodump)
+       set(ENABLE_LIBSSH ON)
+else()
+       set(ENABLE_LIBSSH OFF)
 endif()
+ws_find_package(LIBSSH ENABLE_LIBSSH HAVE_LIBSSH "0.6")
 
-if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
-       set(PACKAGELIST ${PACKAGELIST} Systemd)
-endif()
+ws_find_package(PCAP ENABLE_PCAP HAVE_LIBPCAP)
+ws_find_package(AIRPCAP ENABLE_AIRPCAP HAVE_AIRPCAP)
+ws_find_package(Systemd BUILD_sdjournal HAVE_SYSTEMD)
 
 # Build the Qt GUI?
 if(BUILD_wireshark)
        # Untested, may not work if CMAKE_PREFIX_PATH gets overwritten
        # somewhere. The if WIN32 in this place is annoying as well.
-       if( WIN32 )
-               set( QT5_BASE_PATH "$ENV{QT5_BASE_DIR}" )
-               set( CMAKE_PREFIX_PATH "${QT5_BASE_PATH}" )
-       endif()
-       list (INSERT QT_FIND_PACKAGE_OPTIONS 0 REQUIRED)
-       set(PACKAGELIST ${PACKAGELIST}
+       if(WIN32)
+               set(QT5_BASE_PATH "$ENV{QT5_BASE_DIR}")
+               set(CMAKE_PREFIX_PATH "${QT5_BASE_PATH}")
+       endif()
+       if(APPLE AND EXISTS /usr/local/opt/qt5)
+               # Homebrew installs Qt5 (up to at least 5.11.0) in
+               # /usr/local/qt5. Ensure that it can be found by CMake
+               # since it is not in the default /usr/local prefix.
+               # Add it to PATHS so that it doesn't override the
+               # CMAKE_PREFIX_PATH environment variable.
+               # QT_FIND_PACKAGE_OPTIONS should be passed to find_package,
+               # e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS})
+               list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5)
+       endif()
+       set(QT_PACKAGELIST
                Qt5Core
                Qt5LinguistTools
                Qt5Multimedia
@@ -872,59 +983,56 @@ if(BUILD_wireshark)
                Qt5Svg
                Qt5Widgets
        )
-       set(Qt5Core_OPTIONS ${QT_FIND_PACKAGE_OPTIONS})
-       set(Qt5LinguistTools_OPTIONS ${QT_FIND_PACKAGE_OPTIONS})
-       set(Qt5Multimedia_OPTIONS ${QT_FIND_PACKAGE_OPTIONS})
-       set(Qt5PrintSupport_OPTIONS ${QT_FIND_PACKAGE_OPTIONS})
-       set(Qt5Svg_OPTIONS ${QT_FIND_PACKAGE_OPTIONS})
-       set(Qt5Widgets_OPTIONS ${QT_FIND_PACKAGE_OPTIONS})
-       if (APPLE)
-               set(PACKAGELIST ${PACKAGELIST} Qt5MacExtras)
-               set(Qt5MacExtras_OPTIONS ${QT_FIND_PACKAGE_OPTIONS})
+       if(APPLE)
+               list(APPEND QT_PACKAGELIST Qt5MacExtras)
+       endif()
+       if(WIN32)
+               list(APPEND QT_PACKAGELIST Qt5WinExtras)
        endif()
-       if( WIN32 )
-               set(PACKAGELIST ${PACKAGELIST} Qt5WinExtras)
-               set(Qt5WinExtras_OPTIONS ${QT_FIND_PACKAGE_OPTIONS})
+       foreach(_qt_package IN LISTS QT_PACKAGELIST)
+               find_package(${_qt_package} REQUIRED ${QT_FIND_PACKAGE_OPTIONS})
+               list(APPEND QT_LIBRARIES ${${_qt_package}_LIBRARIES})
+               list(APPEND QT_INCLUDE_DIRS ${${_qt_package}_INCLUDE_DIRS})
+               list(APPEND QT_COMPILE_DEFINITIONS ${${_qt_package}_COMPILE_DEFINITIONS})
+       endforeach()
+       set(QT_FOUND ON)
+       if(Qt5MacExtras_FOUND)
+               set(QT_MACEXTRAS_LIB 1)
        endif()
 endif()
 
 # MaxMind DB address resolution
-if(BUILD_mmdbresolve)
-       set(PACKAGELIST ${PACKAGELIST} MaxMindDB)
-endif()
+ws_find_package(MaxMindDB BUILD_mmdbresolve HAVE_MAXMINDDB)
 
 # SMI SNMP
-if(ENABLE_SMI)
-       set(PACKAGELIST ${PACKAGELIST} SMI)
-endif()
+ws_find_package(SMI ENABLE_SMI HAVE_LIBSMI)
 
-# GNU SSL/TLS support
-if(ENABLE_GNUTLS)
-       set(PACKAGELIST ${PACKAGELIST} GNUTLS)
-       # Minimum version needed.
-       set(GNUTLS_OPTIONS "2.12.0")
-endif()
+# Support for TLS decryption using RSA private keys.
+ws_find_package(GNUTLS ENABLE_GNUTLS HAVE_LIBGNUTLS "3.2.0")
 
 # Kerberos
-if(ENABLE_KERBEROS)
-       set(PACKAGELIST ${PACKAGELIST} KERBEROS)
-endif()
+ws_find_package(KERBEROS ENABLE_KERBEROS HAVE_KERBEROS)
 
 # C Asynchronous resolver
-if(ENABLE_CARES)
-       set(PACKAGELIST ${PACKAGELIST} CARES)
-       # Minimum version needed.
-       set(CARES_OPTIONS "1.5.0")
+ws_find_package(CARES ENABLE_CARES HAVE_C_ARES "1.5.0")
+if(NOT CARES_FOUND)
+       message(WARNING "Not using c-ares.")
+       message(WARNING "DNS name resolution for captures will be disabled.")
 endif()
 
 # Zlib compression
 if(ENABLE_ZLIB)
        if (WIN32)
                # On Windows we build our own version of zlib, so add the paths
-               set(ZLIB_SRC_DIR "${_PROJECT_LIB_DIR}/zlib-1.2.11-ws")
-               set(SKIP_INSTALL_ALL True) # We copy the DLL ourselves.
+               set(ZLIB_SRC_DIR "${_PROJECT_LIB_DIR}/zlib-1.2.11-2-ws")
+               set(SKIP_INSTALL_STATIC True)
+               set(SKIP_INSTALL_HEADERS True)
+               set(SKIP_INSTALL_FILES True)
+               set(ZLIB_EXPORTS "WiresharkTargets")
                add_subdirectory("${ZLIB_SRC_DIR}" "${CMAKE_BINARY_DIR}/zlib")
-               unset(SKIP_INSTALL_ALL)
+               unset(SKIP_INSTALL_STATIC)
+               unset(SKIP_INSTALL_HEADERS)
+               unset(SKIP_INSTALL_FILES)
                set(ZLIB_INCLUDE_DIR  "${ZLIB_SRC_DIR}" "${CMAKE_BINARY_DIR}/zlib")
                set(ZLIB_LIBRARY zlib)
                set(ZLIB_DLL "zlib1.dll")
@@ -936,201 +1044,74 @@ if(ENABLE_ZLIB)
                        EXCLUDE_FROM_DEFAULT_BUILD True
                )
        endif()
-       set(PACKAGELIST ${PACKAGELIST} ZLIB)
+       ws_find_package(ZLIB ENABLE_ZLIB HAVE_ZLIB)
 endif()
 
 # LZ4 compression
-if(ENABLE_LZ4)
-       set(PACKAGELIST ${PACKAGELIST} LZ4)
-endif()
+ws_find_package(LZ4 ENABLE_LZ4 HAVE_LZ4)
 
 # Snappy compression
-if(ENABLE_SNAPPY)
-       set(PACKAGELIST ${PACKAGELIST} SNAPPY)
-endif()
+ws_find_package(SNAPPY ENABLE_SNAPPY HAVE_SNAPPY)
 
 # Enhanced HTTP/2 dissection
-if(ENABLE_NGHTTP2)
-       set(PACKAGELIST ${PACKAGELIST} NGHTTP2)
-endif()
+ws_find_package(NGHTTP2 ENABLE_NGHTTP2 HAVE_NGHTTP2)
 
 # Embedded Lua interpreter
-if(ENABLE_LUA)
-       set(PACKAGELIST ${PACKAGELIST} LUA)
-       set(LUA_OPTIONS "5.1")
-endif()
+ws_find_package(LUA ENABLE_LUA HAVE_LUA "5.1")
 
-if(ENABLE_NETLINK)
-       set(PACKAGELIST ${PACKAGELIST} NL)
-endif()
+ws_find_package(NL ENABLE_NETLINK HAVE_LIBNL)
 
-if(ENABLE_SBC)
-       set(PACKAGELIST ${PACKAGELIST} SBC)
-endif()
+ws_find_package(SBC ENABLE_SBC HAVE_SBC)
 
-if(ENABLE_SPANDSP)
-       set(PACKAGELIST ${PACKAGELIST} SPANDSP)
-endif()
+ws_find_package(SPANDSP ENABLE_SPANDSP HAVE_SPANDSP)
 
-if(ENABLE_BCG729)
-       set(PACKAGELIST ${PACKAGELIST} BCG729)
-endif()
+ws_find_package(BCG729 ENABLE_BCG729 HAVE_BCG729)
 
-if(ENABLE_LIBXML2)
-       set(PACKAGELIST ${PACKAGELIST} LibXml2)
+ws_find_package(LibXml2 ENABLE_LIBXML2 HAVE_LIBXML2)
+if(NOT LIBXML2_FOUND)
+       # The (official) FindLibXml2.cmake file sets this cache variable to a
+       # non-empty value, be sure to clear it when not found.
+       set(LIBXML2_LIBRARIES "")
 endif()
 
 # Capabilities
-if(ENABLE_CAP)
-       set(PACKAGELIST ${PACKAGELIST} CAP SETCAP)
+ws_find_package(CAP ENABLE_CAP HAVE_LIBCAP)
+if(NOT WIN32)
+       find_package(SETCAP)
 endif()
 
 # Windows version updates
-if(ENABLE_WINSPARKLE)
-       set(PACKAGELIST ${PACKAGELIST} WINSPARKLE)
-endif()
-
-set(PACKAGELIST ${PACKAGELIST} POD)
+ws_find_package(WINSPARKLE ENABLE_WINSPARKLE HAVE_SOFTWARE_UPDATE)
 
-set(PACKAGELIST ${PACKAGELIST} DOXYGEN)
-
-set(PROGLIST)
-
-# Sort the package list
-list(SORT PACKAGELIST)
-string(REPLACE ";" " " _package_list "${PACKAGELIST}")
-message(STATUS "Package List: ${_package_list}")
-# Let's loop the package list
-foreach(PACKAGE ${PACKAGELIST})
-       # Most packages export uppercase variables, but there are exceptions.
-       if(PACKAGE MATCHES "^(Qt5)")
-               set(PACKAGE_VAR "${PACKAGE}")
-       else()
-               string(TOUPPER "${PACKAGE}" PACKAGE_VAR)
-       endif()
-       if(${PACKAGE}_OPTIONS)
-               find_package(${PACKAGE} ${${PACKAGE}_OPTIONS})
-       else()
-               find_package(${PACKAGE})
-       endif()
-       if (${PACKAGE_VAR}_FOUND)
-               message(STATUS "${PACKAGE_VAR} FOUND")
-               set(HAVE_LIB${PACKAGE_VAR} 1)
-               if (NOT DEFINED ${PACKAGE_VAR}_INCLUDE_DIRS AND ${PACKAGE_VAR}_INCLUDE_DIR)
-                       set(${PACKAGE_VAR}_INCLUDE_DIRS ${${PACKAGE_VAR}_INCLUDE_DIR})
-               endif()
-               if (${PACKAGE_VAR}_INCLUDE_DIRS)
-                       include_directories(SYSTEM ${${PACKAGE_VAR}_INCLUDE_DIRS})
-                       message(STATUS "${PACKAGE} includes: ${${PACKAGE_VAR}_INCLUDE_DIRS}")
-               endif()
-               if (${PACKAGE_VAR}_LIBRARIES)
-                       message(STATUS "${PACKAGE} libs: ${${PACKAGE_VAR}_LIBRARIES}")
-               endif()
-               if (${PACKAGE_VAR}_DEFINITIONS)
-                       message(STATUS "${PACKAGE} definitions: ${${PACKAGE_VAR}_DEFINITIONS}")
-                       string(REPLACE ";" " " _definitions "${${PACKAGE_VAR}_DEFINITIONS}")
-                       set(CMAKE_C_FLAGS "${_definitions} ${CMAKE_C_FLAGS}")
-                       set(CMAKE_CXX_FLAGS "${_definitions} ${CMAKE_CXX_FLAGS}")
-               endif()
-               if (${PACKAGE_VAR}_LINK_FLAGS)
-                       string(REPLACE ";" " " _link_flags "${${PACKAGE_VAR}_LINK_FLAGS}")
-                       set(WS_LINK_FLAGS "${_link_flags} ${WS_LINK_FLAGS}")
-                       message(STATUS "${PACKAGE} other link flags: ${_link_flags}")
-               endif()
-               if (${PACKAGE_VAR}_EXECUTABLE)
-                       message(STATUS "${PACKAGE} executable: ${${PACKAGE_VAR}_EXECUTABLE}")
-               endif()
-       else()
-               #
-               # Not finding a package is only a fatal error if the
-               # package is required; if it's required, then its
-               # XXX_OPTIONS variable contains REQUIRED, and the above
-               # code will pass REQUIRED to find_package, and the
-               # configure will fail if the package isn't found.
-               #
-               # Do *NOT* report this as an error!
-               #
-               message(STATUS "${PACKAGE_VAR} NOT FOUND")
-       endif()
-endforeach()
+find_package(POD)
 
-# Provide Windows system lib names
-include( UseWinLibs )
+find_package(DOXYGEN)
 
 # dist target that prepares source dir
 # XXX Duplicated in the RPM section below.
 add_custom_target(dist
-       COMMAND ./tools/git-export-release.sh -d "${CMAKE_BINARY_DIR}"
+       COMMAND ${CMAKE_BINARY_DIR}/packaging/source/git-export-release.sh -d "${CMAKE_BINARY_DIR}"
        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 )
 
-
-if(HAVE_LIBAIRPCAP)
-       set(HAVE_AIRPCAP 1)
-endif()
-if(HAVE_LIBLUA)
-       set(HAVE_LUA_H 1)
-       set(HAVE_LUA 1)
-endif()
-if(HAVE_LIBKERBEROS)
-       set(HAVE_KERBEROS 1)
-endif()
-if(MAXMINDDB_FOUND)
-       set(HAVE_MAXMINDDB 1)
-endif()
-if(LIBSSH_FOUND)
-       set(HAVE_LIBSSH 1)
-endif()
-if(JSONGLIB_FOUND)
-       set(HAVE_JSONGLIB 1)
-endif()
-if(NGHTTP2_FOUND)
-       set(HAVE_NGHTTP2 1)
-endif()
-if(HAVE_LIBCARES)
-       set(HAVE_C_ARES 1)
-endif()
-if(NOT HAVE_LIBCARES)
-       message(WARNING "Not using c-ares.")
-       message(WARNING "DNS name resolution for captures will be disabled.")
-endif()
-if(HAVE_LIBNL AND HAVE_AIRPCAP)
-       message(ERROR "Airpcap and Libnl support are mutually exclusive")
-endif()
-if(HAVE_LIBSBC)
-       set(HAVE_SBC 1)
-endif()
-if(SPANDSP_FOUND)
-       set(HAVE_SPANDSP 1)
-endif()
-if(BCG729_FOUND)
-       set(HAVE_BCG729 1)
-endif()
-if(LIBXML2_FOUND)
-       set(HAVE_LIBXML2 1)
-else()
-       # The (official) FindLibXml2.cmake file sets this cache variable to a
-       # non-empty value, be sure to clear it when not found.
-       set(LIBXML2_LIBRARIES "")
-endif()
-
-if (HAVE_LIBWINSPARKLE)
-       set(HAVE_SOFTWARE_UPDATE 1)
+if(GNUTLS_FOUND AND NOT GNUTLS_VERSION VERSION_LESS "3.4.0")
+       # While all Linux and Windows builds have PKCS #11 support enabled,
+       # macos-setup.sh explicitly disables it using --without-p11-kit.
+       #
+       # Require at least GnuTLS 3.4.0 such that public keys can be calculated
+       # from PKCS #11 private keys.
+       include(CheckSymbolExists)
+       cmake_push_check_state()
+       if(WIN32)
+               set(CMAKE_REQUIRED_DEFINITIONS -Dssize_t=int)
+       endif()
+       set(CMAKE_REQUIRED_INCLUDES ${GNUTLS_INCLUDE_DIRS})
+       set(CMAKE_REQUIRED_LIBRARIES ${GNUTLS_LIBRARIES})
+       check_symbol_exists(gnutls_pkcs11_obj_list_import_url4 gnutls/pkcs11.h HAVE_GNUTLS_PKCS11)
+       cmake_pop_check_state()
 endif()
 
-if(HAVE_LIBZLIB)
-       set(HAVE_ZLIB 1)
-       # Always include the "true" zlib includes first. This works around a
-       # bug in the Windows setup of GTK[23] which has a faulty zconf.h.
-       include_directories(BEFORE ${ZLIB_INCLUDE_DIRS})
-endif()
-if(HAVE_LIBLZ4)
-       set(HAVE_LZ4 1)
-endif()
-if(SNAPPY_FOUND)
-       set(HAVE_SNAPPY 1)
-endif()
-if (Qt5Widgets_FOUND)
+if (QT_FOUND)
        if (Qt5Widgets_VERSION VERSION_LESS 5.2)
                message(FATAL_ERROR "Qt 5.2 or later is required.")
        endif()
@@ -1140,27 +1121,6 @@ if (Qt5Widgets_FOUND)
                set(CMAKE_CXX_STANDARD 11)
                set(CMAKE_CXX_STANDARD_REQUIRED ON)
        endif()
-       set (QT_FOUND ON)
-       set (QT_LIBRARIES ${Qt5Widgets_LIBRARIES} ${Qt5PrintSupport_LIBRARIES})
-       if(Qt5Multimedia_FOUND)
-               set (QT_LIBRARIES ${QT_LIBRARIES} ${Qt5Multimedia_LIBRARIES})
-               # That's the name autotools used
-               set(QT_MULTIMEDIA_LIB 1)
-       endif()
-       if(Qt5Svg_FOUND)
-               set (QT_LIBRARIES ${QT_LIBRARIES} ${Qt5Svg_LIBRARIES})
-               # That's the name autotools used
-               set(QT_SVG_LIB 1)
-       endif()
-       if(Qt5MacExtras_FOUND)
-               set (QT_LIBRARIES ${QT_LIBRARIES} ${Qt5MacExtras_LIBRARIES})
-               # That's the name autotools used
-               set(QT_MACEXTRAS_LIB 1)
-       endif()
-       if(Qt5WinExtras_FOUND)
-               set (QT_LIBRARIES ${QT_LIBRARIES} ${Qt5WinExtras_LIBRARIES})
-               # set(QT_WINEXTRAS_LIB 1) # Not needed?
-       endif()
        if(NOT DEFINED MOC_OPTIONS)
                # Squelch moc verbose "nothing to do" output
                set(MOC_OPTIONS -nn)
@@ -1187,6 +1147,22 @@ if (Qt5Widgets_FOUND)
                        HINTS "${QT_BIN_PATH}"
                        DOC "Path to the macdeployqt utility."
                )
+               # https://doc.qt.io/qt-5.11/supported-platforms-and-configurations.html
+               # CMake < 3.7 doesn't support VERSION_GREATER_EQUAL.
+               if(Qt5Widgets_VERSION VERSION_GREATER "5.11.999")
+                       set(MIN_MACOS_VERSION 10.12)
+               elseif(Qt5Widgets_VERSION VERSION_GREATER "5.9.999")
+                       set(MIN_MACOS_VERSION 10.11)
+               elseif(Qt5Widgets_VERSION VERSION_GREATER "5.8.999")
+                       set(MIN_MACOS_VERSION 10.10)
+               elseif(Qt5Widgets_VERSION VERSION_GREATER "5.7.999")
+                       set(MIN_MACOS_VERSION 10.9)
+               elseif(Qt5Widgets_VERSION VERSION_GREATER "5.4.999")
+                       set(MIN_MACOS_VERSION 10.8)
+               endif()
+               if(CMAKE_OSX_DEPLOYMENT_TARGET AND CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS MIN_MACOS_VERSION)
+                       message(FATAL_ERROR "Qt version ${Qt5Widgets_VERSION} requires CMAKE_OSX_DEPLOYMENT_TARGET (${CMAKE_OSX_DEPLOYMENT_TARGET}) >= ${MIN_MACOS_VERSION}")
+               endif()
        endif()
 
 endif()
@@ -1195,6 +1171,16 @@ if(ENABLE_CHECKHF_CONFLICT)
        set(ENABLE_CHECK_FILTER 1)
 endif()
 
+#
+# Platform-specific additional libraries.
+#
+if(WIN32)
+       set(WIN_PSAPI_LIBRARY    psapi.lib)
+       set(WIN_WSOCK32_LIBRARY  wsock32.lib)
+       set(WIN_COMCTL32_LIBRARY comctl32.lib )
+       set(WIN_VERSION_LIBRARY  version.lib)
+endif()
+
 if(APPLE)
        #
        # We assume that APPLE means macOS so that we have the macOS
@@ -1237,6 +1223,8 @@ include( UseCheckAPI )
 # $DESTDIR/lib/wireshark/extcap
 # Windows: $DESTDIR/extcap
 # macOS app bundle: Wireshark.app/Contents/Resources/share/wireshark/extcap
+# If you change the nesting level be sure to check also the INSTALL_RPATH
+# target property.
 if (WIN32)
        set(EXTCAP_INSTALL_LIBDIR "extcap" CACHE INTERNAL "The extcap dir")
 else ()
@@ -1369,7 +1357,7 @@ set( VERSION ${PROJECT_VERSION} )
 add_custom_target(version
        BYPRODUCTS version.h
        COMMAND ${PERL_EXECUTABLE}
-               ${CMAKE_SOURCE_DIR}/make-version.pl
+               ${CMAKE_SOURCE_DIR}/tools/make-version.pl
                ${CMAKE_SOURCE_DIR}
 )
 set_target_properties(version PROPERTIES FOLDER "Auxiliary")
@@ -1391,36 +1379,25 @@ string (REPLACE ";" " " DOXYGEN_TOP_LEVEL_SOURCES "${TOP_LEVEL_SOURCE_LIST}")
 set(DOXYGEN_INPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
 set(DOXYGEN_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
 
-set(ICON_PATH "${CMAKE_SOURCE_DIR}/image/")
-set( IN_FILES
-       doxygen.cfg.in
-       image/libwireshark.rc.in
-       image/text2pcap.rc.in
-       image/capinfos.rc.in
-       image/wireshark.rc.in
-       image/mergecap.rc.in
-       image/tshark.rc.in
-       image/dumpcap.rc.in
-       image/reordercap.rc.in
-       image/rawshark.rc.in
-       image/file_dlg_win32.rc
-       image/tfshark.rc.in
-       image/editcap.rc.in
-       image/captype.rc.in
-       image/libwscodecs.rc.in
-       image/libwsutil.rc.in
-       image/wiretap.rc.in
-       image/wireshark.exe.manifest.in
-       packaging/macosx/Info.plist.in
-       packaging/macosx/osx-app.sh.in
-       packaging/macosx/osx-dmg.sh.in
-       packaging/macosx/Wireshark_package.pmdoc/index.xml.in
-       wireshark.pc.in
+set(CFG_OUT_FILES
+       doxygen.cfg
+       image/libwireshark.rc
+       image/wireshark.rc
+       image/dumpcap.rc
+       image/libwscodecs.rc
+       image/libwsutil.rc
+       image/wiretap.rc
+       image/wireshark.exe.manifest
+       packaging/macosx/Info.plist
+       packaging/macosx/osx-app.sh
+       packaging/macosx/osx-dmg.sh
+       packaging/macosx/Read_me_first.rtf
+       packaging/macosx/Wireshark_package.pmdoc/index.xml
+       packaging/source/git-export-release.sh
+       wireshark.pc
 )
-foreach( _in_file ${IN_FILES} )
-       get_filename_component( _path ${_in_file} PATH )
-       string( REGEX REPLACE "(.*)\\.in" "\\1" _outfile ${_in_file}  )
-       configure_file( ${CMAKE_SOURCE_DIR}/${_in_file} ${CMAKE_BINARY_DIR}/${_outfile} @ONLY )
+foreach( _cfg_file ${CFG_OUT_FILES} )
+       configure_file( ${CMAKE_SOURCE_DIR}/${_cfg_file}.in ${CMAKE_BINARY_DIR}/${_cfg_file} @ONLY )
 endforeach()
 
 include(FeatureSummary)
@@ -1471,19 +1448,6 @@ message(STATUS "Warnings as errors: ${WERROR_COMMON_FLAGS}")
 
 feature_summary(WHAT ALL)
 
-link_directories(
-       ${CMAKE_BINARY_DIR}/ui
-       ${CMAKE_BINARY_DIR}/ui/qt
-       ${CMAKE_BINARY_DIR}/capchild
-       ${CMAKE_BINARY_DIR}/caputils
-       ${CMAKE_BINARY_DIR}/codecs
-       ${CMAKE_BINARY_DIR}/epan
-       ${CMAKE_BINARY_DIR}/randpkt_core
-       ${CMAKE_BINARY_DIR}/wiretap
-       ${CMAKE_BINARY_DIR}/writecap
-       ${CMAKE_BINARY_DIR}/wsutil
-)
-
 if(WIN32)
        set(PLATFORM_UI_SRC
                ui/win32/console_win32.c
@@ -1498,17 +1462,6 @@ elseif(APPLE)
        )
 endif()
 
-# sources common for wireshark, tshark, rawshark and sharkd
-set(SHARK_COMMON_SRC
-       cfile.c
-       file_packet_provider.c
-       frame_tvbuff.c
-       sync_pipe_write.c
-       version_info.c
-       extcap.c
-       extcap_parser.c
-)
-
 set(TSHARK_TAP_SRC
        ${CMAKE_SOURCE_DIR}/ui/cli/tap-camelsrt.c
        ${CMAKE_SOURCE_DIR}/ui/cli/tap-diameter-avp.c
@@ -1546,13 +1499,21 @@ set(TSHARK_TAP_SRC
 set(INSTALL_DIRS
        diameter
        dtds
-       ${DATAFILE_DIR}/help
        profiles
        radius
        tpncp
        wimaxasncp
 )
 
+# FIXME: The help files are textfified on Windows into the staging dir.
+# The DATAFILE_DIR depends on CMAKE_CFG_INTDIR therefore it cannot be
+# added to an install() command with build systems supporting multiple
+# configurations in the build tree (e.g.: Visual Studio).
+if(NOT WIN32)
+       list(APPEND INSTALL_DIRS help)
+endif()
+
+
 set(INSTALL_FILES
        cfilters
        colorfilters
@@ -1611,23 +1572,11 @@ else()
        set(INSTALL_FILES COPYING ${INSTALL_FILES})
 endif()
 
-set(LIBEPAN_LIBS
-               epan
-               ${AIRPCAP_LIBRARIES}
-               ${PCAP_LIBRARIES}
-               ${CARES_LIBRARIES}
-               ${KERBEROS_LIBRARIES}
-               ${LUA_LIBRARIES}
-               ${PYTHON_LIBRARIES}
-               ${GEOIP_LIBRARIES}
-               ${GCRYPT_LIBRARIES}
-               ${GNUTLS_LIBRARIES}
-               ${SMI_LIBRARIES}
-               ${ZLIB_LIBRARIES}
-               ${LZ4_LIBRARIES}
-               ${SNAPPY_LIBRARIES}
-               ${M_LIBRARIES}
-               ${WINSPARKLE_LIBRARIES}
+set(VERSION_INFO_LIBS
+       ${ZLIB_LIBRARIES}
+)
+set(VERSION_INFO_INCLUDE_DIRS
+       ${ZLIB_INCLUDE_DIRS}
 )
 
 if(WIN32)
@@ -1652,13 +1601,15 @@ if(WIN32)
                WORKING_DIRECTORY "${GLIB2_DLL_DIR}"
        )
 
-       # Optional DLLs.
+       # Optional DLLs and PDBs.
        set (OPTIONAL_DLLS)
+       set (OPTIONAL_PDBS)
        if (AIRPCAP_FOUND)
                list (APPEND OPTIONAL_DLLS "${AIRPCAP_DLL_DIR}/${AIRPCAP_DLL}")
        endif(AIRPCAP_FOUND)
        if (CARES_FOUND)
                list (APPEND OPTIONAL_DLLS "${CARES_DLL_DIR}/${CARES_DLL}")
+               list (APPEND OPTIONAL_PDBS "${CARES_DLL_DIR}/${CARES_PDB}")
        endif(CARES_FOUND)
        if (MAXMINDDB_FOUND)
                list (APPEND OPTIONAL_DLLS "${MAXMINDDB_DLL_DIR}/${MAXMINDDB_DLL}")
@@ -1666,9 +1617,6 @@ if(WIN32)
        if (LIBSSH_FOUND)
                list (APPEND OPTIONAL_DLLS "${LIBSSH_DLL_DIR}/${LIBSSH_DLL}")
        endif(LIBSSH_FOUND)
-       if (JSONGLIB_FOUND)
-               list (APPEND OPTIONAL_DLLS "${JSONGLIB_DLL_DIR}/${JSONGLIB_DLL}")
-       endif(JSONGLIB_FOUND)
        foreach( _dll ${GCRYPT_DLLS} )
                list (APPEND OPTIONAL_DLLS "${GCRYPT_DLL_DIR}/${_dll}")
        endforeach(_dll)
@@ -1756,13 +1704,22 @@ if(WIN32)
                                "${_dll_output_dir}"
                        VERBATIM
                )
+               install(FILES ${OPTIONAL_DLLS} DESTINATION "${CMAKE_INSTALL_BINDIR}")
        endif(OPTIONAL_DLLS)
 
+       if (OPTIONAL_PDBS)
+               add_custom_command(TARGET copy_cli_dlls PRE_BUILD
+                       COMMAND ${CMAKE_COMMAND} -E copy_if_different
+                               ${OPTIONAL_PDBS}
+                               "${_dll_output_dir}"
+                       VERBATIM
+               )
+       endif(OPTIONAL_PDBS)
+
        add_dependencies(epan copy_cli_dlls)
 
        # We have a lot of choices for creating zip archives:
        # - 7z, WinZip, etc., which require a separate download+install.
-       # - Cygwin's zip, which requires Cygwin.
        # - "CMake -E tar cz", which creates a tar file.
        # - CPack, which requires a CPack configuration.
        # - PowerShell via PSCX or System.IO.Compression.FileSystem.
@@ -2009,20 +1966,45 @@ list(APPEND copy_data_files_depends
 add_custom_target(copy_data_files ALL DEPENDS ${copy_data_files_depends} )
 set_target_properties(copy_data_files PROPERTIES FOLDER "Copy Tasks")
 
+
+# Shared code, build object files once for all users.
+add_library(version_info OBJECT version_info.c)
+target_include_directories(version_info SYSTEM PRIVATE ${VERSION_INFO_INCLUDE_DIRS})
+add_dependencies(version_info version)
+# sources common for wireshark, tshark, rawshark and sharkd
+add_library(shark_common OBJECT
+       cfile.c
+       extcap.c
+       extcap_parser.c
+       file_packet_provider.c
+       frame_tvbuff.c
+       sync_pipe_write.c
+)
+add_library(cli_main OBJECT cli_main.c)
+add_library(capture_opts OBJECT capture_opts.c)
+target_include_directories(capture_opts SYSTEM PRIVATE ${PCAP_INCLUDE_DIRS})
+set_target_properties(version_info shark_common cli_main capture_opts
+       PROPERTIES
+       COMPILE_FLAGS "${WERROR_COMMON_FLAGS}"
+)
+
+
 if(BUILD_wireshark AND QT_FOUND)
        set(WIRESHARK_SRC
                capture_info.c
-               capture_opts.c
                file.c
                fileset.c
-               ${SHARK_COMMON_SRC}
                ${PLATFORM_UI_SRC}
        )
        set(wireshark_FILES
+               $<TARGET_OBJECTS:capture_opts>
+               $<TARGET_OBJECTS:qtui>
+               $<TARGET_OBJECTS:shark_common>
+               $<TARGET_OBJECTS:version_info>
                ${WIRESHARK_SRC}
-               ${CMAKE_BINARY_DIR}/image/wireshark.rc
                ${PLATFORM_UI_RC_FILES}
        )
+       set_executable_resources(wireshark "Wireshark" UNIQUE_RC)
 endif()
 
 if(ENABLE_APPLICATION_BUNDLE)
@@ -2050,6 +2032,9 @@ if(ENABLE_APPLICATION_BUNDLE)
        "-Wl,-headerpad_max_install_names -Wl,-search_paths_first ${CMAKE_EXE_LINKER_FLAGS}"
        )
 
+       # Create our Frameworks directory
+       file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/run/${CMAKE_CFG_INTDIR}/Wireshark.app/Contents/Frameworks")
+
        # Add files to the app bundle
        # Wireshark.app/Contents
        file(WRITE ${CMAKE_BINARY_DIR}/packaging/macosx/PkgInfo "APPLWshk\n")
@@ -2095,41 +2080,25 @@ endif()
 
 if(BUILD_wireshark AND QT_FOUND)
        set(wireshark_LIBS
-               qtui
                ui
                capchild
                caputils
                wiretap
-               ${QT_LIBRARIES}
-               ${GTHREAD2_LIBRARIES}
                wscodecs
-               ${LIBEPAN_LIBS}
+               epan
+               ${QT_LIBRARIES}
+               ${VERSION_INFO_LIBS}
                ${APPLE_APPLICATION_SERVICES_LIBRARY}
                ${APPLE_APPKIT_LIBRARY}
                ${APPLE_CORE_FOUNDATION_LIBRARY}
                ${APPLE_SYSTEM_CONFIGURATION_LIBRARY}
-               ${NL_LIBRARIES}
                ${WIN_VERSION_LIBRARY}
+               ${WINSPARKLE_LIBRARIES}
+               $<$<BOOL:${WIN32}>:UxTheme.lib>
        )
 
        add_executable(wireshark WIN32 MACOSX_BUNDLE ${wireshark_FILES} ${EXTRA_BUNDLE_FILES})
-       add_dependencies(wireshark version)
        set(PROGLIST ${PROGLIST} wireshark)
-       if(CMAKE_VERSION VERSION_LESS "2.8.12"
-           AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
-           AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))
-               #
-               # https://doc.qt.io/qt-5/cmake-manual.html says that for CMake
-               # versions older than 2.8.12,
-               # Qt5<Module>_EXECUTABLE_COMPILE_FLAGS must be added such that
-               # -fPIC is included. We should not do add this to
-               # CMAKE_CXX_FLAGS though since it may end up before the -fPIE
-               # option. Instead, add it to the target COMPILE_FLAGS. This
-               # option is deprecated in newer CMake versions and not necessary
-               # either since Qt uses the INTERFACE_COMPILE_OPTIONS property.
-               #
-               set_target_properties(wireshark PROPERTIES COMPILE_FLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
-       endif()
        set_target_properties(wireshark PROPERTIES
                LINK_FLAGS "${WS_LINK_FLAGS}"
                FOLDER "Executables"
@@ -2157,6 +2126,7 @@ if(BUILD_wireshark AND QT_FOUND)
        endif()
 
        target_link_libraries(wireshark ${wireshark_LIBS})
+
        install(
                TARGETS wireshark
                RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -2179,6 +2149,13 @@ if(BUILD_wireshark AND QT_FOUND)
                                "$<TARGET_FILE:wireshark>"
                )
                add_dependencies(copy_qt_dlls wireshark)
+
+               install(CODE "execute_process(COMMAND
+                       \"${QT_WINDEPLOYQT_EXECUTABLE}\"
+                       --no-compiler-runtime
+                       \"\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/Wireshark.exe\")"
+               )
+
        endif(QT_WINDEPLOYQT_EXECUTABLE)
 endif()
 
@@ -2222,21 +2199,24 @@ if(BUILD_tshark)
                capchild
                caputils
                wiretap
-               ${LIBEPAN_LIBS}
+               epan
+               ${VERSION_INFO_LIBS}
                ${APPLE_CORE_FOUNDATION_LIBRARY}
                ${APPLE_SYSTEM_CONFIGURATION_LIBRARY}
+               ${M_LIBRARIES}
        )
        set(tshark_FILES
-               capture_opts.c
+               $<TARGET_OBJECTS:capture_opts>
+               $<TARGET_OBJECTS:cli_main>
+               $<TARGET_OBJECTS:shark_common>
+               $<TARGET_OBJECTS:version_info>
                tshark-tap-register.c
                tshark.c
                ${TSHARK_TAP_SRC}
-               ${SHARK_COMMON_SRC}
-               ${CMAKE_BINARY_DIR}/image/tshark.rc
        )
 
+       set_executable_resources(tshark "TShark" UNIQUE_RC)
        add_executable(tshark ${tshark_FILES})
-       add_dependencies(tshark version)
        set_extra_executable_properties(tshark "Executables")
        target_link_libraries(tshark ${tshark_LIBS})
        install(TARGETS tshark RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
@@ -2246,18 +2226,20 @@ if(BUILD_tfshark)
        set(tfshark_LIBS
                ui
                wiretap
-               ${LIBEPAN_LIBS}
+               epan
+               ${VERSION_INFO_LIBS}
                ${APPLE_CORE_FOUNDATION_LIBRARY}
                ${APPLE_SYSTEM_CONFIGURATION_LIBRARY}
        )
        set(tfshark_FILES
+               $<TARGET_OBJECTS:cli_main>
+               $<TARGET_OBJECTS:shark_common>
+               $<TARGET_OBJECTS:version_info>
                tfshark.c
                ${TSHARK_TAP_SRC}
-               ${SHARK_COMMON_SRC}
-               ${CMAKE_BINARY_DIR}/image/tfshark.rc
        )
+       set_executable_resources(tfshark "TFShark")
        add_executable(tfshark ${tfshark_FILES})
-       add_dependencies(tfshark version)
        set_extra_executable_properties(tfshark "Executables")
        target_link_libraries(tfshark ${tfshark_LIBS})
        install(TARGETS tfshark RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
@@ -2268,17 +2250,19 @@ if(BUILD_rawshark AND PCAP_FOUND)
                caputils
                ui
                wiretap
-               ${LIBEPAN_LIBS}
+               epan
+               ${VERSION_INFO_LIBS}
                ${APPLE_CORE_FOUNDATION_LIBRARY}
                ${APPLE_SYSTEM_CONFIGURATION_LIBRARY}
        )
        set(rawshark_FILES
-               ${SHARK_COMMON_SRC}
+               $<TARGET_OBJECTS:cli_main>
+               $<TARGET_OBJECTS:shark_common>
+               $<TARGET_OBJECTS:version_info>
                rawshark.c
-               ${CMAKE_BINARY_DIR}/image/rawshark.rc
        )
+       set_executable_resources(rawshark "Rawshark")
        add_executable(rawshark ${rawshark_FILES})
-       add_dependencies(rawshark version)
        set_extra_executable_properties(rawshark "Executables")
        target_link_libraries(rawshark ${rawshark_LIBS})
        install(TARGETS rawshark RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
@@ -2289,20 +2273,30 @@ if(BUILD_sharkd)
                ui
                wscodecs
                wiretap
-               ${LIBEPAN_LIBS}
+               epan
+               ${VERSION_INFO_LIBS}
                ${APPLE_CORE_FOUNDATION_LIBRARY}
                ${APPLE_SYSTEM_CONFIGURATION_LIBRARY}
        )
        set(sharkd_FILES
+               #
+               # XXX - currently doesn't work on Windows if it uses
+               # $<TARGET_OBJECTS:cli_main> and has real_main().
+               #
+               $<TARGET_OBJECTS:shark_common>
+               $<TARGET_OBJECTS:version_info>
                sharkd.c
                sharkd_daemon.c
                sharkd_session.c
-               ${SHARK_COMMON_SRC}
        )
+       set_executable_resources(sharkd "SharkD")
        add_executable(sharkd ${sharkd_FILES})
-       add_dependencies(sharkd version)
        set_extra_executable_properties(sharkd "Executables")
        target_link_libraries(sharkd ${sharkd_LIBS})
+       if(WIN32)
+               target_link_libraries(sharkd "ws2_32.lib")
+       endif(WIN32)
+
        install(TARGETS sharkd RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 endif()
 
@@ -2310,13 +2304,13 @@ if(BUILD_dftest)
        set(dftest_LIBS
                ui
                wiretap
-               ${LIBEPAN_LIBS}
+               epan
+               ${VERSION_INFO_LIBS}
        )
        set(dftest_FILES
                dftest.c
        )
        add_executable(dftest ${dftest_FILES})
-       add_dependencies(dftest version)
        set_extra_executable_properties(dftest "Tests")
        target_link_libraries(dftest ${dftest_LIBS})
 endif()
@@ -2333,30 +2327,18 @@ if(BUILD_randpkt)
                ${ZLIB_LIBRARIES}
        )
        set(randpkt_FILES
+               $<TARGET_OBJECTS:cli_main>
+               $<TARGET_OBJECTS:version_info>
                randpkt.c
-               version_info.c
        )
        add_executable(randpkt ${randpkt_FILES})
-       add_dependencies(randpkt version)
        set_extra_executable_properties(randpkt "Executables")
        target_link_libraries(randpkt ${randpkt_LIBS})
        install(TARGETS randpkt RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 endif()
 
-if(BUILD_fuzzshark)
-       set(fuzzshark_LIBS
-               wiretap
-               ${LIBEPAN_LIBS}
-       )
-       set(fuzzshark_FILES
-               tools/oss-fuzzshark/fuzzshark.c
-               tools/oss-fuzzshark/StandaloneFuzzTargetMain.c
-               version_info.c
-       )
-       add_executable(fuzzshark ${fuzzshark_FILES})
-       add_dependencies(fuzzshark version)
-       set_extra_executable_properties(fuzzshark "Executables")
-       target_link_libraries(fuzzshark ${fuzzshark_LIBS})
+if(BUILD_fuzzshark OR ENABLE_FUZZER OR OSS_FUZZ)
+       add_subdirectory(fuzz)
 endif()
 
 if(BUILD_text2pcap)
@@ -2367,15 +2349,16 @@ if(BUILD_text2pcap)
                ${ZLIB_LIBRARIES}
        )
        set(text2pcap_FILES
+               $<TARGET_OBJECTS:cli_main>
+               $<TARGET_OBJECTS:version_info>
                text2pcap.c
-               version_info.c
        )
        add_lex_files(text2pcap_LEX_FILES text2pcap_FILES
                text2pcap-scanner.l
        )
-       add_executable(text2pcap ${text2pcap_FILES}
-               ${CMAKE_BINARY_DIR}/image/text2pcap.rc)
-       add_dependencies(text2pcap version)
+       set_executable_resources(text2pcap "Text2pcap"
+               COPYRIGHT_INFO "2001 Ashok Narayanan <ashokn@cisco.com>")
+       add_executable(text2pcap ${text2pcap_FILES})
        set_extra_executable_properties(text2pcap "Executables")
        target_link_libraries(text2pcap ${text2pcap_LIBS})
        install(TARGETS text2pcap RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
@@ -2389,12 +2372,12 @@ if(BUILD_mergecap)
                ${CMAKE_DL_LIBS}
        )
        set(mergecap_FILES
+               $<TARGET_OBJECTS:cli_main>
+               $<TARGET_OBJECTS:version_info>
                mergecap.c
-               version_info.c
-               ${CMAKE_BINARY_DIR}/image/mergecap.rc
        )
+       set_executable_resources(mergecap "Mergecap")
        add_executable(mergecap ${mergecap_FILES})
-       add_dependencies(mergecap version)
        set_extra_executable_properties(mergecap "Executables")
        target_link_libraries(mergecap ${mergecap_LIBS})
        install(TARGETS mergecap RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
@@ -2408,12 +2391,12 @@ if(BUILD_reordercap)
                ${CMAKE_DL_LIBS}
        )
        set(reordercap_FILES
+               $<TARGET_OBJECTS:cli_main>
+               $<TARGET_OBJECTS:version_info>
                reordercap.c
-               version_info.c
-               ${CMAKE_BINARY_DIR}/image/reordercap.rc
        )
+       set_executable_resources(reordercap "Reordercap")
        add_executable(reordercap ${reordercap_FILES})
-       add_dependencies(reordercap version)
        set_extra_executable_properties(reordercap "Executables")
        target_link_libraries(reordercap ${reordercap_LIBS})
        install(TARGETS reordercap RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
@@ -2429,12 +2412,12 @@ if(BUILD_capinfos)
                ${CMAKE_DL_LIBS}
        )
        set(capinfos_FILES
+               $<TARGET_OBJECTS:cli_main>
+               $<TARGET_OBJECTS:version_info>
                capinfos.c
-               version_info.c
-               ${CMAKE_BINARY_DIR}/image/capinfos.rc
        )
+       set_executable_resources(capinfos "Capinfos")
        add_executable(capinfos ${capinfos_FILES})
-       add_dependencies(capinfos version)
        set_extra_executable_properties(capinfos "Executables")
        target_link_libraries(capinfos ${capinfos_LIBS})
        install(TARGETS capinfos RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
@@ -2449,12 +2432,12 @@ if(BUILD_captype)
                ${CMAKE_DL_LIBS}
        )
        set(captype_FILES
+               $<TARGET_OBJECTS:cli_main>
+               $<TARGET_OBJECTS:version_info>
                captype.c
-               version_info.c
-               ${CMAKE_BINARY_DIR}/image/captype.rc
        )
+       set_executable_resources(captype "Captype")
        add_executable(captype ${captype_FILES})
-       add_dependencies(captype version)
        set_extra_executable_properties(captype "Executables")
        target_link_libraries(captype ${captype_LIBS})
        install(TARGETS captype RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
@@ -2469,12 +2452,12 @@ if(BUILD_editcap)
                ${CMAKE_DL_LIBS}
        )
        set(editcap_FILES
+               $<TARGET_OBJECTS:cli_main>
+               $<TARGET_OBJECTS:version_info>
                editcap.c
-               version_info.c
-               ${CMAKE_BINARY_DIR}/image/editcap.rc
        )
+       set_executable_resources(editcap "Editcap")
        add_executable(editcap ${editcap_FILES})
-       add_dependencies(editcap version)
        set_extra_executable_properties(editcap "Executables")
        target_link_libraries(editcap ${editcap_LIBS})
        install(TARGETS editcap RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
@@ -2493,20 +2476,17 @@ if(BUILD_dumpcap AND PCAP_FOUND)
                ${ZLIB_LIBRARIES}
                ${APPLE_CORE_FOUNDATION_LIBRARY}
                ${APPLE_SYSTEM_CONFIGURATION_LIBRARY}
-               ${NL_LIBRARIES}
        )
        set(dumpcap_FILES
-               capture_opts.c
-               capture_stop_conditions.c
-               conditions.c
+               $<TARGET_OBJECTS:capture_opts>
+               $<TARGET_OBJECTS:cli_main>
+               $<TARGET_OBJECTS:version_info>
                dumpcap.c
                ringbuffer.c
                sync_pipe_write.c
-               version_info.c
-               ${CMAKE_BINARY_DIR}/image/dumpcap.rc
        )
+       set_executable_resources(dumpcap "Dumpcap" UNIQUE_RC)
        add_executable(dumpcap ${dumpcap_FILES})
-       add_dependencies(dumpcap version)
        set_extra_executable_properties(dumpcap "Executables")
        target_link_libraries(dumpcap ${dumpcap_LIBS})
        install(TARGETS dumpcap
@@ -2590,7 +2570,8 @@ if (MAXMINDDB_FOUND)
        add_executable(mmdbresolve ${mmdbresolve_FILES})
        set_extra_executable_properties(mmdbresolve "Executables")
        target_link_libraries(mmdbresolve ${mmdbresolve_LIBS})
-       target_include_directories(mmdbresolve PUBLIC ${MAXMINDDB_INCLUDE_DIR})
+       target_include_directories(mmdbresolve PUBLIC ${MAXMINDDB_INCLUDE_DIRS})
+       target_compile_definitions(mmdbresolve PUBLIC ${MAXMINDDB_DEFINITIONS})
        install(TARGETS mmdbresolve RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 endif()
 
@@ -2648,20 +2629,16 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
        find_program(RPMBUILD_EXECUTABLE rpmbuild)
        find_program(DPKG_BUILDPACKAGE_EXECUTABLE dpkg-buildpackage)
        find_program(GIT_EXECUTABLE git)
+       # Should we add appimaged's monitored directories
+       # as HINTS?
+       # https://github.com/AppImage/appimaged
+       find_program(LINUXDEPLOYQT_EXECUTABLE linuxdeployqt)
+       find_program(APPIMAGETOOL_EXECUTABLE appimagetool)
 endif()
 
-function(_SET_GITVERSION_CMAKE_VARIABLE OUTPUT_VARIABLE)
-       # Load version string and write it to a cmake variable so it can be accessed from cmake.
-       FILE(READ "${CMAKE_CURRENT_BINARY_DIR}/version.h" VERSION_H_FILE_CONTENT)
-       string(REPLACE "\n" "" VERSION_H_FILE_CONTENT ${VERSION_H_FILE_CONTENT})
-       #define VCSVERSION "v2.9.0rc0-305-gb8e8aa87"
-       string(SUBSTRING "${VERSION_H_FILE_CONTENT}" 21 -1 VERSION_STRING)
-       STRING(REGEX REPLACE "\"" "" VERSION_STRING "${VERSION_STRING}")
-       MESSAGE(STATUS "Version string created from version.h: ${VERSION_STRING}")
-       SET(${OUTPUT_VARIABLE} "${VERSION_STRING}"  CACHE INTERNAL "${OUTPUT_VARIABLE}")
-endfunction(_SET_GITVERSION_CMAKE_VARIABLE)
-
 
+string(REPLACE "-" "_" RPM_VERSION "${VERSION}")
+configure_file(packaging/rpm/wireshark.spec.in ${CMAKE_BINARY_DIR}/packaging/rpm/SPECS/wireshark.spec)
 if(RPMBUILD_EXECUTABLE)
        foreach(_rpm_dir BUILD RPMS SOURCES SPECS SRPMS)
                file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/packaging/rpm/${_rpm_dir}")
@@ -2707,30 +2684,17 @@ if(RPMBUILD_EXECUTABLE)
 
        execute_process(
                COMMAND ${PERL_EXECUTABLE}
-                       ${CMAKE_SOURCE_DIR}/make-version.pl
+                       ${CMAKE_SOURCE_DIR}/tools/make-version.pl
                        ${CMAKE_SOURCE_DIR}
        )
 
-       _SET_GITVERSION_CMAKE_VARIABLE(_git_description)
-
-       if (NOT _git_description)
-               # We're building the rpm outside the source. Guess the version from the dirname.
-               get_filename_component(CMAKE_SOURCE_DIR_NAME ${CMAKE_SOURCE_DIR} NAME)
-               # XXX this assumes the directory to start with "wireshark-"
-               string(SUBSTRING "${CMAKE_SOURCE_DIR_NAME}" 10 -1 _git_description)
-       endif()
-       string(REPLACE "-" "_" RPM_VERSION "${_git_description}")
-       configure_file(packaging/rpm/wireshark.spec.in ${CMAKE_BINARY_DIR}/packaging/rpm/SPECS/wireshark.spec)
-
        # XXX Replace with the "dist" target?
-       set(_export_tarball "${CPACK_PACKAGE_NAME}-${_git_description}.tar.xz")
+       set(_export_tarball "${CPACK_PACKAGE_NAME}-${VERSION}.tar.xz")
        add_custom_command(
                OUTPUT "${CMAKE_BINARY_DIR}/packaging/rpm/SOURCES/${_export_tarball}"
-               COMMAND ./tools/git-export-release.sh
+               COMMAND ${CMAKE_BINARY_DIR}/packaging/source/git-export-release.sh
                        -d "${CMAKE_BINARY_DIR}/packaging/rpm/SOURCES"
-                       "${_git_description}"
-               # XXX Add an option to git-export-release.sh to write to a
-               # specific directory so that we can get rid of `ln` below.
+                       "${VERSION}"
                WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
        )
        add_custom_target(rpm-package
@@ -2738,7 +2702,7 @@ if(RPMBUILD_EXECUTABLE)
                        --define "_topdir ${CMAKE_BINARY_DIR}/packaging/rpm"
                        --define "_prefix ${CMAKE_INSTALL_PREFIX}"
                        ${_rpmbuild_with_args}
-                       --clean -ba SPECS/wireshark.spec
+                       -ba SPECS/wireshark.spec
                DEPENDS "${CMAKE_BINARY_DIR}/packaging/rpm/SOURCES/${_export_tarball}"
                WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/packaging/rpm"
                COMMENT "Create a tarball from the current git commit."
@@ -2752,6 +2716,54 @@ if(DPKG_BUILDPACKAGE_EXECUTABLE)
        )
 endif()
 
+if(LINUXDEPLOYQT_EXECUTABLE AND APPIMAGETOOL_EXECUTALBE)
+       # The documentation at https://github.com/probonopd/linuxdeployqt
+       # says that you need to set CMAKE_BUILD_TYPE=Release and
+       # CMAKE_INSTALL_PREFIX=/usr. I (gcc) also had to set
+       # CMAKE_INSTALL_LIBDIR=/usr/lib.
+       if (CMAKE_BUILD_TYPE STREQUAL "Release" AND CMAKE_INSTALL_PREFIX STREQUAL "/usr" AND CMAKE_INSTALL_LIBDIR STREQUAL "/usr/lib" )
+               add_custom_target(appimage-prerequisites)
+               add_dependencies(appimage-prerequisites ${PROGLIST})
+       else()
+               add_custom_target(appimage-prerequisites
+                       COMMAND echo "CMAKE_BUILD_TYPE isn't Release or CMAKE_INSTALL_PREFIX isn't /usr or CMAKE_INSTALL_LIBDIR isn't /usr/lib."
+                       COMMAND false
+               )
+       endif()
+       set (_ai_appdir "${CMAKE_BINARY_DIR}/packaging/appimage/appdir")
+       add_custom_target(appimage-appdir
+               COMMAND ${CMAKE_COMMAND} -E make_directory "${_ai_appdir}"
+               COMMAND env DESTDIR=${_ai_appdir}
+                       ${CMAKE_COMMAND} --build . --target install
+               DEPENDS appimage-prerequisites
+       )
+       set(_exe_args)
+       foreach(_prog ${PROGLIST})
+               # XXX Is this the correct path?
+               list(APPEND _exe_args "-executable=${_ai_appdir}/usr/bin/${_prog}")
+       endforeach()
+       # linuxdeployqt currently clobbers AppRun:
+       # https://github.com/probonopd/linuxdeployqt/issues/159
+       # When that's fixed we will no longer need appimagetool. Until
+       # then, we need to prep and package in two steps:
+       # https://github.com/probonopd/linuxdeployqt/wiki/Custom-wrapper-script-instead-of-AppRun
+       add_custom_target(appimage-prep
+               COMMAND ${LINUXDEPLOYQT_EXECUTABLE}
+                       "${_ai_appdir}/usr/share/applications/wireshark.desktop"
+                       ${_exe_args}
+               COMMAND rm -f "${_ai_appdir}/AppRun"
+               COMMAND install
+                       "${CMAKE_SOURCE_DIR}/packaging/appimage/AppRun"
+                       "${_ai_appdir}/AppRun"
+               DEPENDS appimage-appdir
+       )
+       add_custom_target(appimage
+               COMMAND env VERSION=${PROJECT_VERSION} ${APPIMAGETOOL_EXECUTABLE} appdir
+               WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/packaging/appimage"
+               DEPENDS appimage-prep
+       )
+endif()
+
 set(CLEAN_C_FILES
        ${dumpcap_FILES}
        ${wireshark_FILES}
@@ -2779,6 +2791,7 @@ if (WIN32)
        list(FILTER CLEAN_C_FILES EXCLUDE REGEX ".*\\.rc")
 endif (WIN32)
 
+# XXX This also contains object files ($<TARGET_OBJECTS:...>), is that an issue?
 set_source_files_properties(
        ${CLEAN_C_FILES}
        PROPERTIES
@@ -2793,11 +2806,12 @@ install(
                GROUP_READ
                WORLD_READ
        DESTINATION
-               ${CMAKE_INSTALL_DATADIR}/${CPACK_PACKAGE_NAME}
+               ${CMAKE_INSTALL_DATADIR}
 )
 
 set(SHARK_PUBLIC_HEADERS
        cfile.h
+       cli_main.h
        file.h
        globals.h
        log.h
@@ -2809,38 +2823,33 @@ set(SHARK_PUBLIC_HEADERS
        ${CMAKE_BINARY_DIR}/ws_version.h
 )
 
-if(NOT WIN32)
-       install(
-               FILES
-                       ${SHARK_PUBLIC_HEADERS}
-               DESTINATION
-                       ${CMAKE_INSTALL_INCLUDEDIR}/${CPACK_PACKAGE_NAME}
-       )
-endif()
+install(FILES ${SHARK_PUBLIC_HEADERS}
+       DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CPACK_PACKAGE_NAME}
+)
 
 # Install icons and other desktop files for Freedesktop.org-compliant desktops.
 if((BUILD_wireshark AND QT_FOUND) AND NOT (WIN32 OR APPLE))
        install(FILES wireshark-mime-package.xml
-               DESTINATION "${CMAKE_INSTALL_DATADIR}/mime/packages"
+               DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/mime/packages"
                RENAME wireshark.xml
        )
        install(FILES wireshark.appdata.xml
-               DESTINATION "${CMAKE_INSTALL_DATADIR}/appdata"
+               DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/appdata"
        )
        if(BUILD_wireshark AND QT_FOUND)
                install(FILES wireshark.desktop
-                       DESTINATION "${CMAKE_INSTALL_DATADIR}/applications")
+                       DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications")
        endif()
        foreach(size 16 24 32 48 64 128 256)
                install(FILES image/wsicon${size}.png
-                       DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/${size}x${size}/apps"
+                       DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${size}x${size}/apps"
                        RENAME wireshark.png)
                install(FILES image/WiresharkDoc-${size}.png
-                       DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/${size}x${size}/mimetypes"
+                       DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${size}x${size}/mimetypes"
                        RENAME application-wireshark-doc.png)
        endforeach()
        install(FILES image/wsicon.svg
-               DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps"
+               DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps"
                RENAME wireshark.svg)
 endif()
 
@@ -2855,7 +2864,7 @@ install(
        DIRECTORY
                ${INSTALL_DIRS}
        DESTINATION
-               ${CMAKE_INSTALL_DATADIR}/${CPACK_PACKAGE_NAME}
+               ${CMAKE_INSTALL_DATADIR}
        FILE_PERMISSIONS
                OWNER_WRITE OWNER_READ
                GROUP_READ
@@ -2869,7 +2878,14 @@ install(
        PATTERN "Makefile.*" EXCLUDE
 )
 
-set(CMAKE_INSTALL_MODULES_DIR "${CMAKE_INSTALL_LIBDIR}/${CPACK_PACKAGE_NAME}/cmake")
+if(WIN32)
+       # Note: CMake export mechanism misbehaves with a '.' in the
+       # path (incorrect relative path computation).
+       set(WIRESHARK_INSTALL_CMAKEDIR "cmake")
+else()
+       set(WIRESHARK_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/${CPACK_PACKAGE_NAME}/cmake")
+endif()
+
 install(
        FILES
                ${CMAKE_MODULE_PATH}/FindGLIB2.cmake
@@ -2878,14 +2894,14 @@ install(
                ${CMAKE_MODULE_PATH}/LocatePythonModule.cmake
                ${CMAKE_MODULE_PATH}/UseMakePluginReg.cmake
        DESTINATION
-               ${CMAKE_INSTALL_MODULES_DIR}
+               ${WIRESHARK_INSTALL_CMAKEDIR}
 )
 
 include(CMakePackageConfigHelpers)
 
 configure_package_config_file(WiresharkConfig.cmake.in
        ${CMAKE_BINARY_DIR}/WiresharkConfig.cmake
-       INSTALL_DESTINATION ${CMAKE_INSTALL_MODULES_DIR}
+       INSTALL_DESTINATION ${WIRESHARK_INSTALL_CMAKEDIR}
        PATH_VARS
                CMAKE_INSTALL_LIBDIR
                CMAKE_INSTALL_INCLUDEDIR
@@ -2898,21 +2914,17 @@ write_basic_package_version_file(
        COMPATIBILITY AnyNewerVersion
 )
 
-# XXX On Windows wsutil depends on a CMake zlib target for which there are no
-# exports.
-if(NOT WIN32)
-       install(
-               FILES
-                       ${CMAKE_BINARY_DIR}/WiresharkConfig.cmake
-                       ${CMAKE_BINARY_DIR}/WiresharkConfigVersion.cmake
-               DESTINATION
-                       ${CMAKE_INSTALL_MODULES_DIR}
-       )
+install(
+       FILES
+               ${CMAKE_BINARY_DIR}/WiresharkConfig.cmake
+               ${CMAKE_BINARY_DIR}/WiresharkConfigVersion.cmake
+       DESTINATION
+               ${WIRESHARK_INSTALL_CMAKEDIR}
+)
 
-       install(EXPORT WiresharkTargets
-               DESTINATION ${CMAKE_INSTALL_MODULES_DIR}
-       )
-endif()
+install(EXPORT WiresharkTargets
+       DESTINATION ${WIRESHARK_INSTALL_CMAKEDIR}
+)
 
 if (DOXYGEN_EXECUTABLE)
        # API reference
@@ -2960,6 +2972,7 @@ set(_test_group_list
        suite_dfilter.group_bytes_ipv6
        suite_dfilter.group_bytes_type
        suite_dfilter.group_double
+       suite_dfilter.group_dfunction_string
        suite_dfilter.group_integer
        suite_dfilter.group_integer_1byte
        suite_dfilter.group_ipv4
@@ -2973,11 +2986,13 @@ set(_test_group_list
        suite_dfilter.group_tvb
        suite_dfilter.group_uint64
        suite_dissection
+       suite_dissectors.group_asterix
        suite_fileformats
        suite_follow
        suite_io
        suite_mergecap
        suite_nameres
+       suite_outputformats
        suite_text2pcap
        suite_sharkd
        suite_unittests
@@ -3003,6 +3018,15 @@ foreach(_group_name ${_test_group_list})
        set_tests_properties(${_group_name} PROPERTIES TIMEOUT 600)
 endforeach()
 
+# Make it possible to run pytest without passing the full path as argument.
+if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
+       file(READ "${CMAKE_CURRENT_SOURCE_DIR}/pytest.ini" pytest_ini)
+       string(REGEX REPLACE "\naddopts = ([^\n]+)"
+               "\naddopts = ${CMAKE_CURRENT_SOURCE_DIR}/test \\1"
+               pytest_ini "${pytest_ini}")
+       file(WRITE "${CMAKE_BINARY_DIR}/pytest.ini" "${pytest_ini}")
+endif()
+
 if (GIT_EXECUTABLE)
        # Update AUTHORS file with entries from git shortlog
        add_custom_target(
@@ -3063,11 +3087,12 @@ if(SHELLCHECK_EXECUTABLE)
        add_custom_command(TARGET shellcheck POST_BUILD
                COMMAND shellcheck --external-sources
                        image/stock_icons/svg-to-png.sh
+                       packaging/appimage/AppRun
                        packaging/macosx/osx-app.sh.in
                        packaging/macosx/osx-dmg.sh.in
+                       packaging/source/git-export-release.sh.in
                        tools/compress-pngs.sh
                        tools/debian-setup.sh
-                       tools/git-export-release.sh
                        tools/fuzz-test.sh
                        tools/gen-bugnote
                        tools/pre-commit