3 # Wireshark - Network traffic analyzer
4 # By Gerald Combs <gerald@wireshark.org>
5 # Copyright 1998 Gerald Combs
7 # SPDX-License-Identifier: GPL-2.0-or-later
10 # We should use CPack to generate the NSIS package. Even better,
11 # we should use CPack to create a .msi using WiX.
13 set(WIRESHARK_NSIS_GENERATED_FILES
14 ${CMAKE_CURRENT_BINARY_DIR}/wireshark-manifest.nsh
15 ${CMAKE_CURRENT_BINARY_DIR}/wireshark-config.nsh
17 if(NOT SKIP_NSIS_QT_DLLS)
18 list(APPEND WIRESHARK_NSIS_GENERATED_FILES ${CMAKE_CURRENT_BINARY_DIR}/wireshark-qt-manifest.nsh)
20 set(WIRESHARK_NSIS_GENERATED_FILES ${WIRESHARK_NSIS_GENERATED_FILES} PARENT_SCOPE)
22 set(WIRESHARK_NSIS_FILES
23 ${CMAKE_CURRENT_SOURCE_DIR}/wireshark.nsi
24 ${CMAKE_CURRENT_SOURCE_DIR}/wireshark-common.nsh
25 ${CMAKE_CURRENT_SOURCE_DIR}/servicelib.nsh
26 ${CMAKE_CURRENT_SOURCE_DIR}/NpcapPage.ini
27 ${CMAKE_CURRENT_SOURCE_DIR}/USBPcapPage.ini
28 ${WIRESHARK_NSIS_GENERATED_FILES}
32 set(STRATOSHARK_NSIS_GENERATED_FILES
33 ${CMAKE_CURRENT_BINARY_DIR}/stratoshark-manifest.nsh
34 ${CMAKE_CURRENT_BINARY_DIR}/stratoshark-config.nsh
35 ${CMAKE_CURRENT_BINARY_DIR}/stratoshark-qt-manifest.nsh
37 set(STRATOSHARK_NSIS_GENERATED_FILES ${STRATOSHARK_NSIS_GENERATED_FILES} PARENT_SCOPE)
39 set(STRATOSHARK_NSIS_FILES
41 stratoshark-common.nsh
45 ${STRATOSHARK_NSIS_GENERATED_FILES}
49 # Variables required for config.nsh
50 set(PROGRAM_NAME ${CMAKE_PROJECT_NAME})
51 file(TO_NATIVE_PATH "${CMAKE_SOURCE_DIR}" TOP_SRC_DIR)
52 # STAGING_DIR depends on the build configuration so we pass it
53 # on the command line below.
54 file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/doc" DOC_DIR)
55 set (MMDBRESOLVE_EXE ${MAXMINDDB_FOUND})
58 # - Sync the various version names between CMake and NSIS.
59 # - Set CMakeLists.txt version strings in tools/make-version.py
60 # - Add a VERSION_EXTRA cmake option
61 set (PRODUCT_VERSION ${PROJECT_MAJOR_VERSION}.${PROJECT_MINOR_VERSION}.${PROJECT_PATCH_VERSION}.${PROJECT_BUILD_VERSION})
62 set (STRATOSHARK_PRODUCT_VERSION ${STRATOSHARK_MAJOR_VERSION}.${STRATOSHARK_MINOR_VERSION}.${STRATOSHARK_PATCH_VERSION}.${STRATOSHARK_BUILD_VERSION})
64 if((BUILD_wireshark OR BUILD_stratoshark) AND QT_FOUND)
65 set (QT_DIR "\${STAGING_DIR}")
68 # Look for the Visual C++ Redistributable packages in the following locations:
70 # - _PROJECT_LIB_DIR/vcredist_MSVCxx
72 # - %VCINSTALLDIR%/redist/1033 (<= Visual Studio 2015)
73 # - %VCINSTALLDIR%/Redist/MSVC/* (>= Visual Studio 2017)
74 # MSVC_VERSION (_MSC_VER) = Visual Studio Version / MSVC Toolset Version
75 # 1900 = VS2015 14.0 / 14.00
76 # 1910 = VS2017 15.1, 15.2 / 14.10
77 # 1911 = VS2017 15.3, 15.4 / 14.11
78 # 1912 = VS2017 15.5 / 14.12
79 # 1913 = VS2017 15.6 / 14.13
80 # 1914 = VS2017 15.7 / 14.14
81 if(MSVC_VERSION GREATER_EQUAL 1930)
82 set(_ws_vcredist_subdir "vcredist_MSVC2022")
83 elseif(MSVC_VERSION GREATER_EQUAL 1920)
84 set(_ws_vcredist_subdir "vcredist_MSVC2019")
85 set(_msvs_version 15.0) # Doesn't appear to be set
86 elseif(MSVC_VERSION GREATER_EQUAL 1910)
87 set(_ws_vcredist_subdir "vcredist_MSVC2017")
88 set(_msvs_version 15.0)
89 elseif(MSVC_VERSION GREATER_EQUAL 1900)
90 set(_ws_vcredist_subdir "vcredist_MSVC2015")
91 set(_ms_vcredist_subdir "redist/1033")
92 set(_msvs_version 14.0)
95 # Try to find the Redist folder in VCINSTALLDIR which is set by vcvarsall.bat.
96 # If it is not set, query it within the registry. VS2015 looks for the "VC7" key
97 # in two locations (four if you count HKCU instead of HKLM). However, VS2017
98 # does not use "VC7" (it sets a directory relative to vsdevcmd_start.bat). As
99 # both versions do set "VS7", use that instead.
100 find_path(VCINSTALLDIR Redist PATHS
102 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7;${_msvs_version}]\\VC"
103 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\VisualStudio\\SxS\\VS7;${_msvs_version}]\\VC"
106 file(TO_NATIVE_PATH "${VCINSTALLDIR}" VCINSTALLDIR_NATIVE)
107 message(STATUS "Using VCINSTALLDIR: ${VCINSTALLDIR_NATIVE}")
109 # Visual Studio Community 2017 version 15.7.5 uses VCRT 14.14.26405, but an
110 # earlier version used 14.10.25008. Let's just glob for the right value.
111 if(MSVC_VERSION GREATER_EQUAL 1910 AND VCINSTALLDIR)
112 file(GLOB _ms_vcredist_subdir RELATIVE "${VCINSTALLDIR}"
113 "${VCINSTALLDIR}/Redist/MSVC/14.*.*")
116 find_program(_vcredist
118 "vc_redist.${WIRESHARK_TARGET_PLATFORM}.exe" # Visual Studio 2022 and later
119 "vcredist_${WIRESHARK_TARGET_PLATFORM}.exe" # Visual Studio 2019 and earlier
120 PATHS "${_PROJECT_LIB_DIR}" $ENV{VCToolsRedistDir} "${VCINSTALLDIR}"
121 PATH_SUFFIXES ${_ws_vcredist_subdir} ${_ms_vcredist_subdir}
125 file(TO_NATIVE_PATH "${_vcredist}" _vcredist)
126 message(STATUS "Using ${_vcredist} for the NSIS installer.")
127 get_filename_component(VCREDIST_DIR ${_vcredist} DIRECTORY)
128 get_filename_component(VCREDIST_EXE ${_vcredist} NAME)
132 # Ideally we would generate this at compile time using a separate cmake
133 # module, e.g. cmake/modules/configure_nsis_file.cmake. However we would
134 # have to figure out a clean way to pass in the variables above.
135 file(READ "${CMAKE_CURRENT_SOURCE_DIR}/wireshark-config.nsh.in" _config_nsh_contents)
136 string(CONFIGURE "${_config_nsh_contents}" _config_nsh_contents)
137 string(REPLACE "#define" "!define" _config_nsh_contents "${_config_nsh_contents}")
138 string(REPLACE "#undef" "!undef" _config_nsh_contents "${_config_nsh_contents}")
139 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/wireshark-config.nsh" "${_config_nsh_contents}")
141 # wireshark-manifest.nsh. Can be created at configure time.
142 set(_all_manifest "${CMAKE_CURRENT_BINARY_DIR}/wireshark-manifest.nsh")
143 set(_all_manifest_contents "# Files required for all sections. Generated by CMake.\n")
145 set(_all_manifest_contents "${_all_manifest_contents}!ifdef BUNDLE_DEBUG_DLLS\n")
146 foreach(_dll ${GLIB2_DLLS_DEBUG})
147 set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
149 set(_all_manifest_contents "${_all_manifest_contents}!else\n")
150 foreach(_dll ${GLIB2_DLLS_RELEASE})
151 set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
153 set(_all_manifest_contents "${_all_manifest_contents}!endif\n")
154 foreach(_dll ${AMRNB_DLL} ${CARES_DLL} ${PCRE2_RELEASE_DLL} ${GCRYPT_DLLS}
155 ${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLLS} ${LUA_DLL}
156 ${LZ4_DLL} ${MINIZIP_DLL} ${MINIZIPNG_DLLS} ${NGHTTP2_DLL} ${NGHTTP3_DLL} ${SBC_DLL} ${SMI_DLL}
157 ${SNAPPY_DLL} ${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLLS} ${WINSPARKLE_DLL}
158 ${ZLIB_DLL} ${ZLIBNG_DLL} ${BROTLI_DLLS} ${ZSTD_DLL} ${ILBC_DLL} ${OPUS_DLL}
160 # Needed for mmdbresolve
163 set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
166 include(${CMAKE_CURRENT_SOURCE_DIR}/InstallMSYS2.cmake)
167 foreach(_dll ${MINGW_DLLS})
168 file(TO_NATIVE_PATH ${_dll} _path)
169 set(_all_manifest_contents "${_all_manifest_contents}File \"${_path}\"\n")
172 include(${CMAKE_CURRENT_SOURCE_DIR}/InstallMinGW.cmake)
173 foreach(_dll ${MINGW_DLLS})
174 file(TO_NATIVE_PATH ${_dll} _path)
175 set(_all_manifest_contents "${_all_manifest_contents}File \"${_path}\"\n")
178 file(WRITE "${_all_manifest}" "${_all_manifest_contents}")
181 if (BUILD_stratoshark)
182 # Ideally we would generate this at compile time using a separate cmake
183 # module, e.g. cmake/modules/configure_nsis_file.cmake. However we would
184 # have to figure out a clean way to pass in the variables above.
185 file(READ "${CMAKE_CURRENT_SOURCE_DIR}/stratoshark-config.nsh.in" _config_nsh_contents)
186 string(CONFIGURE "${_config_nsh_contents}" _config_nsh_contents)
187 string(REPLACE "#define" "!define" _config_nsh_contents "${_config_nsh_contents}")
188 string(REPLACE "#undef" "!undef" _config_nsh_contents "${_config_nsh_contents}")
189 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/stratoshark-config.nsh" "${_config_nsh_contents}")
191 # stratoshark-manifest.nsh. Can be created at configure time.
192 set(_all_manifest "${CMAKE_CURRENT_BINARY_DIR}/stratoshark-manifest.nsh")
193 set(_all_manifest_contents "# Files required for all sections. Generated by CMake.\n")
194 set(_all_manifest_contents "${_all_manifest_contents}!ifdef BUNDLE_DEBUG_DLLS\n")
195 foreach(_dll ${GLIB2_DLLS_DEBUG})
196 set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
198 set(_all_manifest_contents "${_all_manifest_contents}!else\n")
199 foreach(_dll ${GLIB2_DLLS_RELEASE})
200 set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
202 set(_all_manifest_contents "${_all_manifest_contents}!endif\n")
203 foreach(_dll ${AMRNB_DLL} ${CARES_DLL} ${PCRE2_RELEASE_DLL} ${GCRYPT_DLLS}
204 ${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLLS} ${LUA_DLL}
205 ${LZ4_DLL} ${MINIZIP_DLL} ${MINIZIPNG_DLLS} ${NGHTTP2_DLL} ${NGHTTP3_DLL} ${SBC_DLL} ${SMI_DLL}
206 ${SNAPPY_DLL} ${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLLS} ${WINSPARKLE_DLL}
207 ${ZLIB_DLL} ${ZLIBNG_DLL} ${BROTLI_DLLS} ${ZSTD_DLL} ${ILBC_DLL} ${OPUS_DLL}
209 # Needed for mmdbresolve
212 set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
214 file(WRITE "${_all_manifest}" "${_all_manifest_contents}")
217 file(TO_NATIVE_PATH "${DATAFILE_DIR}" _staging_dir)
218 file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}" _outfile_dir)
219 file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}" _nsis_include_dir)
221 # Variables we can't set via config.nsh.
223 -DSTAGING_DIR=${_staging_dir}
224 -DOUTFILE_DIR=${_outfile_dir}
225 -DNSIS_INCLUDE_DIR=${_nsis_include_dir}
230 macro( ADD_NSIS_PACKAGE_TARGETS )
231 set (_nsis_source_dir ${CMAKE_SOURCE_DIR}/packaging/nsis )
232 set (_nsis_binary_dir ${CMAKE_BINARY_DIR}/packaging/nsis )
234 # XXX - if we're not building Wireshark, we can't build the
235 # manifest below. On the other hand, if we're not building
236 # Wireshark, we have no need to include Qt in the installer,
237 # so it's not clear we need this manifest.
239 # This should probably be fixed, so that people can produce
240 # command-line-only installer packages.
242 # wireshark-qt-manifest.nsh. Created using Wireshark.exe.
243 if(NOT SKIP_NSIS_QT_DLLS)
245 add_custom_command(OUTPUT ${_nsis_binary_dir}/wireshark-qt-manifest.nsh
246 COMMAND set "PATH=${QT_BIN_PATH};%PATH%"
247 COMMAND ${POWERSHELL_COMMAND} "${_nsis_source_dir}/windeployqt-to-nsis.ps1"
248 -Executable $<TARGET_FILE:wireshark>
249 -FilePath ${_nsis_binary_dir}/wireshark-qt-manifest.nsh
250 $<$<CONFIG:Debug>:-DebugConfig>
252 "${_nsis_source_dir}/windeployqt-to-nsis.ps1"
253 $<TARGET_FILE:wireshark>
256 add_custom_command(OUTPUT ${_nsis_binary_dir}/wireshark-qt-manifest.nsh
257 COMMAND ${Python3_EXECUTABLE} "${_nsis_source_dir}/windeployqt-to-nsis.py"
258 --executable $<TARGET_FILE:wireshark>
259 ${_nsis_binary_dir}/wireshark-qt-manifest.nsh
260 #$<$<CONFIG:Debug>:-DebugConfig>
262 "${_nsis_source_dir}/windeployqt-to-nsis.py"
263 $<TARGET_FILE:wireshark>
265 elseif(MINGW AND CMAKE_CROSSCOMPILING)
266 add_custom_command(OUTPUT ${_nsis_binary_dir}/wireshark-qt-manifest.nsh
267 COMMAND ${Python3_EXECUTABLE} "${_nsis_source_dir}/windeployqt-to-nsis.py"
268 --sysroot "${MINGW_SYSROOT}"
269 --mapping "${_nsis_source_dir}/mingw64-qt-mapping.txt"
270 ${_nsis_binary_dir}/wireshark-qt-manifest.nsh
271 #$<$<CONFIG:Debug>:-DebugConfig>
273 "${_nsis_source_dir}/windeployqt-to-nsis.py"
274 "${_nsis_source_dir}/mingw64-qt-mapping.txt"
277 message(FATAL_ERROR "Unknown Qt deployment method")
281 # Build NSIS package dependencies. We build the package in
282 # two stages so that wireshark_nsis below doesn't trigger
283 # any dependencies that might clobber any signed executables.
284 add_custom_target(wireshark_nsis_prep
286 ${WIRESHARK_NSIS_FILES}
291 set_target_properties(wireshark_nsis_prep PROPERTIES
293 EXCLUDE_FROM_DEFAULT_BUILD True
296 # Make sure required blobs are available
297 FetchContent_MakeAvailable(Npcap USBPcap)
299 # Dump the installer into
300 # ${CMAKE_CURRENT_SOURCE_DIR}/packaging/nsis
301 # Note that executables and DLLs *must* be built separately
302 add_custom_target(wireshark_nsis
303 COMMAND ${MAKENSIS_EXECUTABLE} ${NSIS_OPTIONS}
304 $<$<CONFIG:Debug>:-DBUNDLE_DEBUG_DLLS>
305 $<$<BOOL:${MSVC}>:-DUSE_VCREDIST>
307 WORKING_DIRECTORY ${_nsis_source_dir}
309 set_target_properties(wireshark_nsis PROPERTIES
311 EXCLUDE_FROM_DEFAULT_BUILD True
315 if(BUILD_stratoshark)
316 # stratoshark-qt-manifest.nsh. Created using Wireshark.exe.
317 add_custom_command(OUTPUT ${_nsis_binary_dir}/stratoshark-qt-manifest.nsh
318 COMMAND set "PATH=${QT_BIN_PATH};%PATH%"
319 COMMAND ${POWERSHELL_COMMAND} "${_nsis_source_dir}/windeployqt-to-nsis.ps1"
320 -Executable $<TARGET_FILE:stratoshark>
321 -FilePath ${_nsis_binary_dir}/stratoshark-qt-manifest.nsh
322 $<$<CONFIG:Debug>:-DebugConfig>
323 DEPENDS "${_nsis_source_dir}/windeployqt-to-nsis.ps1"
326 # Build NSIS package dependencies. We build the package in
327 # two stages so that stratoshark_nsis below doesn't trigger
328 # any dependencies that might clobber any signed executables.
329 add_custom_target(stratoshark_nsis_prep
331 ${STRATOSHARK_NSIS_FILES}
334 ${DATAFILE_DIR}/uninstall-stratoshark.exe
336 set_target_properties(stratoshark_nsis_prep PROPERTIES
338 EXCLUDE_FROM_DEFAULT_BUILD True
341 # Dump the installer into
342 # ${CMAKE_CURRENT_SOURCE_DIR}/packaging/nsis
343 # Note that executables and DLLs *must* be built separately
344 add_custom_target(stratoshark_nsis
345 COMMAND ${MAKENSIS_EXECUTABLE} ${NSIS_OPTIONS}
346 $<$<CONFIG:Debug>:-DBUNDLE_DEBUG_DLLS>
348 WORKING_DIRECTORY ${_nsis_source_dir}
350 set_target_properties(stratoshark_nsis PROPERTIES
352 EXCLUDE_FROM_DEFAULT_BUILD True
355 endmacro( ADD_NSIS_PACKAGE_TARGETS )
358 ${DATAFILE_DIR}/uninstall-wireshark.exe
359 wireshark-${VERSION}-${WIRESHARK_TARGET_PLATFORM}.exe
361 wireshark-manifest.nsh
362 wireshark-qt-manifest.nsh
363 ${DATAFILE_DIR}/uninstall-stratoshark.exe
364 stratoshark-${VERSION}-${WIRESHARK_TARGET_PLATFORM}.exe
365 stratoshark-config.nsh
366 stratoshark-manifest.nsh
367 stratoshark-qt-manifest.nsh