MSYS2: Add support for building a stand-alone NSIS installer
This changes the existing code for the MSVC installer as little as possible to allow building the Wireshark .exe Windows installer using the MinGW-w64 toolchain. Currently the DLL dependency list is static, this may change in the future. Ideally we would use CPack and install() logic to copy the DLLs. The msys2checkdeps.py script is copied from the Inkscape project[1]. It doesn't have a specific license identifier. The Inkscape project is licensed under the GPL version 2 or later. TODO: Download Npcap and USBPcap using CMake instead of requiring manual action. [1]https://gitlab.com/inkscape/inkscape Ping #17771.
This commit is contained in:
parent
83cebf9563
commit
aa6b8368b7
@ -178,10 +178,10 @@ if(WIN32)
|
||||
and CPU target ${WIRESHARK_TARGET_PROCESSOR_ARCHITECTURE}"
|
||||
)
|
||||
|
||||
find_package(PowerShell REQUIRED)
|
||||
|
||||
# Determine where the 3rd party libraries will be
|
||||
if(USE_REPOSITORY)
|
||||
find_package(PowerShell REQUIRED)
|
||||
|
||||
if( DEFINED ENV{WIRESHARK_LIB_DIR} )
|
||||
# The buildbots set WIRESHARK_LIB_DIR but not WIRESHARK_BASE_DIR.
|
||||
file( TO_CMAKE_PATH "$ENV{WIRESHARK_LIB_DIR}" _PROJECT_LIB_DIR )
|
||||
@ -213,6 +213,8 @@ and CPU target ${WIRESHARK_TARGET_PROCESSOR_ARCHITECTURE}"
|
||||
set(EXTRA_INSTALLER_DIR ${_ws_lib_dir})
|
||||
|
||||
# XXX Add a dependency on ${_ws_lib_dir}/current_tag.txt?
|
||||
else()
|
||||
set(EXTRA_INSTALLER_DIR ${CMAKE_BINARY_DIR}/packaging/nsis)
|
||||
endif()
|
||||
endif(WIN32)
|
||||
|
||||
@ -1397,8 +1399,13 @@ if (QT_FOUND)
|
||||
)
|
||||
# Use qmake to find windeployqt and macdeployqt. Ideally one of
|
||||
# the modules in ${QTDIR}/lib/cmake would do this for us.
|
||||
if(WIN32 AND NOT USE_MSYSTEM)
|
||||
find_program(QT_WINDEPLOYQT_EXECUTABLE windeployqt
|
||||
if(WIN32)
|
||||
if (USE_qt6 AND USE_MSYSTEM)
|
||||
set(_windeployqt_name "windeployqt-qt6")
|
||||
else()
|
||||
set(_windeployqt_name "windeployqt")
|
||||
endif()
|
||||
find_program(QT_WINDEPLOYQT_EXECUTABLE ${_windeployqt_name}
|
||||
HINTS "${QT_BIN_PATH}"
|
||||
DOC "Path to the windeployqt utility."
|
||||
)
|
||||
@ -2263,7 +2270,7 @@ endif()
|
||||
# List of extra dependencies for the "copy_data_files" target
|
||||
set(copy_data_files_depends)
|
||||
|
||||
if(WIN32 AND NOT USE_MSYSTEM)
|
||||
if(WIN32)
|
||||
foreach(_install_as_txt_file COPYING NEWS README.md README.windows)
|
||||
# On Windows, install some files with a .txt extension so that they're
|
||||
# double-clickable.
|
||||
@ -2720,6 +2727,13 @@ if(BUILD_wireshark AND QT_FOUND)
|
||||
set_target_properties(copy_qt_dlls PROPERTIES FOLDER "Copy Tasks")
|
||||
# Will we ever need to use --debug? Windeployqt seems to
|
||||
# be smart enough to copy debug DLLs when needed.
|
||||
if (USE_MSYSTEM AND Qt${qtver}Widgets_VERSION VERSION_EQUAL 6.5.0)
|
||||
# windeployqt released with Qt 6.5.0 is broken.
|
||||
# https://bugreports.qt.io/browse/QTBUG-112204
|
||||
message(WARNING "Qt Deploy Tool 6.5.0 is broken, skipping translations.")
|
||||
list(APPEND QT_WINDEPLOYQT_EXTRA_ARGS --no-translations)
|
||||
set(SKIP_QT_TRANSLATIONS True)
|
||||
endif()
|
||||
add_custom_command(TARGET copy_qt_dlls
|
||||
POST_BUILD
|
||||
COMMAND set "PATH=${QT_BIN_PATH};%PATH%"
|
||||
@ -3263,7 +3277,7 @@ if(BUILD_dcerpcidl2wrs)
|
||||
install(TARGETS idl2wrs RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(WIN32)
|
||||
find_package( MSVC_REDIST )
|
||||
|
||||
# Must come after executable targets are defined.
|
||||
|
@ -104,7 +104,7 @@ option(ENABLE_NGHTTP2 "Build with HTTP/2 header decompression support" ON)
|
||||
option(ENABLE_LUA "Build with Lua dissector support" ON)
|
||||
option(ENABLE_SMI "Build with libsmi snmp support" ON)
|
||||
option(ENABLE_GNUTLS "Build with RSA decryption support" ON)
|
||||
if(WIN32)
|
||||
if(WIN32 AND NOT USE_MSYSTEM)
|
||||
option(ENABLE_WINSPARKLE "Enable automatic updates using WinSparkle" ON)
|
||||
endif()
|
||||
if (NOT WIN32)
|
||||
|
20
README.msys2
20
README.msys2
@ -36,6 +36,23 @@ How to build Wireshark from source:
|
||||
|
||||
The application should be launched using the same shell.
|
||||
|
||||
How to build an NSIS stand-alone binary installer:
|
||||
|
||||
1. Follow the instructions above to compile Wireshark from source.
|
||||
|
||||
2. Build the Wireshark User Guide.
|
||||
|
||||
$ ninja user_guide_html
|
||||
|
||||
3. Download Npcap and USBpcap and copy them to ${CMAKE_BINARY_DIR}/packaging/nsis.
|
||||
|
||||
4. Build the installer
|
||||
|
||||
$ ninja wireshark_nsis_prep
|
||||
$ ninja wireshark_nsis
|
||||
|
||||
If successful the installer can be found in ${CMAKE_BINARY_DIR}/packaging/nsis.
|
||||
|
||||
Alternatively you can also use the PKGBUILD included in the Wireshark
|
||||
source distribution to compile Wireshark into a binary package that can be
|
||||
installed using pacman[3].
|
||||
@ -53,9 +70,6 @@ the build using MSVC:
|
||||
* AirPcap is not available. AirPcap is EOL and currently there is no plan to
|
||||
add support for it with MinGW-w64 builds.
|
||||
|
||||
* TODO: Add a stand-alone distributable binary installer that can be
|
||||
deployed outside the MSYS2 environment.
|
||||
|
||||
References:
|
||||
|
||||
[1]https://packages.msys2.org/base/mingw-w64-wireshark
|
||||
|
@ -39,6 +39,9 @@ That must be done explicitly using ``cmake --install <builddir> --component Deve
|
||||
The Wireshark installation is relocatable on Linux (and other ELF platforms
|
||||
with support for relative RPATHs).
|
||||
|
||||
Support for building an NSIS Windows installer using the MinGW-w64 toolchain
|
||||
and https://www.msys2.org/[MSYS2]. Read README.msys2 in the distribution for more information.
|
||||
|
||||
Many other improvements have been made.
|
||||
See the “New and Updated Features” section below for more details.
|
||||
|
||||
|
@ -18,13 +18,13 @@ set(WIRESHARK_NSIS_GENERATED_FILES
|
||||
set(WIRESHARK_NSIS_GENERATED_FILES ${WIRESHARK_NSIS_GENERATED_FILES} PARENT_SCOPE)
|
||||
|
||||
set(WIRESHARK_NSIS_FILES
|
||||
wireshark.nsi
|
||||
uninstall-wireshark.nsi
|
||||
wireshark-common.nsh
|
||||
GetWindowsVersion.nsh
|
||||
servicelib.nsh
|
||||
NpcapPage.ini
|
||||
USBPcapPage.ini
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wireshark.nsi
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/uninstall-wireshark.nsi
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wireshark-common.nsh
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GetWindowsVersion.nsh
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/servicelib.nsh
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/NpcapPage.ini
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/USBPcapPage.ini
|
||||
${WIRESHARK_NSIS_GENERATED_FILES}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@ -161,26 +161,34 @@ if (BUILD_wireshark)
|
||||
# wireshark-manifest.nsh. Can be created at configure time.
|
||||
set(_all_manifest "${CMAKE_CURRENT_BINARY_DIR}/wireshark-manifest.nsh")
|
||||
set(_all_manifest_contents "# Files required for all sections. Generated by CMake.\n")
|
||||
set(_all_manifest_contents "${_all_manifest_contents}!ifdef BUNDLE_DEBUG_DLLS\n")
|
||||
foreach(_dll ${GLIB2_DLLS_DEBUG})
|
||||
set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
|
||||
endforeach()
|
||||
set(_all_manifest_contents "${_all_manifest_contents}!else\n")
|
||||
foreach(_dll ${GLIB2_DLLS_RELEASE})
|
||||
set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
|
||||
endforeach()
|
||||
set(_all_manifest_contents "${_all_manifest_contents}!endif\n")
|
||||
foreach(_dll ${CARES_DLL} ${PCRE2_DLL} ${GCRYPT_DLLS}
|
||||
${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLLS} ${LUA_DLL}
|
||||
${LZ4_DLL} ${NGHTTP2_DLL} ${SBC_DLL} ${SMI_DLL} ${SNAPPY_DLL}
|
||||
${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLLS} ${WINSPARKLE_DLL}
|
||||
${ZLIB_DLL} ${BROTLI_DLLS} ${ZSTD_DLL} ${ILBC_DLL} ${OPUS_DLL}
|
||||
${SPEEXDSP_DLL}
|
||||
# Needed for mmdbresolve
|
||||
${MAXMINDDB_DLL}
|
||||
)
|
||||
set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
|
||||
endforeach()
|
||||
if(USE_REPOSITORY)
|
||||
set(_all_manifest_contents "${_all_manifest_contents}!ifdef BUNDLE_DEBUG_DLLS\n")
|
||||
foreach(_dll ${GLIB2_DLLS_DEBUG})
|
||||
set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
|
||||
endforeach()
|
||||
set(_all_manifest_contents "${_all_manifest_contents}!else\n")
|
||||
foreach(_dll ${GLIB2_DLLS_RELEASE})
|
||||
set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
|
||||
endforeach()
|
||||
set(_all_manifest_contents "${_all_manifest_contents}!endif\n")
|
||||
foreach(_dll ${CARES_DLL} ${PCRE2_DLL} ${GCRYPT_DLLS}
|
||||
${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLLS} ${LUA_DLL}
|
||||
${LZ4_DLL} ${NGHTTP2_DLL} ${SBC_DLL} ${SMI_DLL} ${SNAPPY_DLL}
|
||||
${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLLS} ${WINSPARKLE_DLL}
|
||||
${ZLIB_DLL} ${BROTLI_DLLS} ${ZSTD_DLL} ${ILBC_DLL} ${OPUS_DLL}
|
||||
${SPEEXDSP_DLL}
|
||||
# Needed for mmdbresolve
|
||||
${MAXMINDDB_DLL}
|
||||
)
|
||||
set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
|
||||
endforeach()
|
||||
else()
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/InstallMSYS2.cmake)
|
||||
foreach(_dll ${MINGW_DLLS})
|
||||
file(TO_NATIVE_PATH ${_dll} _path)
|
||||
set(_all_manifest_contents "${_all_manifest_contents}File \"${_path}\"\n")
|
||||
endforeach()
|
||||
endif()
|
||||
foreach(_script "init.lua" "console.lua" "dtd_gen.lua")
|
||||
set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_script}\"\n")
|
||||
endforeach()
|
||||
@ -291,14 +299,24 @@ macro( ADD_NSIS_PACKAGE_TARGETS )
|
||||
#set (_nsis_package ${CMAKE_BINARY_DIR}/packaging/nsis/Wireshark-$(WIRESHARK_TARGET_PLATFORM)-$(VERSION).exe)
|
||||
|
||||
# wireshark-qt-manifest.nsh. Created using Wireshark.exe.
|
||||
add_custom_command(OUTPUT ${_nsis_binary_dir}/wireshark-qt-manifest.nsh
|
||||
COMMAND set "PATH=${QT_BIN_PATH};%PATH%"
|
||||
COMMAND ${POWERSHELL_COMMAND} "${_nsis_source_dir}/windeployqt-to-nsis.ps1"
|
||||
-Executable $<TARGET_FILE:wireshark>
|
||||
-FilePath ${_nsis_binary_dir}/wireshark-qt-manifest.nsh
|
||||
$<$<CONFIG:Debug>:-DebugConfig>
|
||||
DEPENDS "${_nsis_source_dir}/windeployqt-to-nsis.ps1"
|
||||
)
|
||||
if (USE_REPOSITORY)
|
||||
add_custom_command(OUTPUT ${_nsis_binary_dir}/wireshark-qt-manifest.nsh
|
||||
COMMAND set "PATH=${QT_BIN_PATH};%PATH%"
|
||||
COMMAND ${POWERSHELL_COMMAND} "${_nsis_source_dir}/windeployqt-to-nsis.ps1"
|
||||
-Executable $<TARGET_FILE:wireshark>
|
||||
-FilePath ${_nsis_binary_dir}/wireshark-qt-manifest.nsh
|
||||
$<$<CONFIG:Debug>:-DebugConfig>
|
||||
DEPENDS "${_nsis_source_dir}/windeployqt-to-nsis.ps1"
|
||||
)
|
||||
else()
|
||||
add_custom_command(OUTPUT ${_nsis_binary_dir}/wireshark-qt-manifest.nsh
|
||||
COMMAND ${PYTHON_EXECUTABLE} "${_nsis_source_dir}/windeployqt-to-nsis.py"
|
||||
$<TARGET_FILE:wireshark>
|
||||
${_nsis_binary_dir}/wireshark-qt-manifest.nsh
|
||||
#$<$<CONFIG:Debug>:-DebugConfig>
|
||||
DEPENDS "${_nsis_source_dir}/windeployqt-to-nsis.py"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Build NSIS package dependencies. We build the package in
|
||||
# two stages so that wireshark_nsis below doesn't trigger
|
||||
@ -322,6 +340,9 @@ macro( ADD_NSIS_PACKAGE_TARGETS )
|
||||
add_custom_target(wireshark_nsis
|
||||
COMMAND ${MAKENSIS_EXECUTABLE} ${NSIS_OPTIONS}
|
||||
$<$<CONFIG:Debug>:/DBUNDLE_DEBUG_DLLS>
|
||||
$<$<BOOL:${MSVC}>:/DUSE_VCREDIST>
|
||||
$<$<BOOL:${BUILD_etwdump}>:/DHAVE_ETWDUMP>
|
||||
$<$<BOOL:${SKIP_QT_TRANSLATIONS}>:/DSKIP_QT_TRANSLATIONS>
|
||||
wireshark.nsi
|
||||
WORKING_DIRECTORY ${_nsis_source_dir}
|
||||
)
|
||||
|
71
packaging/nsis/InstallMSYS2.cmake
Normal file
71
packaging/nsis/InstallMSYS2.cmake
Normal file
@ -0,0 +1,71 @@
|
||||
set(MINGW_BIN $ENV{MINGW_PREFIX}/bin)
|
||||
|
||||
if(USE_MSYSTEM)
|
||||
# mingw-w64 dlls
|
||||
# (use msys2checkdeps.py to list required libraries / check for missing or unused libraries)
|
||||
file(GLOB MINGW_DLLS
|
||||
${MINGW_BIN}/libLerc.dll
|
||||
${MINGW_BIN}/libb2-1.dll
|
||||
${MINGW_BIN}/libbrotlicommon.dll
|
||||
${MINGW_BIN}/libbrotlidec.dll
|
||||
${MINGW_BIN}/libbrotlienc.dll
|
||||
${MINGW_BIN}/libbz2-1.dll
|
||||
${MINGW_BIN}/libbcg729.dll
|
||||
${MINGW_BIN}/libcares-2.dll
|
||||
${MINGW_BIN}/libcrypto-3-x64.dll
|
||||
${MINGW_BIN}/libdeflate.dll
|
||||
${MINGW_BIN}/libdouble-conversion.dll
|
||||
${MINGW_BIN}/libexpat-1.dll
|
||||
${MINGW_BIN}/libffi-8.dll
|
||||
${MINGW_BIN}/libfreetype-6.dll
|
||||
${MINGW_BIN}/libgcc_s_seh-1.dll
|
||||
${MINGW_BIN}/libgcrypt-20.dll
|
||||
${MINGW_BIN}/libglib-2.0-0.dll
|
||||
${MINGW_BIN}/libgmodule-2.0-0.dll
|
||||
${MINGW_BIN}/libgmp-10.dll
|
||||
${MINGW_BIN}/libgnutls-30.dll
|
||||
${MINGW_BIN}/libgpg-error-0.dll
|
||||
${MINGW_BIN}/libgraphite2.dll
|
||||
${MINGW_BIN}/libharfbuzz-0.dll
|
||||
${MINGW_BIN}/libhogweed-6.dll
|
||||
${MINGW_BIN}/libiconv-2.dll
|
||||
${MINGW_BIN}/libicudt72.dll
|
||||
${MINGW_BIN}/libicuin72.dll
|
||||
${MINGW_BIN}/libicuuc72.dll
|
||||
${MINGW_BIN}/libilbc.dll
|
||||
${MINGW_BIN}/libidn2-0.dll
|
||||
${MINGW_BIN}/libintl-8.dll
|
||||
${MINGW_BIN}/libjbig-0.dll
|
||||
${MINGW_BIN}/libjpeg-8.dll
|
||||
${MINGW_BIN}/liblz4.dll
|
||||
${MINGW_BIN}/liblzma-5.dll
|
||||
${MINGW_BIN}/libmd4c.dll
|
||||
${MINGW_BIN}/libmaxminddb.dll
|
||||
${MINGW_BIN}/libminizip-1.dll
|
||||
${MINGW_BIN}/libnettle-8.dll
|
||||
${MINGW_BIN}/libnghttp2-14.dll
|
||||
${MINGW_BIN}/libopus-0.dll
|
||||
${MINGW_BIN}/libp11-kit-0.dll
|
||||
${MINGW_BIN}/libpcre2-16-0.dll
|
||||
${MINGW_BIN}/libpcre2-8-0.dll
|
||||
${MINGW_BIN}/libpng16-16.dll
|
||||
${MINGW_BIN}/libsbc-1.dll
|
||||
${MINGW_BIN}/libsharpyuv-0.dll
|
||||
${MINGW_BIN}/libsmi-2.dll
|
||||
${MINGW_BIN}/libsnappy.dll
|
||||
${MINGW_BIN}/libspandsp-2.dll
|
||||
${MINGW_BIN}/libspeexdsp-1.dll
|
||||
${MINGW_BIN}/libssh.dll
|
||||
${MINGW_BIN}/libstdc++-6.dll
|
||||
${MINGW_BIN}/libtasn1-6.dll
|
||||
${MINGW_BIN}/libtiff-6.dll
|
||||
${MINGW_BIN}/libunistring-2.dll
|
||||
${MINGW_BIN}/libwebp-7.dll
|
||||
${MINGW_BIN}/libunistring-5.dll
|
||||
${MINGW_BIN}/libwinpthread-1.dll
|
||||
${MINGW_BIN}/libxml2-2.dll
|
||||
${MINGW_BIN}/libzstd.dll
|
||||
${MINGW_BIN}/lua51.dll
|
||||
${MINGW_BIN}/zlib1.dll
|
||||
)
|
||||
endif()
|
66
packaging/nsis/windeployqt-to-nsis.py
Normal file
66
packaging/nsis/windeployqt-to-nsis.py
Normal file
@ -0,0 +1,66 @@
|
||||
#!/bin/env python3
|
||||
|
||||
# windeployqt-to-nsh
|
||||
#
|
||||
# Windeployqt-to-nsh - Convert the output of windeployqt to an equivalent set of
|
||||
# NSIS "File" function calls.
|
||||
#
|
||||
# Rewritten in python from windeployqt-to-nsis.ps1, that has the following copyright:
|
||||
#
|
||||
# Copyright 2014 Gerald Combs <gerald@wireshark.org>
|
||||
#
|
||||
# Wireshark - Network traffic analyzer
|
||||
# By Gerald Combs <gerald@wireshark.org>
|
||||
# Copyright 1998 Gerald Combs
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
EXECUTABLE = sys.argv[1]
|
||||
OUTFILE = sys.argv[2]
|
||||
|
||||
# Qt version
|
||||
qmake_out = subprocess.run("qmake6 -query QT_VERSION", shell=True, check=True, capture_output=True, encoding="utf-8")
|
||||
qt_version = qmake_out.stdout.strip()
|
||||
|
||||
# XXX The powershell script asserts that the Qt version is greater than 5.3. We already require Qt6 to build the
|
||||
# installer using MSYS2 (currently not enforced).
|
||||
|
||||
# Windeploy output
|
||||
windeploy_command = [
|
||||
"windeployqt6.exe",
|
||||
"--no-compiler-runtime",
|
||||
"--no-translations",
|
||||
"--list", "mapping",
|
||||
EXECUTABLE
|
||||
]
|
||||
|
||||
out = subprocess.run(windeploy_command, shell=True, check=True, capture_output=True, encoding="utf-8")
|
||||
|
||||
with open(OUTFILE, 'w') as f:
|
||||
command_name = os.path.split(sys.argv[0])[1]
|
||||
header = """\
|
||||
#
|
||||
# Automatically generated by {}
|
||||
#
|
||||
# Qt version {}
|
||||
#""".format(command_name, qt_version)
|
||||
|
||||
print(header, file=f)
|
||||
|
||||
current_dir = ""
|
||||
for line in out.stdout.splitlines():
|
||||
path, relative = line.split(" ")
|
||||
rel_path = os.path.split(relative)
|
||||
if len(rel_path) > 1:
|
||||
base_dir = rel_path[0].strip('"')
|
||||
if base_dir != current_dir:
|
||||
set_out_path = 'SetOutPath "$INSTDIR\{}"'.format(base_dir)
|
||||
print(set_out_path, file=f)
|
||||
current_dir = base_dir
|
||||
file_path = 'File {}'.format(path)
|
||||
print(file_path, file=f)
|
||||
|
@ -521,6 +521,7 @@ File "${STAGING_DIR}\dumpcap.html"
|
||||
File "${STAGING_DIR}\extcap.html"
|
||||
File "${STAGING_DIR}\ipmap.html"
|
||||
|
||||
!ifdef USE_VCREDIST
|
||||
; C-runtime redistributable
|
||||
; vc_redist.x64.exe or vc_redist.x86.exe - copy and execute the redistributable installer
|
||||
File "${VCREDIST_DIR}\${VCREDIST_EXE}"
|
||||
@ -553,6 +554,7 @@ ${Switch} $0
|
||||
${EndSwitch}
|
||||
|
||||
Delete "$INSTDIR\${VCREDIST_EXE}"
|
||||
!endif
|
||||
|
||||
|
||||
; global config files - don't overwrite if already existing
|
||||
@ -973,13 +975,15 @@ WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\App Pa
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\App Paths\${PROGRAM_NAME_PATH}" "Path" '$INSTDIR'
|
||||
!include wireshark-qt-manifest.nsh
|
||||
|
||||
${!defineifexist} TRANSLATIONS_FOLDER "${QT_DIR}\translations"
|
||||
SetOutPath $INSTDIR
|
||||
!ifdef TRANSLATIONS_FOLDER
|
||||
; Starting from Qt 5.5, *.qm files are put in a translations subfolder
|
||||
File /r "${QT_DIR}\translations"
|
||||
!else
|
||||
File "${QT_DIR}\*.qm"
|
||||
!ifndef SKIP_QT_TRANSLATIONS
|
||||
${!defineifexist} TRANSLATIONS_FOLDER "${QT_DIR}\translations"
|
||||
SetOutPath $INSTDIR
|
||||
!ifdef TRANSLATIONS_FOLDER
|
||||
; Starting from Qt 5.5, *.qm files are put in a translations subfolder
|
||||
File /r "${QT_DIR}\translations"
|
||||
!else
|
||||
File "${QT_DIR}\*.qm"
|
||||
!endif
|
||||
!endif
|
||||
|
||||
; Is the Start Menu check box checked?
|
||||
@ -1162,11 +1166,13 @@ Section /o "Androiddump" SecAndroiddump
|
||||
SectionEnd
|
||||
!insertmacro CheckExtrasFlag "androiddump"
|
||||
|
||||
!ifdef HAVE_ETWDUMP
|
||||
Section "Etwdump" SecEtwdump
|
||||
;-------------------------------------------
|
||||
!insertmacro InstallExtcap "Etwdump"
|
||||
SectionEnd
|
||||
!insertmacro CheckExtrasFlag "Etwdump"
|
||||
!endif
|
||||
|
||||
Section /o "Randpktdump" SecRandpktdump
|
||||
;-------------------------------------------
|
||||
@ -1253,7 +1259,9 @@ SectionEnd
|
||||
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecExtcapGroup} "External Capture Interfaces"
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecAndroiddump} "Provide capture interfaces from Android devices."
|
||||
!ifdef HAVE_ETWDUMP
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecEtwdump} "Provide an interface to read Event Tracing for Windows (ETW) event trace (ETL)."
|
||||
!endif
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecRandpktdump} "Provide an interface to the random packet generator. (see also randpkt)"
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecSshdump} "Provide remote capture through SSH. (tcpdump, Cisco EPC, wifi)"
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SecUDPdump} "Provide capture interface to receive UDP packets streamed from network devices."
|
||||
|
@ -82,6 +82,7 @@ BASIC_LIST="base-devel \
|
||||
${PACKAGE_PREFIX}-qt6-base \
|
||||
${PACKAGE_PREFIX}-qt6-multimedia \
|
||||
${PACKAGE_PREFIX}-qt6-tools \
|
||||
${PACKAGE_PREFIX}-qt6-translations \
|
||||
${PACKAGE_PREFIX}-qt6-5compat \
|
||||
${PACKAGE_PREFIX}-sbc \
|
||||
${PACKAGE_PREFIX}-snappy \
|
||||
@ -97,7 +98,8 @@ ADDITIONAL_LIST="${PACKAGE_PREFIX}-asciidoctor \
|
||||
${PACKAGE_PREFIX}-docbook-xsl \
|
||||
${PACKAGE_PREFIX}-doxygen \
|
||||
${PACKAGE_PREFIX}-libxslt \
|
||||
${PACKAGE_PREFIX}-perl"
|
||||
${PACKAGE_PREFIX}-perl \
|
||||
${PACKAGE_PREFIX}-ntldd"
|
||||
|
||||
TESTDEPS_LIST="${PACKAGE_PREFIX}-python-pytest \
|
||||
${PACKAGE_PREFIX}-python-pytest-xdist"
|
||||
|
177
tools/msys2checkdeps.py
Normal file
177
tools/msys2checkdeps.py
Normal file
@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env python
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
# list or check dependencies for binary distributions based on MSYS2 (requires the package mingw-w64-ntldd)
|
||||
#
|
||||
# run './msys2checkdeps.py --help' for usage information
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
SYSTEMROOT = os.environ['SYSTEMROOT']
|
||||
|
||||
|
||||
class Dependency:
|
||||
def __init__(self):
|
||||
self.location = None
|
||||
self.dependents = set()
|
||||
|
||||
|
||||
def warning(msg):
|
||||
print("Warning: " + msg, file=sys.stderr)
|
||||
|
||||
|
||||
def error(msg):
|
||||
print("Error: " + msg, file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
|
||||
def call_ntldd(filename):
|
||||
try:
|
||||
output = subprocess.check_output(['ntldd', '-R', filename], stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as e:
|
||||
error("'ntldd' failed with '" + str(e) + "'")
|
||||
except WindowsError as e:
|
||||
error("Calling 'ntldd' failed with '" + str(e) + "' (have you installed 'mingw-w64-ntldd-git'?)")
|
||||
except Exception as e:
|
||||
error("Calling 'ntldd' failed with '" + str(e) + "'")
|
||||
return output.decode('utf-8')
|
||||
|
||||
|
||||
def get_dependencies(filename, deps):
|
||||
raw_list = call_ntldd(filename)
|
||||
|
||||
skip_indent = float('Inf')
|
||||
parents = {}
|
||||
parents[0] = os.path.basename(filename)
|
||||
for line in raw_list.splitlines():
|
||||
line = line[1:]
|
||||
indent = len(line) - len(line.lstrip())
|
||||
if indent > skip_indent:
|
||||
continue
|
||||
else:
|
||||
skip_indent = float('Inf')
|
||||
|
||||
# if the dependency is not found in the working directory ntldd tries to find it on the search path
|
||||
# which is indicated by the string '=>' followed by the determined location or 'not found'
|
||||
if ('=>' in line):
|
||||
(lib, location) = line.lstrip().split(' => ')
|
||||
if location == 'not found':
|
||||
location = None
|
||||
else:
|
||||
location = location.rsplit('(', 1)[0].strip()
|
||||
else:
|
||||
lib = line.rsplit('(', 1)[0].strip()
|
||||
location = os.getcwd()
|
||||
|
||||
parents[indent+1] = lib
|
||||
|
||||
# we don't care about Microsoft libraries and their dependencies
|
||||
if location and SYSTEMROOT in location:
|
||||
skip_indent = indent
|
||||
continue
|
||||
|
||||
if lib not in deps:
|
||||
deps[lib] = Dependency()
|
||||
deps[lib].location = location
|
||||
deps[lib].dependents.add(parents[indent])
|
||||
return deps
|
||||
|
||||
|
||||
def collect_dependencies(path):
|
||||
# collect dependencies
|
||||
# - each key in 'deps' will be the filename of a dependency
|
||||
# - the corresponding value is an instance of class Dependency (containing full path and dependents)
|
||||
deps = {}
|
||||
if os.path.isfile(path):
|
||||
deps = get_dependencies(path, deps)
|
||||
elif os.path.isdir(path):
|
||||
extensions = ['.exe', '.pyd', '.dll']
|
||||
exclusions = ['distutils/command/wininst'] # python
|
||||
for base, dirs, files in os.walk(path):
|
||||
for f in files:
|
||||
filepath = os.path.join(base, f)
|
||||
(_, ext) = os.path.splitext(f)
|
||||
if (ext.lower() not in extensions) or any(exclusion in filepath for exclusion in exclusions):
|
||||
continue
|
||||
deps = get_dependencies(filepath, deps)
|
||||
return deps
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
modes = ['list', 'list-compact', 'check', 'check-missing', 'check-unused']
|
||||
|
||||
# parse arguments from command line
|
||||
parser = argparse.ArgumentParser(description="List or check dependencies for binary distributions based on MSYS2.\n"
|
||||
"(requires the package 'mingw-w64-ntldd')",
|
||||
formatter_class=argparse.RawTextHelpFormatter)
|
||||
parser.add_argument('mode', metavar="MODE", choices=modes,
|
||||
help="One of the following:\n"
|
||||
" list - list dependencies in human-readable form\n"
|
||||
" with full path and list of dependents\n"
|
||||
" list-compact - list dependencies in compact form (as a plain list of filenames)\n"
|
||||
" check - check for missing or unused dependencies (see below for details)\n"
|
||||
" check-missing - check if all required dependencies are present in PATH\n"
|
||||
" exits with error code 2 if missing dependencies are found\n"
|
||||
" and prints the list to stderr\n"
|
||||
" check-unused - check if any of the libraries in the root of PATH are unused\n"
|
||||
" and prints the list to stderr")
|
||||
parser.add_argument('path', metavar='PATH',
|
||||
help="full or relative path to a single file or a directory to work on\n"
|
||||
"(directories will be checked recursively)")
|
||||
parser.add_argument('-w', '--working-directory', metavar="DIR",
|
||||
help="Use custom working directory (instead of 'dirname PATH')")
|
||||
args = parser.parse_args()
|
||||
|
||||
# check if path exists
|
||||
args.path = os.path.abspath(args.path)
|
||||
if not os.path.exists(args.path):
|
||||
error("Can't find file/folder '" + args.path + "'")
|
||||
|
||||
# get root and set it as working directory (unless one is explicitly specified)
|
||||
if args.working_directory:
|
||||
root = os.path.abspath(args.working_directory)
|
||||
elif os.path.isdir(args.path):
|
||||
root = args.path
|
||||
elif os.path.isfile(args.path):
|
||||
root = os.path.dirname(args.path)
|
||||
os.chdir(root)
|
||||
|
||||
# get dependencies for path recursively
|
||||
deps = collect_dependencies(args.path)
|
||||
|
||||
# print output / prepare exit code
|
||||
exit_code = 0
|
||||
for dep in sorted(deps):
|
||||
location = deps[dep].location
|
||||
dependents = deps[dep].dependents
|
||||
|
||||
if args.mode == 'list':
|
||||
if (location is None):
|
||||
location = '---MISSING---'
|
||||
print(dep + " - " + location + " (" + ", ".join(dependents) + ")")
|
||||
elif args.mode == 'list-compact':
|
||||
print(dep)
|
||||
elif args.mode in ['check', 'check-missing']:
|
||||
if ((location is None) or (root not in os.path.abspath(location))):
|
||||
warning("Missing dependency " + dep + " (" + ", ".join(dependents) + ")")
|
||||
exit_code = 2
|
||||
|
||||
# check for unused libraries
|
||||
if args.mode in ['check', 'check-unused']:
|
||||
installed_libs = [file for file in os.listdir(root) if file.endswith(".dll")]
|
||||
deps_lower = [dep.lower() for dep in deps]
|
||||
top_level_libs = [lib for lib in installed_libs if lib.lower() not in deps_lower]
|
||||
for top_level_lib in top_level_libs:
|
||||
warning("Unused dependency " + top_level_lib)
|
||||
|
||||
exit(exit_code)
|
Loading…
x
Reference in New Issue
Block a user