From f4cdf90d73aeffae37b400fa060bece5917cf4c2 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 8 Oct 2018 22:48:58 +0100 Subject: [PATCH] MDEV-17279 Windows : link C runtime dynamically Changed the build to use /MD flag so that DDL version of C runtime is used. To make sure MariaDB is always runnable on target system, include redistributable CRT libraries into installer. For MSI package, use Microsoft's merge modules. For ZIP use "applocal" approach,i.e place redistributable dlls into the bin directory of the package(via InstallRequiredSystemLibraries cmake module) The space overhead of libraries in negligible, ~ 3MB unpacked. There are 2 cases, where we still link C runtime statically - Upgrade wizard, it uses MFC, and we link statically to avoid redistribute also whole MFC (for this single application, does not make much sense). - MSI installer's custom action dll wixca.dll.Here, we need static link so that MSI won't fail on a target system that does not have VC++2015 runtime already installed. --- cmake/os/Windows.cmake | 19 +++++-- plugin/aws_key_management/CMakeLists.txt | 8 ++- win/packaging/CMakeLists.txt | 69 ++++++++++++------------ win/packaging/CPackWixConfig.cmake | 2 +- win/packaging/ca/CMakeLists.txt | 7 +-- win/packaging/create_msi.cmake | 11 +++- win/packaging/extra.wxs.in | 12 ++++- win/packaging/mysql_server.wxs.in | 2 +- win/upgrade_wizard/CMakeLists.txt | 18 ++++--- 9 files changed, 97 insertions(+), 51 deletions(-) diff --git a/cmake/os/Windows.cmake b/cmake/os/Windows.cmake index 0caa67b20ab..1aa959fc002 100644 --- a/cmake/os/Windows.cmake +++ b/cmake/os/Windows.cmake @@ -96,7 +96,8 @@ IF(MSVC) # Disable mingw based pkg-config found in Strawberry perl SET(PKG_CONFIG_EXECUTABLE 0 CACHE INTERNAL "") - SET(MSVC_CRT_TYPE /MT CACHE STRING + + SET(MSVC_CRT_TYPE /MD CACHE STRING "Runtime library - specify runtime library for linking (/MT,/MTd,/MD,/MDd)" ) SET(VALID_CRT_TYPES /MTd /MDd /MD /MT) @@ -106,9 +107,7 @@ IF(MSVC) IF(MSVC_CRT_TYPE MATCHES "/MD") # Dynamic runtime (DLLs), need to install CRT libraries. - SET(CMAKE_INSTALL_MFC_LIBRARIES TRUE)# upgrade wizard SET(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT VCCRT) - SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS TRUE) SET(CMAKE_INSTALL_UCRT_LIBRARIES TRUE) IF(MSVC_CRT_TYPE STREQUAL "/MDd") SET (CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY TRUE) @@ -278,3 +277,17 @@ ENDIF() SET(FN_NO_CASE_SENSE 1) SET(USE_SYMDIR 1) + +# Force static C runtime for targets in current directory +# (useful to get rid of MFC dll's dependency, or in installer) +MACRO(FORCE_STATIC_CRT) + FOREACH(flag + CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO + CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG_INIT + CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG_INIT + CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL + ) + STRING(REGEX REPLACE "/MD[d]?" "/MT" "${flag}" "${${flag}}" ) + ENDFOREACH() +ENDMACRO() diff --git a/plugin/aws_key_management/CMakeLists.txt b/plugin/aws_key_management/CMakeLists.txt index aa93fc3aa03..4620290000e 100644 --- a/plugin/aws_key_management/CMakeLists.txt +++ b/plugin/aws_key_management/CMakeLists.txt @@ -120,6 +120,12 @@ ELSE() SET(GIT_TAG "1.2.11") ENDIF() + IF(MSVC_CRT_TYPE MATCHES "/MD") + SET(FORCE_SHARED_CRT ON) + ELSE() + SET(FORCE_SHARED_CRT OFF) + ENDIF() + SET(AWS_SDK_PATCH_COMMAND ) ExternalProject_Add( aws_sdk_cpp @@ -131,7 +137,7 @@ ELSE() CMAKE_ARGS -DBUILD_ONLY=kms -DBUILD_SHARED_LIBS=OFF - -DFORCE_SHARED_CRT=OFF + -DFORCE_SHARED_CRT=${FORCE_SHARED_CRT} -DENABLE_TESTING=OFF "-DCMAKE_CXX_FLAGS_DEBUG=${CMAKE_CXX_FLAGS_DEBUG} ${PIC_FLAG}" "-DCMAKE_CXX_FLAGS_RELWITHDEBINFO=${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${PIC_FLAG}" diff --git a/win/packaging/CMakeLists.txt b/win/packaging/CMakeLists.txt index 683abc64ef3..465b4529fac 100644 --- a/win/packaging/CMakeLists.txt +++ b/win/packaging/CMakeLists.txt @@ -178,6 +178,39 @@ IF(CMAKE_GENERATOR MATCHES "Visual Studio") SET(CONFIG_PARAM "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_CFG_INTDIR}") ENDIF() +IF(MSVC_CRT_TYPE MATCHES "/MD") + # Find out CRT merge module path, we're going to use it in installer + # The path and name depends on VS version + IF(MSVC_VERSION LESS 1900) + # VS2015 + SET(VCREDIST_MSM_FILENAME Microsoft_VC140_CRT_${WIX_ARCH_SUFFIX}.msm) + SET(ProgramFilesX86 "ProgramFiles(x86)") + FIND_FILE(${VCREDIST_MSM_FILENAME} + NO_DEFAULT_PATH + PATHS + "$ENV{${ProgramFilesX86}}/Common Files/Merge Modules" + "$ENV{ProgramFiles}/Common Files/Merge Modules" + ) + ELSEIF(MSVC_VERSION LESS 2000) + # VS2017 + SET(VCREDIST_MSM_FILENAME Microsoft_VC141_CRT_${WIX_ARCH_SUFFIX}.msm) + FILE(GLOB MSM_LIST "C:/Program Files*/Microsoft Visual Studio/2017/*/VC/Redist/MSVC/*/MergeModules/${VCREDIST_MSM_FILENAME}") + LIST(LENGTH MSM_LIST LEN) + IF(LEN GREATER 0) + LIST(GET MSM_LIST 0 VCRedist_MSM) + ENDIF() + ELSE() + # Post-VS2017. Needs to be ported when new VS is out + MESSAGE(WARNING + "Name of redistributable merge module not known for this version of MSVC") + ENDIF() + IF (NOT VCRedist_MSM) + MESSAGE(WARNING "Can't find merge module ${VCREDIST_MSM_FILENAME}") + ELSE() + FILE(TO_NATIVE_PATH ${VCRedist_MSM} VCRedist_MSM) + # MESSAGE("VCRedist_MSM=${VCRedist_MSM}") + ENDIF() +ENDIF() ADD_CUSTOM_TARGET( MSI @@ -209,44 +242,12 @@ ADD_CUSTOM_TARGET( -DVERSION="${VERSION}" -DWITH_THIRD_PARTY="${WITH_THIRD_PARTY}" -DWIXCA_LOCATION="$" + -DMSVC_CRT_TYPE="${MSVC_CRT_TYPE}" + -DVCRedist_MSM="${VCRedist_MSM}" -P ${CMAKE_CURRENT_SOURCE_DIR}/create_msi.cmake ) ADD_DEPENDENCIES(MSI wixca) -ADD_CUSTOM_TARGET( - MSI_ESSENTIALS - COMMAND ${CMAKE_COMMAND} ${CONFIG_PARAM} -DESSENTIALS=1 - -DCANDLE_EXECUTABLE="${CANDLE_EXECUTABLE}" - -DCMAKE_CFG_INTDIR="${CMAKE_CFG_INTDIR}" - -DCMAKE_FULL_VER="${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" - -DCMAKE_SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P} - -DCOPYING_RTF="${COPYING_RTF}" - -DCPACK_WIX_CONFIG="${CPACK_WIX_CONFIG}" - -DCPACK_WIX_INCLUDE="${CPACK_WIX_INCLUDE}" - -DCPACK_WIX_PACKAGE_BASE_NAME="${CPACK_WIX_PACKAGE_BASE_NAME}" - -DCPACK_WIX_PACKAGE_NAME="${CPACK_WIX_PACKAGE_NAME}" - -DCPACK_WIX_UPGRADE_CODE="${CPACK_WIX_UPGRADE_CODE}" - -DEXTRA_WIX_PREPROCESSOR_FLAGS="${EXTRA_WIX_PREPROCESSOR_FLAGS}" - -DLIGHT_EXECUTABLE="${LIGHT_EXECUTABLE}" - -DMAJOR_VERSION="${MAJOR_VERSION}" - -DMANUFACTURER="${MANUFACTURER}" - -DMINOR_VERSION="${MINOR_VERSION}" - -DPATCH_VERSION="${PATCH_VERSION}" - -DSIGNCODE="${SIGNCODE}" - -DSIGNTOOL_EXECUTABLE="${SIGNTOOL_EXECUTABLE}" - -DSIGNTOOL_PARAMETERS="${SIGNTOOL_PARAMETERS}" - -DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}" - -DTHIRD_PARTY_DOWNLOAD_LOCATION="${THIRD_PARTY_DOWNLOAD_LOCATION}" - -DTHIRD_PARTY_FEATURE_CONDITION="${THIRD_PARTY_FEATURE_CONDITION}" - -DTINY_VERSION="${TINY_VERSION}" - -DTOP_BINDIR="${CMAKE_BINARY_DIR}" - -DVERSION="${VERSION}" - -DWITH_THIRD_PARTY="${WITH_THIRD_PARTY}" - -DWIXCA_LOCATION="$" - -P ${CMAKE_CURRENT_SOURCE_DIR}/create_msi.cmake -) -ADD_DEPENDENCIES(MSI_ESSENTIALS wixca) - IF(CMAKE_GENERATOR MATCHES "Visual Studio") SET(CPACK_CONFIG_PARAM -C $(Configuration)) diff --git a/win/packaging/CPackWixConfig.cmake b/win/packaging/CPackWixConfig.cmake index 994b121797a..74329e79247 100644 --- a/win/packaging/CPackWixConfig.cmake +++ b/win/packaging/CPackWixConfig.cmake @@ -9,7 +9,7 @@ IF(ESSENTIALS) ENDIF() ELSE() SET(CPACK_COMPONENTS_USED - "Server;Client;Development;SharedLibraries;Documentation;Readme;Common;VCCRT;connect-engine;ClientPlugins;gssapi-server;gssapi-client;aws-key-management;rocksdb-engine;backup") + "Server;Client;Development;SharedLibraries;Documentation;Readme;Common;connect-engine;ClientPlugins;gssapi-server;gssapi-client;aws-key-management;rocksdb-engine;backup") ENDIF() SET( WIX_FEATURE_MySQLServer_EXTRA_FEATURES "DBInstance;SharedClientServerComponents") diff --git a/win/packaging/ca/CMakeLists.txt b/win/packaging/ca/CMakeLists.txt index 04d5408b9c9..79e8ee4c5a7 100644 --- a/win/packaging/ca/CMakeLists.txt +++ b/win/packaging/ca/CMakeLists.txt @@ -18,7 +18,8 @@ SET(WIXCA_SOURCES CustomAction.cpp CustomAction.def) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql) +# Custom action should not depend on C runtime, since we do not know if CRT is installed. +FORCE_STATIC_CRT() ADD_VERSION_INFO(wixca SHARED WIXCA_SOURCES) -ADD_LIBRARY(wixca SHARED EXCLUDE_FROM_ALL ${WIXCA_SOURCES}) -TARGET_LINK_LIBRARIES(wixca ${WIX_WCAUTIL_LIBRARY} ${WIX_DUTIL_LIBRARY} - msi version winservice) +ADD_LIBRARY(wixca SHARED EXCLUDE_FROM_ALL ${WIXCA_SOURCES} ${CMAKE_SOURCE_DIR}/sql/winservice.c) +TARGET_LINK_LIBRARIES(wixca ${WIX_WCAUTIL_LIBRARY} ${WIX_DUTIL_LIBRARY} msi version) diff --git a/win/packaging/create_msi.cmake b/win/packaging/create_msi.cmake index 795baa32c8f..01bb6505b3f 100644 --- a/win/packaging/create_msi.cmake +++ b/win/packaging/create_msi.cmake @@ -59,6 +59,11 @@ IF(CMAKE_INSTALL_CONFIG_NAME) SET(CONFIG_PARAM "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_INSTALL_CONFIG_NAME}") ENDIF() +IF((MSVC_CRT_TYPE MATCHES "/MD") AND (NOT VCRedist_MSM)) + # Something was wrong, we package VC runtime merge modules + # when compiled with dynamic C runtime. + MESSAGE(FATAL_ERROR "Redistributable merge module was not found") +ENDIF() SET(COMPONENTS_ALL "${CPACK_COMPONENTS_ALL}") FOREACH(comp ${COMPONENTS_ALL}) @@ -381,9 +386,13 @@ EXECUTE_PROCESS( ${EXTRA_CANDLE_ARGS} ) +IF(VCRedist_MSM) + SET(SILENCE_VCREDIST_MSM_WARNINGS -sice:ICE82 -sice:ICE03) +ENDIF() + EXECUTE_PROCESS( COMMAND ${LIGHT_EXECUTABLE} -v -ext WixUIExtension -ext WixUtilExtension - -ext WixFirewallExtension -sice:ICE61 + -ext WixFirewallExtension -sice:ICE61 ${SILENCE_VCREDIST_MSM_WARNINGS} mysql_server.wixobj extra.wixobj -out ${CPACK_PACKAGE_FILE_NAME}.msi ${EXTRA_LIGHT_ARGS} ) diff --git a/win/packaging/extra.wxs.in b/win/packaging/extra.wxs.in index a71ef982896..7a9168d394a 100644 --- a/win/packaging/extra.wxs.in +++ b/win/packaging/extra.wxs.in @@ -650,7 +650,17 @@ - + + + + + + + + + + + SKIPNETWORKING ALLOWREMOTEROOTACCESS diff --git a/win/packaging/mysql_server.wxs.in b/win/packaging/mysql_server.wxs.in index c10116830e7..80dcc365e56 100644 --- a/win/packaging/mysql_server.wxs.in +++ b/win/packaging/mysql_server.wxs.in @@ -12,7 +12,7 @@ Keywords='Installer' Description='MariaDB Server' Manufacturer='@MANUFACTURER@' - InstallerVersion='200' + InstallerVersion='301' Languages='1033' Compressed='yes' SummaryCodepage='1252' diff --git a/win/upgrade_wizard/CMakeLists.txt b/win/upgrade_wizard/CMakeLists.txt index f4148ee98d2..7d0e774b968 100644 --- a/win/upgrade_wizard/CMakeLists.txt +++ b/win/upgrade_wizard/CMakeLists.txt @@ -23,21 +23,27 @@ IF(NOT MFC_FOUND) ENDIF() RETURN() ENDIF() + IF(MSVC_CRT_TYPE MATCHES "/MD") - # MFC should be dynamically linked - SET(CMAKE_MFC_FLAG 2) + # FORCE static CRT and MFC for upgrade wizard, + # so we do not have to redistribute MFC. + FORCE_STATIC_CRT() + SET(UPGRADE_WIZARD_SOURCES ${CMAKE_SOURCE_DIR}/sql/winservice.c) ELSE() - # MFC should be statically linked - SET(CMAKE_MFC_FLAG 1) + SET(UPGRADE_WIZARD_LINK_LIBRARIES winservice) ENDIF() + +# MFC should be statically linked +SET(CMAKE_MFC_FLAG 1) + # Enable exception handling (avoids warnings) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc -DNO_WARN_MBCS_MFC_DEPRECATION") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql) MYSQL_ADD_EXECUTABLE(mysql_upgrade_wizard - upgrade.cpp upgradeDlg.cpp upgrade.rc + upgrade.cpp upgradeDlg.cpp upgrade.rc ${UPGRADE_WIZARD_SOURCES} COMPONENT Server) -TARGET_LINK_LIBRARIES(mysql_upgrade_wizard winservice) +TARGET_LINK_LIBRARIES(mysql_upgrade_wizard ${UPGRADE_WIZARD_LINK_LIBRARIES}) # upgrade_wizard is Windows executable, set WIN32_EXECUTABLE so it does not # create a console. SET_TARGET_PROPERTIES(mysql_upgrade_wizard PROPERTIES WIN32_EXECUTABLE 1)