diff --git a/CMakeLists.txt b/CMakeLists.txt index 2526ed5656..af1b52a054 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,20 @@ if(POLICY CMP0083) endif() if(WIN32) + if(DEFINED ENV{MSYSTEM}) + set(_msystem $ENV{MSYSTEM}) + set(_repository False) + message(STATUS "Using MSYS2 with MSYSTEM=${_msystem}") + else() + set(_msystem False) + set(_repository True) + message(STATUS "Using 3rd party repository") + endif() + set(USE_MSYSTEM ${_msystem} CACHE INTERNAL "Use MSYS2 subsystem") + set(USE_REPOSITORY ${_repository} CACHE INTERNAL "Use Wireshark 3rd Party Repository") +endif() + +if(WIN32 AND NOT USE_MSYSTEM) set(_project_name Wireshark) set(_log_project_name Logray) else() @@ -101,27 +115,11 @@ endif() # %WIRESHARK_TARGET_PLATFORM%. if(WIN32) - # Are we using MSYS2? If we are we don't use our own third party - # libraries. - if(DEFINED ENV{MSYSTEM}) - set(_msystem $ENV{MSYSTEM}) - set(_repository False) - message(STATUS "Using MSYS2 with MSYSTEM=${_msystem}") - else() - set(_msystem False) - set(_repository True) - message(STATUS "Using 3rd party repository") - endif() - set(USE_MSYSTEM ${_msystem} CACHE INTERNAL "Use MSYS2 subsystem") - set(USE_REPOSITORY ${_repository} CACHE INTERNAL "Use Wireshark 3rd Party Repository") - if(DEFINED ENV{WIRESHARK_TARGET_PLATFORM}) string(TOLOWER $ENV{WIRESHARK_TARGET_PLATFORM} _target_platform) set(WIRESHARK_TARGET_PLATFORM ${_target_platform}) elseif(USE_MSYSTEM MATCHES "MINGW64") set(WIRESHARK_TARGET_PLATFORM win64) - elseif(USE_MSYSTEM MATCHES "MINGW32") - set(WIRESHARK_TARGET_PLATFORM win32) elseif(USE_MSYSTEM) message(WARNING "Building for MSYSTEM=${USE_MSYSTEM} is not officially supported") elseif(CMAKE_CL_64 OR CMAKE_GENERATOR MATCHES "Win64") @@ -226,7 +224,7 @@ endif() # # Defines CMAKE_INSTALL_BINDIR, CMAKE_INSTALL_DATADIR, etc ... -if(WIN32) +if(WIN32 AND NOT USE_MSYSTEM) # Override some values on Windows, to match the existing # convention of installing everything to a single root folder. set(CMAKE_INSTALL_BINDIR ".") @@ -315,7 +313,7 @@ include(CheckSymbolExists) # Studio has had supported them since Visual Studio 2005/MSVCR80, # and we require newer versions, so we know we have them. # -if(NOT WIN32) +if(NOT MSVC) include(FindLFS) if(LFS_FOUND) # @@ -1166,7 +1164,7 @@ if(BUILD_wireshark OR BUILD_logray) if(DEFINED ENV{WIRESHARK_QT5_PREFIX_PATH}) list(APPEND CMAKE_PREFIX_PATH $ENV{WIRESHARK_QT5_PREFIX_PATH}) # XXX We used to recommend setting QT5_BASE_DIR. Remove after the 4.0 branch is created. - elseif(WIN32 AND DEFINED ENV{QT5_BASE_DIR}) + elseif(WIN32 AND NOT USE_MSYSTEM AND DEFINED ENV{QT5_BASE_DIR}) message(WARNING "Support for QT5_BASE_DIR will be removed in a future release.") set(QT5_BASE_PATH "$ENV{QT5_BASE_DIR}") set(CMAKE_PREFIX_PATH "${QT5_BASE_PATH}") @@ -1342,7 +1340,7 @@ if(GNUTLS_FOUND) # Check that the support is present in case GnuTLS was compiled # --without-p11-kit as macos-setup.sh did until December 2020. cmake_push_check_state() - if(WIN32) + if(WIN32 AND NOT MINGW) set(CMAKE_REQUIRED_DEFINITIONS -Dssize_t=int) endif() set(CMAKE_REQUIRED_INCLUDES ${GNUTLS_INCLUDE_DIRS}) @@ -1374,13 +1372,8 @@ 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) - if (USE_qt6 AND USE_MSYSTEM) - set(_windeployqt_name "windeployqt-qt6") - else() - set(_windeployqt_name "windeployqt") - endif() - find_program(QT_WINDEPLOYQT_EXECUTABLE ${_windeployqt_name} + if(WIN32 AND NOT USE_MSYSTEM) + find_program(QT_WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${QT_BIN_PATH}" DOC "Path to the windeployqt utility." ) @@ -1483,11 +1476,12 @@ include( UseCheckAPI ) # 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) +if(WIN32 AND NOT USE_MSYSTEM) set(EXTCAP_INSTALL_LIBDIR "extcap" CACHE INTERNAL "The extcap dir") -else () +else() set(EXTCAP_INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/extcap" CACHE INTERNAL "The extcap dir") endif() +set(EXTCAP_INSTALL_FULL_LIBDIR "${CMAKE_INSTALL_PREFIX}/${EXTCAP_INSTALL_LIBDIR}") if(APPLE) # @@ -1508,11 +1502,12 @@ else() endif() # Directory where plugins and Lua dissectors can be found. -if(WIN32) +if(WIN32 AND NOT USE_MSYSTEM) set(PLUGIN_INSTALL_LIBDIR "plugins" CACHE INTERNAL "The plugin dir") else() set(PLUGIN_INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/plugins" CACHE INTERNAL "The plugin dir") endif() +set(PLUGIN_INSTALL_FULL_LIBDIR "${CMAKE_INSTALL_PREFIX}/${PLUGIN_INSTALL_LIBDIR}") set(PLUGIN_INSTALL_VERSION_LIBDIR "${PLUGIN_INSTALL_LIBDIR}/${PLUGIN_PATH_ID}") set(PLUGIN_VERSION_DIR "plugins/${PLUGIN_PATH_ID}") @@ -1668,7 +1663,7 @@ if(ENABLE_APPLICATION_BUNDLE) # Xcode set(_logray_plugin_dir "${CMAKE_BINARY_DIR}/run/$/Logray.app/Contents/PlugIns/logray/${PLUGIN_PATH_ID}") endif() -elseif(WIN32 AND NOT CMAKE_CFG_INTDIR STREQUAL ".") +elseif(MSVC AND NOT CMAKE_CFG_INTDIR STREQUAL ".") set(_plugin_dir "${CMAKE_BINARY_DIR}/run/$/${PLUGIN_VERSION_DIR}") set(_logray_plugin_dir ${_plugin_dir}) else() @@ -2215,7 +2210,7 @@ endif() # List of extra dependencies for the "copy_data_files" target set(copy_data_files_depends) -if(WIN32) +if(WIN32 AND NOT USE_MSYSTEM) 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. @@ -2610,7 +2605,7 @@ if(BUILD_wireshark AND QT_FOUND) ) add_executable(wireshark WIN32 MACOSX_BUNDLE ${wireshark_FILES} ${EXTRA_WIRESHARK_BUNDLE_FILES}) - if(WIN32) + if(MSVC) set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT wireshark) endif() set(PROGLIST ${PROGLIST} wireshark) @@ -2625,7 +2620,9 @@ if(BUILD_wireshark AND QT_FOUND) if(MSVC) set_target_properties(wireshark PROPERTIES LINK_FLAGS_DEBUG "${WS_MSVC_DEBUG_LINK_FLAGS}") endif() - if(ENABLE_APPLICATION_BUNDLE OR WIN32) + if (USE_MSYSTEM) + set_target_properties(wireshark PROPERTIES OUTPUT_NAME wireshark) + elseif(ENABLE_APPLICATION_BUNDLE OR WIN32) set_target_properties(wireshark PROPERTIES OUTPUT_NAME Wireshark) endif() @@ -3210,7 +3207,7 @@ if(BUILD_dcerpcidl2wrs) install(TARGETS idl2wrs RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() -if (WIN32) +if(MSVC) find_package( MSVC_REDIST ) # Must come after executable targets are defined. @@ -3728,7 +3725,7 @@ if(CLEAN_C_FILES) # the INCLUDE environment variable). # This should apparently be handled for us via CMAKE_RC_FLAG_REGEX # in CMakeRCInformation.cmake but that doesn't appear to work. - if(WIN32) + if(MSVC) list(FILTER CLEAN_C_FILES EXCLUDE REGEX ".*\\.rc") endif() @@ -3771,7 +3768,7 @@ install(FILES ${SHARK_PUBLIC_HEADERS} ) # Install icons and other desktop files for Freedesktop.org-compliant desktops. -if((BUILD_wireshark AND QT_FOUND) AND NOT (WIN32 OR APPLE)) +if(BUILD_wireshark AND QT_FOUND AND NOT APPLE AND (NOT WIN32 OR USE_MSYSTEM)) install(FILES resources/freedesktop/org.wireshark.Wireshark-mime.xml DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/mime/packages" RENAME org.wireshark.Wireshark.xml @@ -3821,7 +3818,7 @@ install( PATTERN "Makefile.*" EXCLUDE ) -if(WIN32) +if(WIN32 AND NOT USE_MSYSTEM) # Note: CMake export mechanism misbehaves with a '.' in the # path (incorrect relative path computation). set(WIRESHARK_INSTALL_CMAKEDIR "cmake") @@ -3880,7 +3877,7 @@ if (DOXYGEN_EXECUTABLE) COMMAND ${DOXYGEN_EXECUTABLE} doxygen.cfg ) - if (WIN32) + if(WIN32 AND NOT USE_MSYSTEM) add_custom_target(wsar_html_perms DEPENDS wsar_html) else() add_custom_target(wsar_html_perms @@ -4012,7 +4009,7 @@ else (GIT_EXECUTABLE) endif (GIT_EXECUTABLE) set_target_properties(gen-authors PROPERTIES FOLDER "Documentation") -if (WIN32) +if(WIN32 AND NOT USE_MSYSTEM) file (TO_NATIVE_PATH ${CMAKE_SOURCE_DIR}/tools/Get-HardenFlags.ps1 _win_harden_flags) add_custom_target(hardening-check COMMAND ${POWERSHELL_COMMAND} "${_win_harden_flags}" "${_dll_output_dir_win}" @@ -4020,7 +4017,7 @@ if (WIN32) COMMENT "Checking binaries for security features" ) set_target_properties(hardening-check PROPERTIES FOLDER "Tests") -else () +else() find_program(HARDENING_CHECK_EXECUTABLE hardening-check DOC "Path to the hardening-check utility." ) diff --git a/ui/qt/main.cpp b/ui/qt/main.cpp index 68b53ffa7e..aba9f051c5 100644 --- a/ui/qt/main.cpp +++ b/ui/qt/main.cpp @@ -342,7 +342,7 @@ check_and_warn_user_startup() } #endif -#ifdef _WIN32 +#if defined(_WIN32) && !defined(__MINGW64__) // Try to avoid library search path collisions. QCoreApplication will // search QT_INSTALL_PREFIX/plugins for platform DLLs before searching // the application directory. If @@ -360,6 +360,9 @@ check_and_warn_user_startup() // same path on the build machine. At any rate, loading DLLs from paths // you don't control is ill-advised. We work around this by removing every // path except our application directory. +// +// NOTE: This does not apply to MinGW-w64 using MSYS2. In that case we use +// the system's Qt plugins with the default search paths. static inline void win32_reset_library_path(void) @@ -647,7 +650,7 @@ int main(int argc, char *qt_argv[]) commandline_early_options(argc, argv); -#ifdef _WIN32 +#if defined(_WIN32) && !defined(__MINGW64__) win32_reset_library_path(); #endif diff --git a/wsutil/CMakeLists.txt b/wsutil/CMakeLists.txt index 61786a1ccb..420ae5c179 100644 --- a/wsutil/CMakeLists.txt +++ b/wsutil/CMakeLists.txt @@ -7,9 +7,24 @@ # SPDX-License-Identifier: GPL-2.0-or-later # -add_definitions(-DPLUGIN_DIR=\"${CMAKE_INSTALL_PREFIX}/${PLUGIN_INSTALL_LIBDIR}\") -add_definitions(-DEXTCAP_DIR=\"${CMAKE_INSTALL_PREFIX}/${EXTCAP_INSTALL_LIBDIR}\") -add_definitions(-DDATA_DIR=\"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}\") +if(UNIX OR USE_MSYSTEM) + if(USE_MSYSTEM) + # Windows binaries are relocatable and do not need a prefix. + file(TO_NATIVE_PATH "${PLUGIN_INSTALL_LIBDIR}" _dir) + string(REPLACE "\\" "\\\\" _plugin_dir "${_dir}") + file(TO_NATIVE_PATH "${EXTCAP_INSTALL_LIBDIR}" _dir) + string(REPLACE "\\" "\\\\" _extcap_dir "${_dir}") + file(TO_NATIVE_PATH "${CMAKE_INSTALL_DATADIR}" _dir) + string(REPLACE "\\" "\\\\" _data_dir "${_dir}") + elseif(UNIX) + set(_plugin_dir "${PLUGIN_INSTALL_FULL_LIBDIR}") + set(_extcap_dir "${EXTCAP_INSTALL_FULL_LIBDIR}") + set(_data_dir "${CMAKE_INSTALL_FULL_DATADIR}") + endif() + add_definitions(-DPLUGIN_DIR=\"${_plugin_dir}\") + add_definitions(-DEXTCAP_DIR=\"${_extcap_dir}\") + add_definitions(-DDATA_DIR=\"${_data_dir}\") +endif() add_subdirectory(wmem) diff --git a/wsutil/filesystem.c b/wsutil/filesystem.c index 27813ffdc3..32113624ed 100644 --- a/wsutil/filesystem.c +++ b/wsutil/filesystem.c @@ -51,6 +51,8 @@ #define PLUGINS_DIR_NAME "plugins" #define PROFILES_INFO_NAME "profile_files.txt" +#define _S G_DIR_SEPARATOR_S + /* * Application configuration namespace. Used to construct configuration * paths and environment variables. @@ -73,6 +75,12 @@ char *datafile_dir = NULL; char *persdatafile_dir = NULL; char *persconfprofile = NULL; +/* Directory from which the executable came. */ +static char *progfile_dir = NULL; +#ifdef __MINGW64__ +static char *install_prefix = NULL; +#endif + static gboolean do_store_persconffiles = FALSE; static GHashTable *profile_files = NULL; @@ -209,11 +217,6 @@ test_for_fifo(const char *path) return 0; } -/* - * Directory from which the executable came. - */ -static char *progfile_dir; - #ifdef __APPLE__ /* * Directory of the application bundle in which we're contained, @@ -531,6 +534,19 @@ static void trim_progfile_dir(void) g_free(extcap_progfile_dir); } +#ifdef __MINGW64__ +static char * +trim_last_dir_from_path(const char *_path) +{ + char *path = ws_strdup(_path); + char *last_dir = find_last_pathname_separator(path); + if (last_dir) { + *last_dir = '\0'; + } + return path; +} +#endif + /* * Construct the path name of a non-extcap Wireshark executable file, * given the program name. The executable name doesn't include ".exe"; @@ -562,19 +578,10 @@ get_executable_path(const char *program_name) * and save it for future use. Returns NULL on success, and a * g_mallocated string containing an error on failure. */ +#ifdef _WIN32 char * -configuration_init( -#ifdef _WIN32 - const char* arg0 _U_, -#else - const char* arg0, -#endif - const char *namespace_name -) +configuration_init_w32(const char* arg0 _U_) { - set_configuration_namespace(namespace_name); - -#ifdef _WIN32 TCHAR prog_pathname_w[_MAX_PATH+2]; char *prog_pathname; DWORD error; @@ -599,7 +606,7 @@ configuration_init( progfile_dir = g_path_get_dirname(prog_pathname); if (progfile_dir != NULL) { trim_progfile_dir(); - return NULL; /* we succeeded */ + /* we succeeded */ } else { /* * OK, no. What do we do now? @@ -634,7 +641,32 @@ configuration_init( return ws_strdup_printf("GetModuleFileName failed: %s (%u)", msg, error); } -#else + +#ifdef __MINGW64__ + /* + * We already have the program_dir. Find the installation prefix. + * This is one level up from the bin_dir. If the program_dir does + * not end with "bin" then assume we are running in the build directory + * and the "installation prefix" (staging directory) is the same as + * the program_dir. + */ + if (g_str_has_suffix(progfile_dir, _S"bin")) { + install_prefix = trim_last_dir_from_path(progfile_dir); + } + else { + install_prefix = g_strdup(progfile_dir); + running_in_build_directory_flag = TRUE; + } +#endif /* __MINGW64__ */ + + return NULL; +} + +#else /* !_WIN32 */ + +char * +configuration_init_posix(const char* arg0) +{ const char *execname; char *prog_pathname; char *curdir; @@ -865,6 +897,18 @@ configuration_init( g_free(prog_pathname); return retstr; } +} +#endif /* ?_WIN32 */ + +char * +configuration_init(const char* arg0, const char *namespace_name) +{ + set_configuration_namespace(namespace_name); + +#ifdef _WIN32 + return configuration_init_w32(arg0); +#else + return configuration_init_posix(arg0); #endif } @@ -918,7 +962,13 @@ get_datafile_dir(void) if (datafile_dir != NULL) return datafile_dir; -#ifdef _WIN32 +#if defined(__MINGW64__) + if (running_in_build_directory_flag) { + datafile_dir = g_strdup(install_prefix); + } else { + datafile_dir = g_build_filename(install_prefix, DATA_DIR, (gchar *)NULL); + } +#elif defined(_WIN32) /* * Do we have the pathname of the program? If so, assume we're * running an installed version of the program. If we fail, @@ -1020,7 +1070,13 @@ static void init_plugin_dir(void) { #if defined(HAVE_PLUGINS) || defined(HAVE_LUA) -#ifdef _WIN32 +#if defined(__MINGW64__) + if (running_in_build_directory_flag) { + plugin_dir = g_build_filename(install_prefix, "plugins", (gchar *)NULL); + } else { + plugin_dir = g_build_filename(install_prefix, PLUGIN_DIR, (gchar *)NULL); + } +#elif defined(_WIN32) /* * On Windows, the data file directory is the installation * directory; the plugins are stored under it. @@ -1166,7 +1222,9 @@ get_plugins_pers_dir_with_version(void) */ static char *extcap_dir = NULL; -static void init_extcap_dir(void) { +static void +init_extcap_dir(void) +{ const char *extcap_dir_envar = CONFIGURATION_ENVIRONMENT_VARIABLE("EXTCAP_DIR"); if (g_getenv(extcap_dir_envar) && !started_with_special_privs()) { /* @@ -1175,7 +1233,14 @@ static void init_extcap_dir(void) { */ extcap_dir = g_strdup(g_getenv(extcap_dir_envar)); } -#ifdef _WIN32 + +#if defined(__MINGW64__) + else if (running_in_build_directory_flag) { + extcap_dir = g_build_filename(install_prefix, "extcap", (gchar *)NULL); + } else { + extcap_dir = g_build_filename(install_prefix, EXTCAP_DIR, (gchar *)NULL); + } +#elif defined(_WIN32) else { /* * On Windows, the data file directory is the installation @@ -2519,6 +2584,10 @@ free_progdirs(void) persconfprofile = NULL; g_free(progfile_dir); progfile_dir = NULL; +#ifdef __MINGW64__ + g_free(install_prefix); + install_prefix = NULL; +#endif #if defined(HAVE_PLUGINS) || defined(HAVE_LUA) g_free(plugin_dir); plugin_dir = NULL;