# Copyright (c) 2014, 2025, Oracle and/or its affiliates. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2.0, # as published by the Free Software Foundation. # # This program is designed to work with certain software (including # but not limited to OpenSSL) that is licensed under separate terms, # as designated in a particular file or component or in included license # documentation. The authors of MySQL hereby grant you an additional # permission to link the program and your derivative works with the # separately licensed software that they have either included with # the program or referenced in the documentation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU General Public License, version 2.0, for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA MESSAGE(STATUS "Running cmake version ${CMAKE_VERSION}") IF(MYSQL_SOURCE_DIR) FILE(TO_CMAKE_PATH "${MYSQL_SOURCE_DIR}" MYSQL_SOURCE_DIR) ENDIF() IF(MYSQL_BUILD_DIR) FILE(TO_CMAKE_PATH "${MYSQL_BUILD_DIR}" MYSQL_BUILD_DIR) ENDIF() IF(WIN32) # CMake 3.8.0 is needed for Visual Studio 2017 and x64 toolset. CMAKE_MINIMUM_REQUIRED(VERSION 3.8.0) EXECUTE_PROCESS(COMMAND wmic os get version OUTPUT_VARIABLE NT_RELEASE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE WMIC_RESULT ) IF(WMIC_RESULT EQUAL 0) STRING(REPLACE "\r" "" NT_RELEASE_VERSION "${NT_RELEASE_VERSION}") STRING(REPLACE "\n" "" NT_RELEASE_VERSION "${NT_RELEASE_VERSION}") STRING(REGEX MATCH "Version[ ]+([0-9\.]+)" V_NUM "${NT_RELEASE_VERSION}") MESSAGE(STATUS "NT_RELEASE_VERSION is ${NT_RELEASE_VERSION}") IF(CMAKE_MATCH_1) IF(CMAKE_MATCH_1 VERSION_LESS "10") MESSAGE(FATAL_ERROR "Need at least Windows Server 2016, or Windows 10, to build") ENDIF() ENDIF() ENDIF() IF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_GENERATOR MATCHES "2019") IF(CMAKE_VERSION MATCHES "MSVC") # It is the bundled version, ignore version check, # (although this seems to be buggy too). ELSE() # Bug in msbuild, install the latest in the 3.15 series as a workaround. # https://gitlab.kitware.com/cmake/cmake/issues/19303 # custom commands are re-built every time CMAKE_MINIMUM_REQUIRED(VERSION 3.15.3) ENDIF() ENDIF() ELSEIF(APPLE) # Version 3.12.4 is needed because the new build system of Xcode is not # supported by cmake. 3.12.4 will force using the legacy build system. # Version 3.9.2 is needed because INCLUDE_DIRECTORIES(SYSTEM ...) wasn't # handled properly by the cmake Xcode generator. IF(CMAKE_GENERATOR STREQUAL "Xcode") CMAKE_MINIMUM_REQUIRED(VERSION 3.12.4) ELSE() CMAKE_MINIMUM_REQUIRED(VERSION 3.9.2) ENDIF() # If this is macOS 11, we need cmake 3.18 # System libraries like # /usr/lib/libresolv.dylib # are no longer present in the file system. # cmake >= 3.18 will look for .tbd files in the SDK instead # So we end up linking with: # /Applications/Xcode.app/.../usr/lib/libresolv.tbd # We must postpone the version test until we have called 'uname -r' below. ELSEIF(UNIX) # This is currently minimum version on all supported platforms. IF(CMAKE_VERSION VERSION_LESS 3.5.1) # Default cmake is 2.8.12.2 on RedHat IF(EXISTS "/etc/redhat-release") MESSAGE(WARNING "Please use cmake3 rather than cmake on this platform") FIND_PROGRAM(MY_CMAKE3 cmake3 /bin /usr/bin /usr/local/bin) IF(MY_CMAKE3) MESSAGE(STATUS "Found ${MY_CMAKE3}") ELSE() MESSAGE(STATUS "Please install cmake3 (yum install cmake3)") ENDIF() ELSE() # On SunOS /opt/csw/bin/cmake is (most likely) too old. FIND_PROGRAM(MY_UNAME uname /bin /usr/bin /usr/local/bin /sbin) IF(MY_UNAME) EXEC_PROGRAM(uname ARGS -s OUTPUT_VARIABLE MY_HOST_SYSTEM_NAME) IF(MY_HOST_SYSTEM_NAME MATCHES "SunOS") FIND_PROGRAM(MY_CMAKE cmake /usr/bin NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH ) IF(MY_CMAKE) MESSAGE(STATUS "Found ${MY_CMAKE}") EXEC_PROGRAM(${MY_CMAKE} ARGS --version) ELSE() MESSAGE(STATUS "Please install /usr/bin/cmake ") ENDIF() ENDIF() ENDIF() ENDIF() ENDIF() ENDIF() # CMake 3.5 is needed for TARGET_SOURCES(... $) # CMake 3.7 is needeed for VERSION_GREATER_EQUAL # For the set of currently supported platforms, we can bump up to: CMAKE_MINIMUM_REQUIRED(VERSION 3.14.6) INCLUDE(CMakePushCheckState) # On Linux el6/el7/el8/el9 the default gcc is too old, # see if devtoolset/gcc-toolset is installed. # Same with SUSE linux, look for gcc 10/12 there. # We need to look for gcc before calling PROJECT below. OPTION(FORCE_UNSUPPORTED_COMPILER "Disable compiler version checks" OFF) MARK_AS_ADVANCED(FORCE_UNSUPPORTED_COMPILER) # Use 'uname -r' and 'rpm -qf /' to figure out host system. # For Docker images we cannot trust uname, so use rpm instead. IF(UNIX) FIND_PROGRAM(MY_UNAME uname /bin /usr/bin /usr/local/bin /sbin) IF(MY_UNAME) EXECUTE_PROCESS(COMMAND ${MY_UNAME} -s OUTPUT_VARIABLE MY_HOST_SYSTEM_NAME OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE MY_UNAME_RESULT ) EXECUTE_PROCESS(COMMAND ${MY_UNAME} -m OUTPUT_VARIABLE MY_HOST_MACHINE_NAME OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE MY_UNAME_MACHINE_RESULT ) EXEC_PROGRAM(${MY_UNAME} ARGS -r OUTPUT_VARIABLE MY_HOST_SYSTEM_VERSION) ENDIF() FIND_PROGRAM(MY_DPKG_BUILDFLAGS dpkg-buildflags /bin /usr/bin) FIND_PROGRAM(MY_RPM rpm /bin /usr/bin) IF(MY_RPM) EXECUTE_PROCESS(COMMAND ${MY_RPM} -qf / OUTPUT_VARIABLE MY_HOST_FILESYSTEM_NAME OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE MY_RPM_RESULT ) ENDIF() ENDIF() # STRING(APPEND ...) from cmake VERSION 3.4 MACRO(STRING_APPEND STRING_VAR INPUT) SET(${STRING_VAR} "${${STRING_VAR}}${INPUT}") ENDMACRO() MACRO(STRING_PREPEND STRING_VAR INPUT) SET(${STRING_VAR} "${INPUT}${${STRING_VAR}}") ENDMACRO() IF(MY_HOST_SYSTEM_NAME MATCHES "SunOS") SET(SOLARIS 1) ENDIF() IF(MY_HOST_SYSTEM_NAME MATCHES "Linux") # Trust 'rpm -qf /' rather than 'uname -s' STRING(REGEX MATCH "\\.el([6789])\\." MATCH_FSYS "${MY_HOST_FILESYSTEM_NAME}") IF(NOT CMAKE_MATCH_1) STRING(REGEX MATCH "\\.el(10)\\." MATCH_FSYS "${MY_HOST_FILESYSTEM_NAME}") ENDIF() # Set LINUX_RHEL6, LINUX_RHEL7, LINUX_RHEL8 or LINUX_RHEL9 or LINUX_RHEL10 IF(CMAKE_MATCH_1) SET(LINUX_RHEL 1) SET(LINUX_RHEL${CMAKE_MATCH_1} 1) ENDIF() ENDIF() IF(NOT LINUX_RHEL AND MY_HOST_SYSTEM_NAME MATCHES "Linux") IF(EXISTS "/etc/os-release") FILE(READ "/etc/os-release" MY_OS_RELEASE) IF(MY_OS_RELEASE MATCHES "Debian") SET(LINUX_DEBIAN 1) ELSEIF(MY_OS_RELEASE MATCHES "Ubuntu") SET(LINUX_UBUNTU 1) IF(MY_OS_RELEASE MATCHES "16.04") SET(LINUX_UBUNTU_16_04 1) ELSEIF(MY_OS_RELEASE MATCHES "18.04") SET(LINUX_UBUNTU_18_04 1) ENDIF() # /etc/os-release contains a line like # VERSION_ID="20.04" # Match the numeric value, including the dot, ignore the rest: STRING(REGEX MATCH "VERSION_ID=\"([0-9\\.]+).*" UNUSED ${MY_OS_RELEASE}) IF(CMAKE_MATCH_1) SET(LINUX_UBUNTU_VERSION_ID ${CMAKE_MATCH_1}) ENDIF() ENDIF() ENDIF() ENDIF() IF(EXISTS "/etc/SuSE-release") SET(LINUX_SUSE 1) ENDIF() IF(LINUX_SUSE) FILE(READ "/etc/SuSE-release" MY_OS_RELEASE) IF(MY_OS_RELEASE MATCHES "SUSE Linux Enterprise Server 12") SET(LINUX_SUSE_12 1) ELSEIF(MY_OS_RELEASE MATCHES "SUSE Linux Enterprise Server 15" OR MY_OS_RELEASE MATCHES "openSUSE .* 15") SET(LINUX_SUSE_15 1) ELSE() MESSAGE(WARNING "Unknown SUSE version.") ENDIF() ENDIF() IF(CMAKE_HOST_UNIX AND NOT FORCE_UNSUPPORTED_COMPILER AND NOT CMAKE_C_COMPILER AND NOT CMAKE_CXX_COMPILER) # Cannot INCLUDE(CMakeDetermineSystem) prior to PROJECT initialization below. SET (ENV_CC "$ENV{CC}") SET (ENV_CXX "$ENV{CXX}") IF (ENV_CC STREQUAL "" AND ENV_CXX STREQUAL "") IF(LINUX_RHEL) MESSAGE(STATUS "This is ${MATCH_FSYS} as found from 'rpm -qf /'") ENDIF() IF(LINUX_RHEL AND NOT LINUX_RHEL10) MESSAGE(STATUS "Looking for a devtoolset compiler") IF(LINUX_RHEL6) SET(ALTERNATIVE_PATHS "/opt/rh/devtoolset-8") ELSEIF(LINUX_RHEL7) # gcc11 not available yet IF(MY_HOST_MACHINE_NAME MATCHES "aarch64") SET(ALTERNATIVE_PATHS "/opt/rh/devtoolset-10") ELSE() SET(ALTERNATIVE_PATHS "/opt/rh/devtoolset-11") ENDIF() ELSEIF(LINUX_RHEL8 OR LINUX_RHEL9) SET(ALTERNATIVE_PATHS "/opt/rh/gcc-toolset-13") ELSEIF(LINUX_RHEL10) # Use default /usr/bin/gcc which is 14.2.1 ENDIF() FOREACH(OPT_PATH ${ALTERNATIVE_PATHS}) FIND_PROGRAM(ALTERNATIVE_GCC gcc NO_DEFAULT_PATH PATHS "${OPT_PATH}/root/usr/bin") FIND_PROGRAM(ALTERNATIVE_GPP g++ NO_DEFAULT_PATH PATHS "${OPT_PATH}/root/usr/bin") FIND_PROGRAM(ALTERNATIVE_LD ld NO_DEFAULT_PATH PATHS "${OPT_PATH}/root/usr/bin") FIND_PROGRAM(ALTERNATIVE_AR ar NO_DEFAULT_PATH PATHS "${OPT_PATH}/root/usr/bin") FIND_PROGRAM(ALTERNATIVE_RANLIB ranlib NO_DEFAULT_PATH PATHS "${OPT_PATH}/root/usr/bin") FIND_PROGRAM(ALTERNATIVE_ENABLE enable NO_DEFAULT_PATH PATHS "${OPT_PATH}") ENDFOREACH() # A missing ALTERNATIVE_LD may generate bad executables. IF(ALTERNATIVE_GCC AND ALTERNATIVE_GPP AND ALTERNATIVE_LD) # Set correct search path for executables, libraries, and data files. GET_FILENAME_COMPONENT(GCC_B_PREFIX ${ALTERNATIVE_GCC} DIRECTORY) STRING_PREPEND(CMAKE_C_FLAGS "-B${GCC_B_PREFIX} ") GET_FILENAME_COMPONENT(GPP_B_PREFIX ${ALTERNATIVE_GPP} DIRECTORY) STRING_PREPEND(CMAKE_CXX_FLAGS "-B${GPP_B_PREFIX} ") SET(CMAKE_C_COMPILER ${ALTERNATIVE_GCC}) SET(CMAKE_CXX_COMPILER ${ALTERNATIVE_GPP}) SET(CMAKE_LINKER ${ALTERNATIVE_LD}) SET(CMAKE_LINKER ${ALTERNATIVE_LD} CACHE PATH "Alternative ld") IF(ALTERNATIVE_AR) SET(CMAKE_AR ${ALTERNATIVE_AR}) SET(CMAKE_AR ${ALTERNATIVE_AR} CACHE PATH "Alternative ar") ENDIF() IF(ALTERNATIVE_RANLIB) SET(CMAKE_RANLIB ${ALTERNATIVE_RANLIB}) SET(CMAKE_RANLIB ${ALTERNATIVE_RANLIB} CACHE PATH "Alternative ranlib") ENDIF() MESSAGE(STATUS "Using ${ALTERNATIVE_GCC}") MESSAGE(STATUS "Using ${ALTERNATIVE_GPP}") ELSE() IF(LINUX_RHEL6) SET(DEV_PACKAGES "devtoolset-8-gcc devtoolset-8-gcc-c++ devtoolset-8-binutils") ELSEIF(LINUX_RHEL7) IF(MY_HOST_MACHINE_NAME MATCHES "aarch64") SET(DEV_PACKAGES "devtoolset-10-gcc devtoolset-10-gcc-c++ devtoolset-10-binutils") ELSE() SET(DEV_PACKAGES "devtoolset-11-gcc devtoolset-11-gcc-c++ devtoolset-11-binutils") ENDIF() ELSEIF(LINUX_RHEL8 OR LINUX_RHEL9) SET(DEV_PACKAGES "gcc-toolset-13-gcc gcc-toolset-13-gcc-c++ gcc-toolset-13-binutils") STRING_APPEND(DEV_PACKAGES " gcc-toolset-13-annobin-annocheck") STRING_APPEND(DEV_PACKAGES " gcc-toolset-13-annobin-plugin-gcc") ENDIF() MESSAGE(WARNING "Could not find devtoolset compiler/linker in ${ALTERNATIVE_PATHS}") MESSAGE(WARNING "You need to install the required packages:\n" " yum install ${DEV_PACKAGES}\n") MESSAGE(FATAL_ERROR "Or you can set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER explicitly.") ENDIF() ELSEIF(LINUX_UBUNTU_18_04) MESSAGE(STATUS "Looking for gcc-8 on Ubuntu 18.04") FIND_PROGRAM(ALTERNATIVE_GCC gcc-8 NO_DEFAULT_PATH PATHS "/usr/bin") FIND_PROGRAM(ALTERNATIVE_GPP g++-8 NO_DEFAULT_PATH PATHS "/usr/bin") FIND_PROGRAM(GCC_AR_EXECUTABLE gcc-ar-8 NO_DEFAULT_PATH PATHS "/usr/bin") FIND_PROGRAM(GCC_RANLIB_EXECUTABLE gcc-ranlib-8 NO_DEFAULT_PATH PATHS "/usr/bin") IF(GCC_AR_EXECUTABLE) SET(CMAKE_AR ${GCC_AR_EXECUTABLE}) SET(CMAKE_AR ${GCC_AR_EXECUTABLE} CACHE PATH "Alternative ar") ENDIF() IF(GCC_RANLIB_EXECUTABLE) SET(CMAKE_RANLIB ${GCC_RANLIB_EXECUTABLE}) SET(CMAKE_RANLIB ${GCC_RANLIB_EXECUTABLE} CACHE PATH "Alternative ranlib") ENDIF() IF (ALTERNATIVE_GCC AND ALTERNATIVE_GPP) SET(CMAKE_C_COMPILER ${ALTERNATIVE_GCC}) SET(CMAKE_CXX_COMPILER ${ALTERNATIVE_GPP}) MESSAGE(STATUS "Using ${ALTERNATIVE_GCC}") MESSAGE(STATUS "Using ${ALTERNATIVE_GPP}") ELSE() MESSAGE(WARNING "Could not find gcc-8") MESSAGE(FATAL_ERROR "Please do 'apt install gcc-8 g++-8'\n" "or set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER explicitly.") ENDIF() ELSEIF(LINUX_SUSE_12 OR LINUX_SUSE_15) MESSAGE(STATUS "We need to look for a newer GCC on SUSE Linux.") IF(LINUX_SUSE_12) FIND_PROGRAM(ALTERNATIVE_GCC gcc-10 NO_DEFAULT_PATH PATHS "/usr/bin") FIND_PROGRAM(ALTERNATIVE_GPP g++-10 NO_DEFAULT_PATH PATHS "/usr/bin") FIND_PROGRAM(GCC_AR_EXECUTABLE gcc-ar-10 NO_DEFAULT_PATH PATHS "/usr/bin") FIND_PROGRAM(GCC_RANLIB_EXECUTABLE gcc-ranlib-10 NO_DEFAULT_PATH PATHS "/usr/bin") ELSEIF(LINUX_SUSE_15) FIND_PROGRAM(ALTERNATIVE_GCC gcc-12 NO_DEFAULT_PATH PATHS "/usr/bin") FIND_PROGRAM(ALTERNATIVE_GPP g++-12 NO_DEFAULT_PATH PATHS "/usr/bin") FIND_PROGRAM(GCC_AR_EXECUTABLE gcc-ar-12 NO_DEFAULT_PATH PATHS "/usr/bin") FIND_PROGRAM(GCC_RANLIB_EXECUTABLE gcc-ranlib-12 NO_DEFAULT_PATH PATHS "/usr/bin") ENDIF() IF(GCC_AR_EXECUTABLE) SET(CMAKE_AR ${GCC_AR_EXECUTABLE}) SET(CMAKE_AR ${GCC_AR_EXECUTABLE} CACHE PATH "Alternative ar") ENDIF() IF(GCC_RANLIB_EXECUTABLE) SET(CMAKE_RANLIB ${GCC_RANLIB_EXECUTABLE}) SET(CMAKE_RANLIB ${GCC_RANLIB_EXECUTABLE} CACHE PATH "Alternative ranlib") ENDIF() IF (ALTERNATIVE_GCC AND ALTERNATIVE_GPP) SET(CMAKE_C_COMPILER ${ALTERNATIVE_GCC}) SET(CMAKE_CXX_COMPILER ${ALTERNATIVE_GPP}) MESSAGE(STATUS "Using ${ALTERNATIVE_GCC}") MESSAGE(STATUS "Using ${ALTERNATIVE_GPP}") # Use the new ABI so that std::string can be used with allocators # that are not default-constructible (e.g. Memroot_allocator) IF(LINUX_SUSE_12) ADD_DEFINITIONS(-D_GLIBCXX_USE_CXX11_ABI=1) ENDIF() ELSE() MESSAGE(WARNING "Could not find newer gcc.") IF(LINUX_SUSE_12) MESSAGE(FATAL_ERROR "Please do zypper install gcc10 gcc10-c++\n" "or set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER explicitly.") ELSE() MESSAGE(FATAL_ERROR "Please do zypper install gcc12 gcc12-c++\n" "or set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER explicitly.") ENDIF() ENDIF() ELSEIF(SOLARIS) MESSAGE(STATUS "Looking for GCC 10 on Solaris.") FIND_PROGRAM(ALTERNATIVE_GCC gcc NO_DEFAULT_PATH PATHS "/usr/gcc/10/bin") FIND_PROGRAM(ALTERNATIVE_GPP g++ NO_DEFAULT_PATH PATHS "/usr/gcc/10/bin") IF (ALTERNATIVE_GCC AND ALTERNATIVE_GPP) SET(CMAKE_C_COMPILER ${ALTERNATIVE_GCC}) SET(CMAKE_CXX_COMPILER ${ALTERNATIVE_GPP}) MESSAGE(STATUS "Using ${ALTERNATIVE_GCC}") MESSAGE(STATUS "Using ${ALTERNATIVE_GPP}") ELSE() MESSAGE(WARNING "Could not find /usr/gcc/10/bin/gcc") ENDIF() ENDIF() ENDIF() ENDIF() project(mysqlsh) IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang") SET(MY_COMPILER_IS_CLANG 1) ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "GNU") SET(MY_COMPILER_IS_GNU 1) IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9 AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8) SET(MY_COMPILER_IS_GNU_8 1) ENDIF() ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "SunPro") SET(MY_COMPILER_IS_SUNPRO 1) ENDIF() IF(MY_COMPILER_IS_CLANG OR MY_COMPILER_IS_GNU) SET(MY_COMPILER_IS_GNU_OR_CLANG 1) ENDIF() # Include the platform-specific file. To allow exceptions, this code # looks for files in order of how specific they are. If there is, for # example, a generic Linux.cmake and a version-specific # Linux-2.6.28-11-generic, it will pick Linux-2.6.28-11-generic and # include it. It is then up to the file writer to include the generic # version if necessary. FOREACH(_base ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_VERSION}-${CMAKE_SYSTEM_PROCESSOR} ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_VERSION} ${CMAKE_SYSTEM_NAME}) SET(_file ${CMAKE_SOURCE_DIR}/cmake/os/${_base}.cmake) IF(EXISTS ${_file}) INCLUDE(${_file}) BREAK() ENDIF() ENDFOREACH() IF(CMAKE_VERSION VERSION_GREATER "3.12.0") CMAKE_POLICY(SET CMP0075 NEW) ENDIF() set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH} ) IF(LINUX_RHEL10 AND MY_HOST_MACHINE_NAME MATCHES "aarch64") SET(CMAKE_POSITION_INDEPENDENT_CODE ON) MESSAGE(STATUS "Building with PIC") ENDIF() include(TestBigEndian) TEST_BIG_ENDIAN(IS_BIG_ENDIAN) add_definitions(-DIS_BIG_ENDIAN=${IS_BIG_ENDIAN}) ### Configuring package year IF(NOT PACKAGE_YEAR) SET(PACKAGE_YEAR "2025") ENDIF() add_definitions(-DPACKAGE_YEAR="${PACKAGE_YEAR}") IF(WITH_TESTS) ENABLE_TESTING() ENDIF() ### ### Initial configuration ### INCLUDE(version.cmake) ### ### Detect Stuff ### INCLUDE(link_options) INCLUDE(cpu_info) INCLUDE(install_macros) INCLUDE(exeutils) INCLUDE(libutils) INCLUDE(compiler) INCLUDE(static_analysis) include(compile_flags) INCLUDE(msvc) # Set correct search path for executables, libraries, and data files. IF(LINUX_RHEL) IF(ALTERNATIVE_GCC) GET_FILENAME_COMPONENT(GCC_B_PREFIX ${ALTERNATIVE_GCC} DIRECTORY) STRING_PREPEND(CMAKE_C_FLAGS "-B${GCC_B_PREFIX} ") ENDIF() IF(ALTERNATIVE_GPP) GET_FILENAME_COMPONENT(GPP_B_PREFIX ${ALTERNATIVE_GPP} DIRECTORY) STRING_PREPEND(CMAKE_CXX_FLAGS "-B${GPP_B_PREFIX} ") ENDIF() ENDIF() IF(CMAKE_C_FLAGS MATCHES " -flto" OR CMAKE_CXX_FLAGS MATCHES " -flto") SET(CMAKE_COMPILER_FLAG_WITH_LTO 1) ENDIF() include(CheckCSourceCompiles) include(CheckCXXSourceCompiles) FUNCTION(MY_CHECK_CXX_COMPILER_WARNING WARNING_OPTION RETURN_VALUE) # Strip off possible leading -Wno- or -W STRING(REGEX REPLACE "^-Wno-" "" WARNING_OPTION ${WARNING_OPTION}) STRING(REGEX REPLACE "^-W" "" WARNING_OPTION ${WARNING_OPTION}) STRING(REGEX MATCH "^error=" ERROR_PREFIX ${WARNING_OPTION}) # Use HAVE_CXX_W_warning_option as cache variable. STRING(REPLACE "-" "_" VAR_NAME ${WARNING_OPTION}) STRING(REPLACE "=" "_" VAR_NAME ${VAR_NAME}) STRING(REPLACE "c++" "cpp" VAR_NAME ${VAR_NAME}) SET(VAR_NAME "HAVE_CXX_W_${VAR_NAME}") IF(MY_COMPILER_IS_GNU_OR_CLANG) IF(SHOW_SUPPRESSED_COMPILER_WARNINGS AND NOT ERROR_PREFIX) MY_CHECK_CXX_COMPILER_FLAG("-Werror=${WARNING_OPTION}" ${VAR_NAME}) IF(${VAR_NAME}) SET(WARNING_OPTION "error=${WARNING_OPTION}") ENDIF() ENDIF() IF(NOT ${VAR_NAME}) MY_CHECK_CXX_COMPILER_FLAG("-W${WARNING_OPTION}" ${VAR_NAME}) ENDIF() ELSE() SET(${VAR_NAME} 0 CACHE INTERNAL "-W${WARNING_OPTION} not supported") ENDIF() IF(${VAR_NAME}) SET(${RETURN_VALUE} "-Wno-${WARNING_OPTION}" PARENT_SCOPE) ELSE() SET(${RETURN_VALUE} 0 PARENT_SCOPE) ENDIF() ENDFUNCTION() FUNCTION(GET_MAJOR_MINOR input_ver output_var) STRING(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*" "\\1.\\2" input_ver "${input_ver}") SET(${output_var} ${input_ver} PARENT_SCOPE) ENDFUNCTION() # Use lld for Clang if available and not explicitly disabled. # Also works for gcc on Debian/Ubuntu. Do 'apt install lld'. # LTO build fails with lld, so turn it off by default. IF(LINUX AND NOT WITH_LTO AND NOT CMAKE_COMPILER_FLAG_WITH_LTO) OPTION(USE_LD_LLD "Use llvm lld linker" ON) ELSE() OPTION(USE_LD_LLD "Use llvm lld linker" OFF) ENDIF() IF(USE_LD_LLD) CMAKE_PUSH_CHECK_STATE(RESET) # RPM builds on Fedora use -specs files. # This may cause the test for -fuse-ld=lld to succeed, when it should fail. SET(SAVE_CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) SET(SAVE_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) IF(CMAKE_C_FLAGS) STRING(REGEX REPLACE "-specs=/usr/lib/rpm/redhat/.*" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) ENDIF() IF(CMAKE_CXX_FLAGS) STRING(REGEX REPLACE "-specs=/usr/lib/rpm/redhat/.*" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) ENDIF() SET(CMAKE_REQUIRED_LIBRARIES "-fuse-ld=lld") CHECK_C_SOURCE_COMPILES("int main() {}" C_LD_LLD_RESULT) CHECK_CXX_SOURCE_COMPILES("int main() {}" CXX_LD_LLD_RESULT) IF(C_LD_LLD_RESULT AND CXX_LD_LLD_RESULT) FOREACH(flag CMAKE_C_LINK_FLAGS CMAKE_CXX_LINK_FLAGS CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS ) STRING_APPEND(${flag} " -fuse-ld=lld") ENDFOREACH() ENDIF() SET(CMAKE_C_FLAGS ${SAVE_CMAKE_C_FLAGS}) SET(CMAKE_CXX_FLAGS ${SAVE_CMAKE_CXX_FLAGS}) CMAKE_POP_CHECK_STATE() ENDIF() # Use gold on x86 if available and not explicitly disabled. # LTO build fails with gold, so turn it off by default. IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT WIN32 AND NOT WITH_LTO AND NOT CMAKE_COMPILER_FLAG_WITH_LTO) OPTION(USE_LD_GOLD "Use GNU gold linker" ON) ELSE() OPTION(USE_LD_GOLD "Use GNU gold linker" OFF) ENDIF() IF (USE_LD_GOLD AND NOT (C_LD_LLD_RESULT AND CXX_LD_LLD_RESULT)) CMAKE_PUSH_CHECK_STATE(RESET) SET(CMAKE_REQUIRED_LIBRARIES "-fuse-ld=gold") CHECK_C_SOURCE_COMPILES("int main() {}" C_LD_GOLD_RESULT) CHECK_CXX_SOURCE_COMPILES("int main() {}" CXX_LD_GOLD_RESULT) IF (C_LD_GOLD_RESULT AND CXX_LD_GOLD_RESULT AND NOT SOLARIS) STRING_APPEND(CMAKE_C_LINK_FLAGS " -fuse-ld=gold") STRING_APPEND(CMAKE_CXX_LINK_FLAGS " -fuse-ld=gold") # Seemingly --gc-sections causes problems with randomization, so only # turn it on if we are not making a randomized build. # The --gc-sections seems to be causing OOM errors when building 32-bit # binaries for Ubuntu 18.04, do not use it there. IF (NOT LINK_RANDOMIZE AND NOT LINUX_UBUNTU_18_04) STRING_APPEND(CMAKE_C_LINK_FLAGS " -Wl,--gc-sections") STRING_APPEND(CMAKE_CXX_LINK_FLAGS " -Wl,--gc-sections") ENDIF() ENDIF() CMAKE_POP_CHECK_STATE() ENDIF() # Linker/binutils bug in Fedora 28, undefined reference to symbol '__bss_start' # Similar bug on 32bit Ubuntu. # Fedora 34: undefined reference to symbol 'crc32_z@@ZLIB_1.2.9' IF(LINUX_FEDORA_28 OR LINUX_FEDORA_34 OR LINUX_UBUNTU_16_04) IF(NOT CMAKE_CXX_LINK_FLAGS MATCHES "-fuse-ld=lld" AND NOT CMAKE_CXX_LINK_FLAGS MATCHES "-fuse-ld=gold") STRING_APPEND(CMAKE_CXX_LINK_FLAGS " -Wl,--copy-dt-needed-entries") ENDIF() ENDIF() IF(LINUX) FIND_PROGRAM(PATCHELF_EXECUTABLE patchelf) IF(PATCHELF_EXECUTABLE) EXECUTE_PROCESS( COMMAND ${PATCHELF_EXECUTABLE} --version OUTPUT_VARIABLE PATCHELF_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) STRING(REPLACE "patchelf" "" PATCHELF_VERSION "${PATCHELF_VERSION}") MESSAGE(STATUS "Using patchelf: ${PATCHELF_EXECUTABLE}, version: ${PATCHELF_VERSION}") IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND PATCHELF_VERSION VERSION_LESS "0.14.5") SET(PATCHELF_PAGE_SIZE_ARGS --page-size 65536) ENDIF() ENDIF() ENDIF() include(fuzzer) INCLUDE(CheckIncludeFiles) INCLUDE(CheckFunctionExists) include(curl) MYSQL_CHECK_CURL() include(zlib) MYSQL_CHECK_ZLIB() IF (PYTHON_DEPS AND NOT HAVE_PYTHON) MESSAGE(FATAL_ERROR "PYTHON_DEPS should not be used when python is not available.") ENDIF() IF(BUNDLED_OPENSSL_DIR) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") # this will force the MYSQL_CHECK_SSL() macro to use shared libraries SET(LINUX_STANDALONE 1) ENDIF() SET(WITH_SSL "${BUNDLED_OPENSSL_DIR}") ELSE() SET(WITH_SSL "system") ENDIF() INCLUDE(ssl) MYSQL_CHECK_SSL() SET(OPENSSL_VERSION_ID "${OPENSSL_VERSION_MAJOR}${OPENSSL_VERSION_MINOR}${OPENSSL_FIX_VERSION}") ADD_DEFINITIONS(-DOPENSSL_VERSION_ID=${OPENSSL_VERSION_ID}) INCLUDE(bison) if(NOT BUILD_SOURCE_PACKAGE) if(BUNDLED_ANTLR_DIR) set(ANTLR4_INCLUDE_DIRS "${BUNDLED_ANTLR_DIR}/include") set(ANTLR4_LIBRARIES "${BUNDLED_ANTLR_DIR}/lib") else() find_package(antlr4-runtime REQUIRED) get_filename_component(ANTLR4_INCLUDE_DIRS ${ANTLR4_INCLUDE_DIR} DIRECTORY) set(ANTLR4_LIBRARIES "${ANTLR4_LIB_DIR}") unset(ANTLR4_FOUND) unset(ANTLR4_INCLUDE_DIR) unset(ANTLR4_LIB_DIR) endif() INCLUDE(FindANTLR4) if(NOT ANTLR4_INCLUDE_DIRS OR NOT ANTLR4_LIBRARIES) message(FATAL_ERROR "Could not find antlr4 runtime!") endif() if(NOT ANTLR4_VERSION_SHORT VERSION_EQUAL "4.10") # we're storing files generated by antlr4 4.10.1, patch version should not matter message(FATAL_ERROR "Required version of antlr4 runtime is 4.10") endif() endif() if(HAVE_PYTHON) SET(MINIMUM_PYTHON_VERSION "3.8") IF(NOT USE_PYTHON_VERSION) SET(USE_PYTHON_VERSION "${MINIMUM_PYTHON_VERSION}") ENDIF() IF(USE_PYTHON_VERSION VERSION_LESS MINIMUM_PYTHON_VERSION) MESSAGE(FATAL_ERROR "Minimum supported Python version is ${MINIMUM_PYTHON_VERSION}") ENDIF() FUNCTION(GET_PYTHON_VERSION python_dir output_var) FILE(GLOB_RECURSE patch_level "${python_dir}/patchlevel.h") IF(patch_level AND EXISTS "${patch_level}") FILE(STRINGS "${patch_level}" python_version_str REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") STRING(REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" python_version_str "${python_version_str}") SET(${output_var} "${python_version_str}" PARENT_SCOPE) ELSE() MESSAGE(FATAL_ERROR "Couldn't find patchlevel.h in ${python_dir}") ENDIF() ENDFUNCTION() # On windows stores the path to the python libraries since they will be bundled IF(WIN32) FIND_PACKAGE(PythonLibs "${USE_PYTHON_VERSION}" REQUIRED) # PYTHON_PATH and PYTHON_FOLDER are used to properly copy the python libraries where needed # By default they take the value of PB2WORKDIR and PYTHON_SOURCENAME env vars IF(NOT PYTHON_PATH AND NOT PYTHON_FOLDER) SET(PYTHON_PATH "$ENV{PB2WORKDIR}") SET(PYTHON_FOLDER "$ENV{PYTHON_SOURCENAME}") ENDIF() IF(NOT PYTHON_PATH AND NOT PYTHON_FOLDER) GET_FILENAME_COMPONENT(PYTHON_PATH ${PYTHON_INCLUDE_DIRS} DIRECTORY) GET_FILENAME_COMPONENT(PYTHON_FOLDER ${PYTHON_PATH} NAME) GET_FILENAME_COMPONENT(PYTHON_PATH ${PYTHON_PATH} DIRECTORY) ENDIF() IF(PYTHON_PATH AND PYTHON_FOLDER) SET(PYTHON_ROOT "${PYTHON_PATH}/${PYTHON_FOLDER}") FILE(TO_CMAKE_PATH "${PYTHON_ROOT}" PYTHON_ROOT) SET(PYTHON_LIBRARY_PATH "${PYTHON_ROOT}/Lib") SET(PYTHON_DLLS_PATH "${PYTHON_ROOT}/DLLs") SET(PYTHON_EXECUTABLE "${PYTHON_ROOT}/python.exe") ENDIF() ELSEIF(BUNDLED_PYTHON_DIR) # If we're using a Python build for bundling, ensure we build against it too GET_PYTHON_VERSION("${BUNDLED_PYTHON_DIR}" PYTHONLIBS_VERSION_STRING) GET_MAJOR_MINOR("${PYTHONLIBS_VERSION_STRING}" PYTHONLIBS_MAJOR_MINOR) FIND_PROGRAM(PYTHON_EXECUTABLE NAMES python${PYTHONLIBS_MAJOR_MINOR}mu python${PYTHONLIBS_MAJOR_MINOR}m python${PYTHONLIBS_MAJOR_MINOR}u python${PYTHONLIBS_MAJOR_MINOR} HINTS "${BUNDLED_PYTHON_DIR}/bin" NO_DEFAULT_PATH ) FIND_PATH(PYTHON_INCLUDE_DIRS NAMES Python.h HINTS "${BUNDLED_PYTHON_DIR}/include" PATH_SUFFIXES python${PYTHONLIBS_MAJOR_MINOR}mu python${PYTHONLIBS_MAJOR_MINOR}m python${PYTHONLIBS_MAJOR_MINOR}u python${PYTHONLIBS_MAJOR_MINOR} NO_DEFAULT_PATH ) FIND_LIBRARY(PYTHON_LIBRARIES NAMES python${PYTHONLIBS_MAJOR_MINOR}mu python${PYTHONLIBS_MAJOR_MINOR}m python${PYTHONLIBS_MAJOR_MINOR}u python${PYTHONLIBS_MAJOR_MINOR} HINTS "${BUNDLED_PYTHON_DIR}/lib" NO_DEFAULT_PATH ) IF(NOT PYTHON_LIBRARIES MATCHES ".*\\.a$") SET(BUNDLED_SHARED_PYTHON "YES") ENDIF() ELSE() FIND_PACKAGE(PythonLibs "${USE_PYTHON_VERSION}" REQUIRED) IF(NOT PYTHON_EXECUTABLE) # Can't use FIND_PACKAGE(Python ...) as it finds the latest Python interp and not the version we want GET_MAJOR_MINOR("${PYTHONLIBS_VERSION_STRING}" PYTHONLIBS_MAJOR_MINOR) FIND_PROGRAM(PYTHON_EXECUTABLE NAMES python${PYTHONLIBS_MAJOR_MINOR}mu python${PYTHONLIBS_MAJOR_MINOR}m python${PYTHONLIBS_MAJOR_MINOR}u python${PYTHONLIBS_MAJOR_MINOR} ) ENDIF() ENDIF() endif() IF (JIT_EXECUTOR_LIB) FIND_LIBRARY(JIT_EXECUTOR_LIBRARY NAMES jitexecutor HINTS "${JIT_EXECUTOR_LIB}" NO_DEFAULT_PATH) INCLUDE_DIRECTORIES(SYSTEM "${JIT_EXECUTOR_LIB}") MESSAGE(STATUS "Jit Executor Library: ${JIT_EXECUTOR_LIBRARY}") SET(HAVE_JS 1) SET(HAVE_JIT_EXECUTOR 1) ADD_DEFINITIONS(-DHAVE_JS) ADD_DEFINITIONS(-DHAVE_JIT_EXECUTOR) ENDIF() IF(WIN32) # Speed up build process excluding unused header files # Also definitely resolves the trouble of using both # windows.h and winsock2.h ADD_DEFINITIONS(-DWIN32_LEAN_AND_MEAN) ADD_DEFINITIONS(-DNOMINMAX) ADD_DEFINITIONS(-DNOGDI) ADD_DEFINITIONS(-DNOMB) ADD_DEFINITIONS(-DNOMEMMGR) ADD_DEFINITIONS(-DNOMETAFILE) ADD_DEFINITIONS(-DNOSCROLL) ADD_DEFINITIONS(-DNOSERVICE) ADD_DEFINITIONS(-DNOSOUND) ADD_DEFINITIONS(-DNOTEXTMETRIC) ADD_DEFINITIONS(-DNOWH) ADD_DEFINITIONS(-DNOWINOFFSETS) ADD_DEFINITIONS(-DNOCOMM) ADD_DEFINITIONS(-DNOKANJI) ADD_DEFINITIONS(-DNOHELP) ADD_DEFINITIONS(-DNOPROFILER) ADD_DEFINITIONS(-DNODEFERWINDOWPOS) ADD_DEFINITIONS(-DNOMCX) # Silence warnings about functions that are perfectly fine for posix ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) # Sets the windows versions that should be supported ADD_DEFINITIONS(-DNTDDI_VERSION=0x06000100 -D_WIN32_WINNT=0x0600) IF (MSVC) # Enable parallel builds ADD_COMPILE_OPTIONS(/MP) # Make sure source files and execution context are set to UTF8 ADD_COMPILE_OPTIONS(/utf-8) # Make sure we keep with the language standards conformance ADD_COMPILE_OPTIONS(/permissive-) ENDIF() ELSE() # Non windows builds should build dev packages by default SET(WITH_DEV "1") ENDIF() IF(PYTHONLIBS_FOUND OR BUNDLED_PYTHON_DIR) set(HAVE_PYTHON "YES") # Variable for CMake processing IF(BUNDLED_PYTHON_DIR) add_definitions(-DHAVE_PYTHON=2) # 2 means bundled ELSE() add_definitions(-DHAVE_PYTHON=1) # 1 means normal (or windows) ENDIF() message(STATUS "Python ${PYTHONLIBS_VERSION_STRING}") message(STATUS "PYTHON_EXECUTABLE: ${PYTHON_EXECUTABLE}") message(STATUS "PYTHON_INCLUDE_DIRS: ${PYTHON_INCLUDE_DIRS}") message(STATUS "PYTHON_LIBRARIES: ${PYTHON_LIBRARIES}") IF(NOT PYTHONLIBS_VERSION_STRING) MESSAGE(FATAL_ERROR "Couldn't detect Python's version") ENDIF() # supported Python versions: (v >= 3.8) IF(PYTHONLIBS_VERSION_STRING VERSION_LESS "3.8") MESSAGE(FATAL_ERROR "Python support requires Python 3.8 or greater") ENDIF() GET_MAJOR_MINOR("${PYTHONLIBS_VERSION_STRING}" PYTHONLIBS_MAJOR_MINOR) message(STATUS "Python major.minor: ${PYTHONLIBS_MAJOR_MINOR}") # TODO: Temporary flag indicating python is static as well # Proper logic should be added to correctly configure this IF(WITH_STATIC_MSVCRT) SET(WITH_STATIC_PYTHON_LIB 1) ENDIF() ELSE() message(WARNING "Python is unavailable: building without Python support.") ENDIF() # Sets default linking to static if not already defined if(NOT DEFINED MYSQLCLIENT_STATIC_LINKING) set(MYSQLCLIENT_STATIC_LINKING TRUE) endif() ### Bundling of OpenSSL libraries (if needed) # macro MYSQL_CHECK_SSL_DLLS() adapted for Shell IF (WITH_SSL_PATH AND (APPLE OR WIN32 OR LINUX_STANDALONE)) SET(BUNDLED_OPENSSL 1) MESSAGE(STATUS "WITH_SSL_PATH ${WITH_SSL_PATH}") # In MySQL Server 8.0.4 and up, OpenSSL is linked dynamically and # preferably linked against the system installed OpenSSL. But there # is no standard system installed OpenSSL on macOS or Windows so we # bundle the library copying it from the server install we link # against. IF(WIN32) GET_FILENAME_COMPONENT(CRYPTO_NAME "${CRYPTO_LIBRARY}" NAME_WE) GET_FILENAME_COMPONENT(OPENSSL_NAME "${OPENSSL_LIBRARY}" NAME_WE) # Different naming scheme for the matching .dll as of SSL 1.1 # OpenSSL 3.x Look for libcrypto-3-x64.dll or libcrypto-3.dll # OpenSSL 1.1 Look for libcrypto-1_1-x64.dll or libcrypto-1_1.dll # OpenSSL 1.0 Look for libeay32.dll SET(SSL_MSVC_VERSION_SUFFIX) SET(SSL_MSVC_ARCH_SUFFIX) IF(OPENSSL_VERSION_MINOR VERSION_EQUAL 1) SET(SSL_MSVC_VERSION_SUFFIX "-1_1") SET(SSL_MSVC_ARCH_SUFFIX "-x64") ENDIF() IF(OPENSSL_VERSION_MAJOR VERSION_EQUAL 3) SET(SSL_MSVC_VERSION_SUFFIX "-3") SET(SSL_MSVC_ARCH_SUFFIX "-x64") ENDIF() MESSAGE(STATUS "===> WITH_SSL_PATH: ${WITH_SSL_PATH}") MESSAGE(STATUS "===> CRYPTO_NAME: ${CRYPTO_NAME}") MESSAGE(STATUS "===> OPENSSL_NAME: ${OPENSSL_NAME}") MESSAGE(STATUS "===> SSL_MSVC_VERSION_SUFFIX: ${SSL_MSVC_VERSION_SUFFIX}") MESSAGE(STATUS "===> SSL_MSVC_ARCH_SUFFIX: ${SSL_MSVC_ARCH_SUFFIX}") FIND_FILE(HAVE_CRYPTO_DLL NAMES "${CRYPTO_NAME}${SSL_MSVC_VERSION_SUFFIX}${SSL_MSVC_ARCH_SUFFIX}.dll" "${CRYPTO_NAME}${SSL_MSVC_VERSION_SUFFIX}.dll" PATHS "${WITH_SSL_PATH}/bin" NO_DEFAULT_PATH ) FIND_FILE(HAVE_OPENSSL_DLL NAMES "${OPENSSL_NAME}${SSL_MSVC_VERSION_SUFFIX}${SSL_MSVC_ARCH_SUFFIX}.dll" "${OPENSSL_NAME}${SSL_MSVC_VERSION_SUFFIX}.dll" PATHS "${WITH_SSL_PATH}/bin" NO_DEFAULT_PATH ) MESSAGE(STATUS "HAVE_CRYPTO_DLL ${HAVE_CRYPTO_DLL}") MESSAGE(STATUS "HAVE_OPENSSL_DLL ${HAVE_OPENSSL_DLL}") ELSE() EXECUTE_PROCESS( COMMAND readlink "${CRYPTO_LIBRARY}" OUTPUT_VARIABLE CRYPTO_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) EXECUTE_PROCESS( COMMAND readlink "${OPENSSL_LIBRARY}" OUTPUT_VARIABLE OPENSSL_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) MESSAGE(STATUS "CRYPTO_VERSION ${CRYPTO_VERSION}") MESSAGE(STATUS "OPENSSL_VERSION ${OPENSSL_VERSION}") GET_FILENAME_COMPONENT(CRYPTO_DIRECTORY "${CRYPTO_LIBRARY}" DIRECTORY) GET_FILENAME_COMPONENT(OPENSSL_DIRECTORY "${OPENSSL_LIBRARY}" DIRECTORY) MESSAGE(STATUS "CRYPTO_DIRECTORY ${CRYPTO_DIRECTORY}") MESSAGE(STATUS "OPENSSL_DIRECTORY ${OPENSSL_DIRECTORY}") SET(CRYPTO_FULL_NAME "${CRYPTO_DIRECTORY}/${CRYPTO_VERSION}") SET(OPENSSL_FULL_NAME "${OPENSSL_DIRECTORY}/${OPENSSL_VERSION}") MESSAGE(STATUS "CRYPTO_FULL_NAME ${CRYPTO_FULL_NAME}") MESSAGE(STATUS "OPENSSL_FULL_NAME ${OPENSSL_FULL_NAME}") ENDIF() FIND_PATH(OPENSSL_MODULES_DIR NAMES ossl-modules NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH HINTS ${WITH_SSL_PATH} PATH_SUFFIXES lib lib64 ) IF(OPENSSL_MODULES_DIR) SET(OPENSSL_MODULES_DIR "${OPENSSL_MODULES_DIR}/ossl-modules") FILE(TO_CMAKE_PATH "${OPENSSL_MODULES_DIR}" OPENSSL_MODULES_DIR) MESSAGE(STATUS "OPENSSL_MODULES_DIR ${OPENSSL_MODULES_DIR}") IF(WIN32) SET(_module_ext "dll") ELSEIF(APPLE) SET(_module_ext "dylib") ELSE() SET(_module_ext "so") ENDIF() FILE(GLOB OPENSSL_MODULES_LIST "${OPENSSL_MODULES_DIR}/*.${_module_ext}") MESSAGE(STATUS "OPENSSL_MODULES_LIST ${OPENSSL_MODULES_LIST}") add_definitions(-DBUNDLE_OPENSSL_MODULES) ENDIF() ENDIF() if (NOT BUILD_SOURCE_PACKAGE) IF(NOT MYSQL_SOURCE_DIR) SET(MYSQL_SOURCE_DIR "../mysql" CACHE PATH "Path to MySQL source directory") MESSAGE(STATUS "MYSQL_SOURCE_DIR has been set to: ${MYSQL_SOURCE_DIR}") ENDIF() IF(NOT MYSQL_BUILD_DIR) SET(MYSQL_BUILD_DIR "${MYSQL_SOURCE_DIR}/bld" CACHE PATH "Path to MySQL build directory") MESSAGE(STATUS "MYSQL_BUILD_DIR has been set to: ${MYSQL_BUILD_DIR}") ENDIF() # Needed for protobuf header paths, which are needed to use libmysqlxclient INCLUDE(protobuf) INCLUDE(FindMySQLx) # Needed for X protocol error codes CONFIGURE_FILE(${MYSQL_SOURCE_DIR}/plugin/x/src/xpl_error.h ${CMAKE_SOURCE_DIR}/mysqlshdk/libs/db/mysqlx/xpl_error.h COPYONLY) INCLUDE(lz4) # Add lz4 library (Dependency for the X Client Lib) MYSQL_CHECK_LZ4() endif() ## ## Installation location ## SET(INSTALL_BINDIR "bin") IF(LIBEXECDIR) ADD_DEFINITIONS(-DLIBEXECDIR="${LIBEXECDIR}") SET(INSTALL_LIBEXECDIR "${LIBEXECDIR}/mysqlsh") ELSE() ADD_DEFINITIONS(-DLIBEXECDIR="libexec") SET(INSTALL_LIBEXECDIR "libexec/mysqlsh") ENDIF() SET(INSTALL_LIBDIR "lib/mysqlsh") IF(MYSQL_BUILD_DIR) SET(INSTALL_MYSQL_PLUGINS_DIR "lib/mysql/plugins") SET(_plugin_subdirs "${MYSQL_BUILD_DIR}/plugin_output_directory") SET(_plugin_ext "so") IF(WIN32) STRING(APPEND _plugin_subdirs "/${CMAKE_BUILD_TYPE}") SET(_plugin_ext "dll") ENDIF() FILE(GLOB AUTH_CLIENT_PLUGINS "${_plugin_subdirs}/authentication_*_client.${_plugin_ext}") IF(EXISTS "${_plugin_subdirs}/mysql_native_password.${_plugin_ext}") LIST(APPEND AUTH_CLIENT_PLUGINS "${_plugin_subdirs}/mysql_native_password.${_plugin_ext}") ENDIF() IF(AUTH_CLIENT_PLUGINS) SET(AUTH_CLIENT_PLUGINS_COPY ${AUTH_CLIENT_PLUGINS}) SET(EXPECTED_AUTH_CLIENT_PLUGINS "authentication_kerberos_client" "authentication_ldap_sasl_client" "authentication_oci_client" "authentication_openid_connect_client" "mysql_native_password" ) IF(${OPENSSL_MAJOR_MINOR_FIX_VERSION} VERSION_GREATER_EQUAL "1.1.1") IF(${MYSQL_VERSION} VERSION_GREATER_EQUAL "8.2.0") LIST(APPEND EXPECTED_AUTH_CLIENT_PLUGINS "authentication_webauthn_client") ENDIF() ENDIF() FOREACH(_plugin ${AUTH_CLIENT_PLUGINS}) FOREACH(_expected_plugin ${EXPECTED_AUTH_CLIENT_PLUGINS}) IF(_plugin MATCHES ".+${_expected_plugin}\..+") LIST(REMOVE_ITEM EXPECTED_AUTH_CLIENT_PLUGINS "${_expected_plugin}") LIST(REMOVE_ITEM AUTH_CLIENT_PLUGINS_COPY "${_plugin}") IF(_expected_plugin STREQUAL "authentication_webauthn_client") SET(_library_subdirs "${MYSQL_BUILD_DIR}/library_output_directory") IF(WIN32) STRING(APPEND _library_subdirs "/${CMAKE_BUILD_TYPE}") FILE(GLOB AUTH_CLIENT_PLUGINS_DEPS "${_library_subdirs}/fido2.dll") ELSEIF(APPLE) FILE(GLOB AUTH_CLIENT_PLUGINS_DEPS "${_library_subdirs}/libfido2*.dylib") ELSE() FILE(GLOB AUTH_CLIENT_PLUGINS_DEPS "${_library_subdirs}/libfido2.so*") ENDIF() IF(NOT AUTH_CLIENT_PLUGINS_DEPS) MESSAGE(FATAL_ERROR "Couldn't find libfido2, a dependency of authentication_webauthn_client") ENDIF() ENDIF() BREAK() ENDIF() ENDFOREACH() ENDFOREACH() IF(AUTH_CLIENT_PLUGINS_COPY) MESSAGE(FATAL_ERROR "Found unexpected client authentication plugins: ${AUTH_CLIENT_PLUGINS_COPY}") ENDIF() IF(EXPECTED_AUTH_CLIENT_PLUGINS) MESSAGE(FATAL_ERROR "Didn't find expected client authentication plugins: ${EXPECTED_AUTH_CLIENT_PLUGINS}") ENDIF() ADD_DEFINITIONS(-DDEFAULT_MYSQL_PLUGIN_DIR="${INSTALL_MYSQL_PLUGINS_DIR}") ENDIF() ENDIF() SET(INSTALL_INCLUDEDIR "include/mysqlsh") SET(INSTALL_SHAREDIR "share/mysqlsh") SET(INSTALL_DOCDIR "share/mysqlsh/Docs") SET(INSTALL_MANDIR "share/man") ## ## Binary location ## IF(MSVC) SET(CONFIG_BINARY_DIR "${CMAKE_BINARY_DIR}/$") ELSE() SET(CONFIG_BINARY_DIR "${CMAKE_BINARY_DIR}") ENDIF() ## ## Configure style system detection ## INCLUDE(configure.cmake) ## The following definition is required to have memset_s ## available on the platforms that implement it CHECK_FUNCTION_EXISTS (memset_s HAVE_MEMSET_S) IF (HAVE_MEMSET_S) ADD_DEFINITIONS(-D__STDC_WANT_LIB_EXT1__=1) ENDIF() CONFIGURE_FILE(mysh_config.h.cmake ${CMAKE_BINARY_DIR}/include/mysh_config.h) MACRO (MY_CHECK_CXX_COMPILER_FLAG FLAG RESULT) CMAKE_PUSH_CHECK_STATE() STRING_APPEND(CMAKE_REQUIRED_FLAGS " ${FLAG}") CHECK_CXX_SOURCE_COMPILES("int main(void) { return 0; }" ${RESULT} FAIL_REGEX "unknown argument ignored" FAIL_REGEX "argument unused during compilation" FAIL_REGEX "unsupported .*option" FAIL_REGEX "unknown .*option" FAIL_REGEX "unrecognized .*option" FAIL_REGEX "ignoring unknown option" FAIL_REGEX "[Ww]arning: [Oo]ption" FAIL_REGEX "error: visibility" FAIL_REGEX "warning: visibility" ) CMAKE_POP_CHECK_STATE() ENDMACRO() # By default the shell uses Multi-threaded Dynamic RunTime # Only sets Static if needed IF(WIN32) IF(WITH_STATIC_MSVCRT) FOREACH(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) IF(${flag_var} MATCHES "/MD") STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") ENDIF(${flag_var} MATCHES "/MD") ENDFOREACH(flag_var) ENDIF() ENDIF() # Set NDEBUG for non-debug project types. FOREACH(BUILD_TYPE RELEASE RELWITHDEBINFO MINSIZEREL) FOREACH(LANG C CXX) SET(CMAKE_${LANG}_FLAGS_${BUILD_TYPE} "${CMAKE_${LANG}_FLAGS_${BUILD_TYPE}} -DNDEBUG ") ENDFOREACH() ENDFOREACH() IF(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_GENERATOR MATCHES "Visual Studio" AND NOT CMAKE_GENERATOR MATCHES "Xcode") # This is the case of no CMAKE_BUILD_TYPE choosen, typical for VS and Xcode # or if custom C flags are set. In VS and Xcode for non-Debug configurations # NDEBUG is already correctly set. ADD_DEFINITIONS(-DNDEBUG) ENDIF() # Includes common to the whole project INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/ext ${MYSQL_INCLUDE_DIRS} ${MYSQLX_INCLUDE_DIRS} ${PROTOBUF_INCLUDE_DIRS} ${MYSQL_SOURCE_DIR}/extra/rapidjson/include SYSTEM ${ANTLR4_INCLUDE_DIRS}) ### ### Handle User Options ### if(BUNDLED_SSH_DIR) set(libssh_DIR ${BUNDLED_SSH_DIR}) endif() find_package(libssh 0.9.2 REQUIRED) message(STATUS "Found libssh: ${libssh_VERSION}, using config: ${libssh_CONFIG}") add_definitions(-DMYSH_VERSION="${MYSH_VERSION}" -DMYSH_BUILD_ID="${MYSH_BUILD_ID}" -DEXTRA_NAME_SUFFIX="${EXTRA_NAME_SUFFIX}") if(WIN32) add_definitions(-DMYSH_VERSION_WIN="${MYSH_VERSION_WIN}") endif() ## ## Prepares the python dependencies ### IF(PYTHON_DEPS) IF (NOT WIN32 AND NOT BUNDLED_PYTHON_DIR) # PYTHON_DEPS_PATH will cause the shell initialization to explicitly add the # bundled packages to the PYTHONPATH. # Only needed on this case, as when WIN32 or BUNDLED_PYTHON_DIR they are # automatically loaded by the site.py logic ADD_DEFINITIONS(-DPYTHON_DEPS_PATH="lib/python${PYTHONLIBS_MAJOR_MINOR}/site-packages") ENDIF() ADD_DEFINITIONS(-DPYTHON_DEPS) ENDIF() IF(NOT BUNDLED_MYSQLBINLOG) IF(WIN32) SET(BUNDLED_MYSQLBINLOG "${MYSQL_BUILD_DIR}/runtime_output_directory/${CMAKE_BUILD_TYPE}/mysqlbinlog.exe") ELSE() SET(BUNDLED_MYSQLBINLOG "${MYSQL_BUILD_DIR}/runtime_output_directory/mysqlbinlog") ENDIF() ENDIF() IF(NOT BUILD_SOURCE_PACKAGE AND NOT EXISTS "${BUNDLED_MYSQLBINLOG}") message(FATAL_ERROR "The bundled 'mysqlbinlog' binary was not found, please compile it using: cmake --build '${MYSQL_BUILD_DIR}' --target mysqlbinlog") ENDIF() IF(BUNDLED_MYSQL_CONFIG_EDITOR OR BUNDLED_MYSQLBINLOG) add_definitions(-DHAVE_LIBEXEC_DIR) ENDIF() IF(WITH_TESTS) ### ### Unit-test support ### add_subdirectory(unittest) add_subdirectory(tests/fuzz) ENDIF() ### ### Build Projects ### ADD_SUBDIRECTORY(plugins/external) ADD_SUBDIRECTORY(python) ADD_SUBDIRECTORY(mysqlshdk) ADD_SUBDIRECTORY(modules) ADD_SUBDIRECTORY(res) ADD_SUBDIRECTORY(src) add_subdirectory(samples) add_subdirectory(mysql-secret-store) add_subdirectory(tests/bench) IF(UNIX) ADD_SUBDIRECTORY(man) ENDIF() CHECK_STAN_OPTIONS() IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt) ADD_SUBDIRECTORY(internal) ENDIF() ### ### Optionally bundle Visual C++ Redistributable for Visual Studio ### if(WIN32) option(BUNDLE_RUNTIME_LIBRARIES "Install Windows runtime libraries" OFF) if(BUNDLE_RUNTIME_LIBRARIES) INSTALL_VS_REDIST(main) endif() endif() # # Create the INFO_SRC and INFO_BIN files # ========================= # # Will set GIT_EXECUTABLE and GIT_FOUND FIND_PACKAGE(Git) CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/cmake/info_macros.cmake.in ${CMAKE_BINARY_DIR}/info_macros.cmake @ONLY) INCLUDE(info_src) INSTALL(FILES ${CMAKE_BINARY_DIR}/Docs/INFO_SRC COMPONENT main DESTINATION ${INSTALL_DOCDIR}) IF (NOT BUILD_SOURCE_PACKAGE) INCLUDE(info_bin) INSTALL(FILES ${CMAKE_BINARY_DIR}/Docs/INFO_BIN COMPONENT main DESTINATION ${INSTALL_DOCDIR}) ENDIF() ### ### Packaging and other dependecy copying ### INCLUDE(packaging) if(CPACK_WIX_MYSQLSH_USE_CUSTOM_ACTION) add_subdirectory(packaging/wix4/custom_action) endif()