From 9bf0492b7da5a6aefbe59a3906eb2c4d07452039 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 10 Jun 2025 11:53:45 +0200 Subject: [PATCH] MDEV-36904 Improve runtime dependency packaging on Windows Background: In MDEV-33474, we introduced runtime dependency packaging primarily to support libcurl and other potential third-party dependencies from vcpkg. Problem: The INSTALL(RUNTIME_DEPENDENCY_SET) command was failing at packaging step unless shared libraries from the same build were explicitly excluded via PRE_EXCLUDE_REGEXES. While initially only server.dll was excluded this way, this turned out insufficient for users compiling their own plugins Solution: Exclude all linked shared libraries from the same build via PRE_EXCLUDE_REGEXES. Move dependency detection and install to the end of CMake processing, after all add_library/add_executable calls, when all targets are known. Also made the INSTALL_RUNTIME_DEPENDENCIES variable independent of vcpkg detection, for simplicity. --- CMakeLists.txt | 11 ++------- cmake/install_macros.cmake | 50 +++++++++++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 943d4b4f0c2..79c43fb4fc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,15 +126,7 @@ ENDIF() FIND_PACKAGE(Git) IF(WIN32 AND (CMAKE_VERSION VERSION_GREATER "3.21")) - # Install runtime dependency by default, when using vcpkg - IF(NOT DEFINED INSTALL_RUNTIME_DEPENDENCIES_DEFAULT) - IF("${VCPKG_INSTALLED_DIR}") - SET(INSTALL_RUNTIME_DEPENDENCIES_DEFAULT OFF) - ELSE() - SET(INSTALL_RUNTIME_DEPENDENCIES_DEFAULT ON) - ENDIF() - ENDIF() - OPTION(INSTALL_RUNTIME_DEPENDENCIES "Install runtime dependencies" "${INSTALL_RUNTIME_DEPENDENCIES_DEFAULT}") + OPTION(INSTALL_RUNTIME_DEPENDENCIES "Install runtime dependencies" ON) ENDIF() # Following autotools tradition, add preprocessor definitions @@ -596,6 +588,7 @@ ENDIF() INCLUDE(build_depends) +INSTALL_RUNTIME_DEPS() INCLUDE(CPack) IF(WIN32 AND SIGNCODE) diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index dd072abdfb8..4a4e3dae9b6 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -228,26 +228,58 @@ FUNCTION(MYSQL_INSTALL_TARGETS) IF(SIGNCODE) SIGN_TARGET(${target} ${COMP}) ENDIF() + IF(INSTALL_RUNTIME_DEPENDENCIES) + # Populate INSTALLED_TARGETS list (stored as global property) + # The list is used in INSTALL_RUNTIME_DEPS + GET_PROPERTY(installed_targets GLOBAL PROPERTY INSTALLED_TARGETS) + IF(NOT installed_targets) + SET(installed_targets) + ENDIF() + LIST(APPEND installed_targets "${target}") + SET_PROPERTY(GLOBAL PROPERTY INSTALLED_TARGETS "${installed_targets}") + SET(RUNTIME_DEPS RUNTIME_DEPENDENCY_SET ${target}) + ENDIF() + INSTALL(TARGETS ${target} DESTINATION ${ARG_DESTINATION} ${COMP} ${RUNTIME_DEPS}) + INSTALL_DEBUG_SYMBOLS(${target} ${COMP} INSTALL_LOCATION ${ARG_DESTINATION}) ENDFOREACH() +ENDFUNCTION() - IF(WIN32 AND INSTALL_RUNTIME_DEPENDENCIES) - STRING(JOIN "." runtime_deps_set_name ${TARGETS}) - SET(RUNTIME_DEPS RUNTIME_DEPENDENCY_SET "${runtime_deps_set_name}") + +# On Windows, installs runtime dependency for all targets +FUNCTION(INSTALL_RUNTIME_DEPS) + IF(NOT WIN32 OR NOT INSTALL_RUNTIME_DEPENDENCIES) + RETURN() ENDIF() + # Install all runtime dependencies - INSTALL(TARGETS ${TARGETS} DESTINATION ${ARG_DESTINATION} ${COMP} ${RUNTIME_DEPS}) - INSTALL_DEBUG_SYMBOLS(${TARGETS} ${COMP} INSTALL_LOCATION ${ARG_DESTINATION}) + GET_PROPERTY(installed_targets GLOBAL PROPERTY INSTALLED_TARGETS) + # Exclude all dependencies that are shared libraries from the + # same build. + FOREACH(tgt ${installed_targets}) + SET(exclude_libs) + GET_TARGET_PROPERTY(link_libraries ${tgt} LINK_LIBRARIES) + IF(link_libraries) + FOREACH(lib ${link_libraries}) + IF(TARGET ${lib}) + GET_TARGET_PROPERTY(type ${lib} TYPE) + IF(type MATCHES "SHARED") + LIST(APPEND exclude_libs "$\\.dll") + ENDIF() + ENDIF() + ENDFOREACH() + ENDIF() - IF(WIN32 AND INSTALL_RUNTIME_DEPENDENCIES) INSTALL( RUNTIME_DEPENDENCY_SET - "${runtime_deps_set_name}" + ${tgt} COMPONENT RuntimeDeps DESTINATION ${INSTALL_BINDIR} PRE_EXCLUDE_REGEXES "api-ms-" # Windows stuff "ext-ms-" - "server\\.dll" # main server DLL, installed separately + "icuuc\\.dll" # Old Windows 10 (1809) + "icuin\\.dll" + ${exclude_libs} "clang_rt" # ASAN libraries "vcruntime" POST_EXCLUDE_REGEXES @@ -257,7 +289,7 @@ FUNCTION(MYSQL_INSTALL_TARGETS) ${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin $<$:${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug/bin> ) - ENDIF() + ENDFOREACH() ENDFUNCTION() # Optionally install mysqld/client/embedded from debug build run. outside of the current build dir