# Copyright (c) 2006, 2024, 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(WIN32) # Load policies. This is needed in order to parse the wmic version check. CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1) 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. # NOTE: # cmake >= 3.19 will use the new build system by default for Xcode >= 12.x IF(CMAKE_GENERATOR STREQUAL "Xcode") SET(APPLE_XCODE 1) 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.14.6) # 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) EXECUTE_PROCESS(COMMAND uname -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}") EXECUTE_PROCESS(COMMAND ${MY_CMAKE} --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) # Will set GIT_EXECUTABLE and GIT_FOUND FIND_PACKAGE(Git) SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) # First, decide about build type (debug or release) # If cmake is invoked with -DCMAKE_BUILD_TYPE, # respect user wishes and do not (re)define CMAKE_BUILD_TYPE. If WITH_DEBUG # is given, set CMAKE_BUILD_TYPE = Debug. Otherwise, use Relwithdebinfo. IF(DEFINED CMAKE_BUILD_TYPE) SET(HAVE_CMAKE_BUILD_TYPE TRUE) ENDIF() OPTION(WITH_DEBUG "Use dbug/safemutex" OFF) OPTION(CHECK_ERRMSG_FORMAT "Check printf format for English error messages" OFF) # Use a default manufacturer if no manufacturer was identified. SET(MANUFACTURER_DOCSTRING "Set the entity that appears as the manufacturer of packages that support a manufacturer field.") IF(NOT DEFINED MANUFACTURER) SET(MANUFACTURER "Built from Source" CACHE STRING ${MANUFACTURER_DOCSTRING}) MARK_AS_ADVANCED(MANUFACTURER) ENDIF() # MAX_INDEXES - Set the maximum number of indexes per table, default 64U IF (NOT MAX_INDEXES) SET(MAX_INDEXES 64U) ELSEIF(MAX_INDEXES MATCHES "^[0-9]+[Uu]?$") # MAX_INDEXES should be unsigned, so add the U suffix if it's missing. STRING(REGEX REPLACE "^([0-9]+).*$" "\\1U" MAX_INDEXES "${MAX_INDEXES}") MESSAGE(STATUS "Configuring with MAX_INDEXES = ${MAX_INDEXES}") ELSE() MESSAGE(FATAL_ERROR "MAX_INDEXES should be an unsigned integer.") ENDIF(NOT MAX_INDEXES) IF(MAX_INDEXES GREATER 255) MESSAGE(FATAL_ERROR "MAX_INDEXES values greater than 255 is not supported!") ELSEIF(MAX_INDEXES LESS 64) # Per documentation, ignore values less than 64 and use the default instead. MESSAGE(WARNING "MAX_INDEXES option ignored because it is less than 64.") SET(MAX_INDEXES 64U) ENDIF() # We choose to provide WITH_DEBUG as alias to standard CMAKE_BUILD_TYPE=Debug # which turns out to be not trivial, as this involves synchronization # between CMAKE_BUILD_TYPE and WITH_DEBUG. Besides, we have to deal with cases # where WITH_DEBUG is reset from ON to OFF and here we need to reset # CMAKE_BUILD_TYPE to either none or default RelWithDebInfo SET(BUILDTYPE_DOCSTRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel") IF(WITH_DEBUG) SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING ${BUILDTYPE_DOCSTRING} FORCE) SET(OLD_WITH_DEBUG 1 CACHE INTERNAL "" FORCE) ELSEIF(NOT HAVE_CMAKE_BUILD_TYPE OR OLD_WITH_DEBUG) IF(CMAKE_BUILD_TYPE MATCHES "Debug" OR NOT HAVE_CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING ${BUILDTYPE_DOCSTRING} FORCE) ENDIF() SET(OLD_WITH_DEBUG 0 CACHE INTERNAL "" FORCE) ENDIF() STRING(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_UPPER) IF(CMAKE_GENERATOR MATCHES "Visual Studio [1-9][0-9].*" AND CMAKE_GENERATOR_TOOLSET STREQUAL "") # Switch to 64 bit toolset on Windows (32 bit is default). # This is recommended as the 32 bit linker will run into address space issues # and not exit for long time. SET(CMAKE_GENERATOR_TOOLSET "host=x64") ENDIF() # On Linux el7/el8/el9 the default gcc is too old, # see if devtoolset/gcc-toolset is installed. # Same with SUSE linux 15, look for gcc 12 there. # We need to look for gcc before calling PROJECT below. OPTION(FORCE_UNSUPPORTED_COMPILER "Disable compiler version checks" OFF) MARK_AS_ADVANCED(WITHOUT_SERVER 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 ) EXECUTE_PROCESS(COMMAND ${MY_UNAME} -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() # See comments above, about CMAKE_MINIMUM_REQUIRED VERSION and macOS 11. IF(APPLE) IF(MY_HOST_SYSTEM_VERSION VERSION_GREATER_EQUAL 20) CMAKE_MINIMUM_REQUIRED(VERSION 3.18) ENDIF() ENDIF() # Add all policies *after* CMAKE_MINIMUM_REQUIRED # Repeating CMAKE_MINIMUM_REQUIRED here will load defaults for 3.5.1 CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1) INCLUDE(cmake_policies NO_POLICY_SCOPE) 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}") # Set LINUX_RHEL6, LINUX_RHEL7, LINUX_RHEL8 or LINUX_RHEL9 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) # /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 15" OR MY_OS_RELEASE MATCHES "openSUSE .* 15") SET(LINUX_SUSE_15 1) ELSE() MESSAGE(WARNING "Unknown SUSE version.") ENDIF() ENDIF() # In case we pick up values form the CACHE or from the command line. # See invokation of ADD_LINUX_RPM_FLAGS below. SET(INITIAL_CMAKE_C_FLAGS) SET(INITIAL_CMAKE_CXX_FLAGS) IF(DEFINED CMAKE_C_FLAGS) SET(INITIAL_CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) ENDIF() IF(DEFINED CMAKE_CXX_FLAGS) SET(INITIAL_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) 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) MESSAGE(STATUS "Looking for a devtoolset compiler") IF(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-12") 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 gcc-ar 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 gcc-ranlib 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_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-12-gcc gcc-toolset-12-gcc-c++ gcc-toolset-12-binutils") STRING_APPEND(DEV_PACKAGES " gcc-toolset-12-annobin-annocheck") STRING_APPEND(DEV_PACKAGES " gcc-toolset-12-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_SUSE_15) MESSAGE(STATUS "We need to look for a newer GCC on SUSE Linux.") IF(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}") ELSE() MESSAGE(WARNING "Could not find newer gcc.") MESSAGE(FATAL_ERROR "Please do zypper install gcc12 gcc12-c++\n" "or set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER explicitly.") 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() # Optionally set project name, e.g. # foo.xcodeproj (mac) or foo.sln (windows) SET(MYSQL_PROJECT_NAME_DOCSTRING "MySQL project name") IF(DEFINED MYSQL_PROJECT_NAME) SET(MYSQL_PROJECT_NAME ${MYSQL_PROJECT_NAME} CACHE STRING ${MYSQL_PROJECT_NAME_DOCSTRING} FORCE) ELSE() SET(MYSQL_PROJECT_NAME "MySQL" CACHE STRING ${MYSQL_PROJECT_NAME_DOCSTRING} FORCE) MARK_AS_ADVANCED(MYSQL_PROJECT_NAME) ENDIF() # Handle upgrade of old cmake cache IF(DEFINED WITH_PLUGIN_NDBCLUSTER) IF(NOT WITH_NDBCLUSTER) IF(WITH_PLUGIN_NDBCLUSTER OR WITH_NDBCLUSTER_STORAGE_ENGINE) MESSAGE(FATAL_ERROR "Old broken config, WITH_NDBCLUSTER_STORAGE_ENGINE have changed " "meaning, to build MySQL Cluster please add -DWITH_NDB=ON and " "-UWITH_PLUGIN_NDBCLUSTER") ENDIF() ENDIF() ENDIF() # Allow WITH_NDBCLUSTER, makes it possible to bisect between # old and new source code and use cmake -DWITH_NDBCLUSTER=xx for both. # If both WITH_NDB and WITH_NDBCLUSTER is set they must be equal. # Else WITH_NDB is set as WITH_NDBCLUSTER. # WITH_NDBCLUSTER is unset and not cached to not intefere with # legacy logic in MYSQL_ADD_PLUGIN. IF(DEFINED WITH_NDBCLUSTER) SET(HAVE_WITH_NDBCLUSTER 1) IF(DEFINED WITH_NDB) # The extra NOTs are needed to normalize the boolean values else for # example ON is not treated equal to 1. IF(NOT (NOT WITH_NDB) EQUAL (NOT WITH_NDBCLUSTER)) MESSAGE(FATAL_ERROR "WITH_NDB=${WITH_NDB} do not match WITH_NDBCLUSTER=${WITH_NDBCLUSTER}") ENDIF() SET(WITH_NDB_DEFAULT OFF) ELSEIF(WITH_NDBCLUSTER) MESSAGE(WARNING "WITH_NDBCLUSTER option is deprecated, please use " "WITH_NDB instead. For backward compatibility WITH_NDBCLUSTER=ON sets " "WITH_NDB=ON") SET(WITH_NDB_DEFAULT ON) ELSE() SET(WITH_NDB_DEFAULT OFF) ENDIF() # Unset WITH_NDBCLUSTER to not intefere with MYSQL_ADD_PLUGIN logic. # It will be added to cache at end of this file. UNSET(WITH_NDBCLUSTER CACHE) ELSE() SET(WITH_NDB_DEFAULT OFF) ENDIF() OPTION(WITH_NDB "Build MySQL Cluster" ${WITH_NDB_DEFAULT}) IF(WITH_NDB) MESSAGE(STATUS "Building MySQL Cluster") ENDIF() MESSAGE(STATUS "CMAKE_MODULE_PATH is ${CMAKE_MODULE_PATH}") INCLUDE(mysql_version) PROJECT(${MYSQL_PROJECT_NAME} VERSION ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}) GET_FILENAME_COMPONENT(REALPATH_CMAKE_SOURCE_DIR ${CMAKE_SOURCE_DIR} REALPATH) GET_FILENAME_COMPONENT(REALPATH_CMAKE_BINARY_DIR ${CMAKE_BINARY_DIR} REALPATH) MESSAGE(STATUS "Source directory ${REALPATH_CMAKE_SOURCE_DIR}") MESSAGE(STATUS "Binary directory ${REALPATH_CMAKE_BINARY_DIR}") # IN PB2 we have a few configurations which are built in-source (e.g. doxygen). IF(DEFINED ENV{PB2WORKDIR}) OPTION(FORCE_INSOURCE_BUILD "Allow in-source build" ON) ELSE() OPTION(FORCE_INSOURCE_BUILD "Allow in-source build" OFF) ENDIF() # https://gitlab.kitware.com/cmake/community/wikis/FAQ # cmake-does-not-generate-a-make-distclean-target-why # Why disallow in-source build? # Basically because 'make clean' or 'make distclean' do not work. # So if you do a 'git pull' you may end up with a developer sandbox # that no longer works as expected (CMakeCache.txt and other # generated/configured files may contain data which is no longer valid) SET(THIS_IS_AN_IN_SOURCE_BUILD FALSE) IF(${REALPATH_CMAKE_SOURCE_DIR} STREQUAL ${REALPATH_CMAKE_BINARY_DIR}) SET(THIS_IS_AN_IN_SOURCE_BUILD TRUE) IF(FORCE_INSOURCE_BUILD) MESSAGE(WARNING "This is an in-source build") ELSE() MESSAGE(FATAL_ERROR "Please do not build in-source. " "Out-of source builds are highly recommended: " "you can have multiple builds for the same source, " "and there is an easy way to do cleanup, " "simply remove the build directory " "(note that 'make clean' or 'make distclean' does *not* work) " "\nYou *can* force in-source build by invoking cmake with -DFORCE_INSOURCE_BUILD=1") ENDIF() ENDIF() IF(WIN32) STRING(LENGTH "${REALPATH_CMAKE_BINARY_DIR}" CMAKE_BINARY_DIR_LENGTH) IF(CMAKE_BINARY_DIR_LENGTH LESS_EQUAL 3) MESSAGE(FATAL_ERROR "It seems your build directory ${CMAKE_BINARY_DIR} is a filesystem root, " "this is not supported. Please build in a subdirectory.") ENDIF() ENDIF() MACRO(REPORT_CXX_FLAGS) MESSAGE(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") FOREACH(BUILD_TYPE "" _DEBUG _RELWITHDEBINFO _RELEASE _MINSIZEREL) SET(flag "CMAKE_CXX_FLAGS${BUILD_TYPE}") MESSAGE(STATUS "${flag}: ${${flag}}") ENDFOREACH() ENDMACRO() # Write content to file, using CONFIGURE_FILE # The advantage compared to FILE(WRITE) is that timestamp # does not change if file already has the same content SET(MYSQL_CMAKE_SCRIPT_DIR "${CMAKE_SOURCE_DIR}/cmake") MACRO(CONFIGURE_FILE_CONTENT content file) SET(CMAKE_CONFIGURABLE_FILE_CONTENT "${content}\n") CONFIGURE_FILE( ${MYSQL_CMAKE_SCRIPT_DIR}/configurable_file_content.in ${file} @ONLY) ENDMACRO() SET(BUILD_IS_SINGLE_CONFIG TRUE) MESSAGE(STATUS "CMAKE_GENERATOR: ${CMAKE_GENERATOR}") IF(CMAKE_GENERATOR MATCHES "Visual Studio" OR CMAKE_GENERATOR STREQUAL "Xcode") SET(BUILD_IS_SINGLE_CONFIG FALSE) ENDIF() 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) ENDIF() IF(MY_COMPILER_IS_CLANG OR MY_COMPILER_IS_GNU) SET(MY_COMPILER_IS_GNU_OR_CLANG 1) ENDIF() # Maintainer mode is default on only for debug builds using GCC/G++ IF(CMAKE_BUILD_TYPE_UPPER STREQUAL "DEBUG" OR WITH_DEBUG) IF(MY_COMPILER_IS_GNU) SET(MYSQL_MAINTAINER_MODE ON CACHE BOOL "MySQL maintainer-specific development environment") ENDIF() ENDIF() OPTION(WITH_DEFAULT_COMPILER_OPTIONS "Use flags from cmake/build_configurations/compiler_options.cmake" ON) IF(BUILD_CONFIG) INCLUDE( ${CMAKE_SOURCE_DIR}/cmake/build_configurations/${BUILD_CONFIG}.cmake) ENDIF() OPTION(INSTALL_STATIC_LIBRARIES "Install static libraries" ON) #cmake on 64bit windows/mac/solaris doesn't set CMAKE_SYSTEM_PROCESSOR correctly SET(MYSQL_MACHINE_TYPE ${CMAKE_SYSTEM_PROCESSOR}) SET(KNOWN_64BIT_ARCHITECTURES arm64 aarch64 ppc64 ppc64le s390x x86_64 ) # 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() # Following autotools tradition, add preprocessor definitions # specified in environment variable CPPFLAGS IF(DEFINED ENV{CPPFLAGS}) ADD_DEFINITIONS($ENV{CPPFLAGS}) ENDIF() INCLUDE(CheckTypeSize) CHECK_TYPE_SIZE("void *" SIZEOF_VOIDP) MESSAGE(STATUS "SIZEOF_VOIDP ${SIZEOF_VOIDP}") # On some platforms, cmake may think that CMAKE_SIZEOF_VOID_P == 4 # even if we have configured for 64bit build.... SET(CMAKE_SIZEOF_VOID_P ${SIZEOF_VOIDP}) IF(NOT SIZEOF_VOIDP EQUAL 8) MESSAGE(FATAL_ERROR "MySQL supports only 64-bit platforms.") ENDIF() INCLUDE(compile_flags) INCLUDE(install_layout) IF(WITH_ASAN OR WITH_LSAN OR WITH_MSAN OR WITH_TSAN OR WITH_UBSAN) SET(WITH_SOME_SANITIZER ON) ELSE() SET(WITH_SOME_SANITIZER OFF) ENDIF() # Add RPM or DEB platform flags for STANDALONE build. # Not for DEBUG builds, since both platforms use -O2 and _FORTIFY_SOURCE. # Not for Release or MinSizeRel, it will inflate binary sizes. IF(LINUX_STANDALONE AND (LINUX_DEB_PLATFORM OR LINUX_RPM_PLATFORM)) # Do not add FORTIFY_SOURCE to any of the sanitizers # https://github.com/google/sanitizers/issues/247 IF(WITH_SOME_SANITIZER) SET(WITH_PACKAGE_FLAGS_DEFAULT OFF) ELSEIF(CMAKE_BUILD_TYPE_UPPER STREQUAL "DEBUG" OR WITH_DEBUG) SET(WITH_PACKAGE_FLAGS_DEFAULT OFF) ELSEIF(CMAKE_BUILD_TYPE_UPPER STREQUAL "RELWITHDEBINFO") SET(WITH_PACKAGE_FLAGS_DEFAULT ON) ELSE() SET(WITH_PACKAGE_FLAGS_DEFAULT OFF) ENDIF() OPTION(WITH_PACKAGE_FLAGS "Use DEB/RPM compiler flags" ${WITH_PACKAGE_FLAGS_DEFAULT}) ENDIF() # Do not set package specific flags if language flags already provided # in environment or on command line. # And only for gcc (not clang). IF(MY_COMPILER_IS_GNU AND WITH_PACKAGE_FLAGS AND NOT INITIAL_CMAKE_C_FLAGS AND NOT INITIAL_CMAKE_CXX_FLAGS) IF(LINUX_RPM_PLATFORM) IF(MY_RPM) ADD_LINUX_RPM_FLAGS() ELSE() MESSAGE(WARNING "rpm executable not found") ENDIF() ELSEIF(LINUX_DEB_PLATFORM) IF(MY_DPKG_BUILDFLAGS) ADD_LINUX_DEB_FLAGS() ELSE() MESSAGE(WARNING "dpkg-buildflags executable not found") MESSAGE(WARNING "Please do 'apt install dpkg-dev'") ENDIF() ENDIF() ENDIF() IF(WITH_DEFAULT_COMPILER_OPTIONS) INCLUDE(${CMAKE_SOURCE_DIR}/cmake/build_configurations/compiler_options.cmake) ENDIF() # Assume, for now at least, that we want build-id for all kinds of Linux builds. IF(LINUX AND NOT LINUX_ALPINE) OPTION(WITH_BUILD_ID "Add --build-id=sha1 to all executables." ON) IF(WITH_BUILD_ID) SET(HAVE_BUILD_ID_SUPPORT 1) FIND_PROGRAM(READELF_EXECUTABLE NAMES eu-readelf readelf ) IF(NOT READELF_EXECUTABLE) MESSAGE(WARNING "Cannot find eu-readelf or readelf") MESSAGE(FATAL_ERROR "Install the 'elfutils' package, or do cmake -DWITH_BUILD_ID=OFF") ENDIF() ENDIF() ENDIF() INCLUDE(CMakePushCheckState) # Add macros INCLUDE(add_custom_target) INCLUDE(pkg-config) INCLUDE(character_sets) INCLUDE(link_options) INCLUDE(malloc_utils) INCLUDE(cpu_info) INCLUDE(fileutils) INCLUDE(zlib) INCLUDE(zstd) INCLUDE(lz4) INCLUDE(icu) INCLUDE(libbacktrace) INCLUDE(ssl) INCLUDE(sasl) INCLUDE(ldap) INCLUDE(kerberos) INCLUDE(rpc) INCLUDE(readline) INCLUDE(protobuf) INCLUDE(package_name) INCLUDE(libutils) INCLUDE(plugin) INCLUDE(component) INCLUDE(install_macros) INCLUDE(mysql_add_executable) INCLUDE(curl) INCLUDE(rapidjson) INCLUDE(fprofile) INCLUDE(fido2) INCLUDE(win_jemalloc) INCLUDE(libs_mysql_create_library) INCLUDE(libcno) # To simplify building of JET, skip all dependencies for other targets. IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt) OPTION(WITH_JET_ONLY "Build JET only. No C/C++ targets." OFF) IF(WITH_JET_ONLY) SET(WITH_JET ON) SET(WITH_JET ON CACHE INTERNAL "Build JET" FORCE) ADD_SUBDIRECTORY(internal/jet) RETURN() ENDIF() ENDIF() IF(UNIX) OPTION(WITH_VALGRIND "Valgrind instrumentation" OFF) ENDIF() OPTION(WITH_TCMALLOC "Use tcmalloc rather than builtin malloc/free etc." OFF) OPTION(WITH_TCMALLOC_DEBUG "Use tcmalloc_debug rather than builtin malloc/free etc." OFF) IF(WITH_TCMALLOC OR WITH_TCMALLOC_DEBUG) # Note that libtcmalloc.so reports lots of Mismatched free()/delete/delete[] # So for valgrind builds, link with libtcmalloc_debug.so IF(WITH_VALGRIND OR WITH_TCMALLOC_DEBUG) FIND_MALLOC_LIBRARY(tcmalloc_debug) ELSE() FIND_MALLOC_LIBRARY(tcmalloc) ENDIF() ENDIF() OPTION(WITH_JEMALLOC "Use jemalloc rather than builtin malloc/free etc." OFF) IF(WITH_JEMALLOC) FIND_MALLOC_LIBRARY(jemalloc) ENDIF() IF(WITH_JEMALLOC AND (WITH_TCMALLOC OR WITH_TCMALLOC_DEBUG)) MESSAGE(FATAL_ERROR "Specify only *one* of WITH_TCMALLOC and WITH_JEMALLOC") ENDIF() OPTION(ENABLED_PROFILING "Enable profiling" ON) OPTION(WITHOUT_SERVER OFF) IF(WIN32) OPTION(WITH_MSCRT_DEBUG "MS Visual Studio Debug CRT instrumentation" OFF) ENDIF() IF(NOT WITHOUT_SERVER) IF(FPROFILE_GENERATE OR FPROFILE_USE) # Do not use data from unit testing when optimizing. OPTION(WITH_UNIT_TESTS "Compile MySQL with unit tests" OFF) ELSE() OPTION(WITH_UNIT_TESTS "Compile MySQL with unit tests" ON) ENDIF() OPTION(WITH_ROUTER "Build MySQL Router" ON) ENDIF() IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt) SET(WITH_INTERNAL_DEFAULT 1) ELSE() SET(WITH_INTERNAL_DEFAULT 0) ENDIF() IF(NOT DEFINED WITH_INTERNAL) SET(WITH_INTERNAL ${WITH_INTERNAL_DEFAULT}) ENDIF() # On windows we need a non-standard package for SASL. IF(WITH_INTERNAL AND (NOT WIN32 OR WITH_SASL)) SET(WITH_AUTHENTICATION_LDAP_DEFAULT ON) ELSE() SET(WITH_AUTHENTICATION_LDAP_DEFAULT OFF) ENDIF() OPTION(WITH_AUTHENTICATION_LDAP "Report error if the LDAP authentication plugin cannot be built." ${WITH_AUTHENTICATION_LDAP_DEFAULT}) # Currently only supported on Linux IF(WITH_INTERNAL AND LINUX) SET(WITH_AUTHENTICATION_KERBEROS_DEFAULT ON) ELSE() SET(WITH_AUTHENTICATION_KERBEROS_DEFAULT OFF) ENDIF() OPTION(WITH_AUTHENTICATION_KERBEROS "Report error if the Kerberos authentication plugin cannot be built." ${WITH_AUTHENTICATION_KERBEROS_DEFAULT}) IF(WITH_INTERNAL AND (NOT SOLARIS)) SET(WITH_AUTHENTICATION_WEBAUTHN_DEFAULT ON) ELSE() SET(WITH_AUTHENTICATION_WEBAUTHN_DEFAULT OFF) ENDIF() IF(WITH_INTERNAL) SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/internal/cmake) ENDIF() OPTION(WITH_AUTHENTICATION_WEBAUTHN "Report error if the WEBAUTHN authentication plugin cannot be built." ${WITH_AUTHENTICATION_WEBAUTHN_DEFAULT}) # Default ON if we are building server-side plugins. # Also default ON in pushbuild, for our community builds. IF(WITH_AUTHENTICATION_KERBEROS OR WITH_AUTHENTICATION_LDAP OR WITH_AUTHENTICATION_WEBAUTHN OR DEFINED ENV{PB2WORKDIR}) SET(WITH_AUTHENTICATION_CLIENT_PLUGINS_DEFAULT ON) ELSE() SET(WITH_AUTHENTICATION_CLIENT_PLUGINS_DEFAULT OFF) ENDIF() # Enable building of # The KERBEROS client authentication plugin # authentication_kerberos_client.so # The LDAP client authentication plugin # authentication_ldap_sasl_client.so # The WEBAUTHN client authentication plugin # authentication_webauthn_client.so # The OCI client authentication plugin # authentication_oci_client.so OPTION(WITH_AUTHENTICATION_CLIENT_PLUGINS "Build client-side authentication plugins, even if server-side are disabled" ${WITH_AUTHENTICATION_CLIENT_PLUGINS_DEFAULT}) IF(NOT WITH_AUTHENTICATION_WEBAUTHN AND NOT WITH_AUTHENTICATION_CLIENT_PLUGINS) SET(WITH_FIDO "none") SET(WITH_FIDO "none" CACHE STRING "fido2 is disabled") ENDIF() IF(WITH_INTERNAL) IF(UNIX) SET(WITH_CURL_DEFAULT "system") ELSE() SET(WITH_CURL_DEFAULT "bundled") ENDIF() ELSE() SET(WITH_CURL_DEFAULT "none") ENDIF() OPTION(WITH_LOCK_ORDER "Build the lock order mutex instrumentation code." OFF) IF(WITH_LOCK_ORDER) EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E make_directory lock_order WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) ENDIF() IF(DEFINED WITH_LTO_DEFAULT) SET(WITH_LTO_DEFAULT ${WITH_LTO_DEFAULT}) ELSE() SET(WITH_LTO_DEFAULT OFF) ENDIF() OPTION(WITH_LTO "Enable the link-time optimizer. Currently works for gcc7/gcc8/gcc9/macos only." ${WITH_LTO_DEFAULT} ) IF(CMAKE_C_FLAGS MATCHES " -flto" OR CMAKE_CXX_FLAGS MATCHES " -flto") SET(CMAKE_COMPILER_FLAG_WITH_LTO 1) ENDIF() include(CheckCSourceCompiles) include(CheckCXXSourceCompiles) # We need some extra FAIL_REGEX patterns # Note that CHECK_C_SOURCE_COMPILES is a misnomer, it will also link. MACRO (MY_CHECK_C_COMPILER_FLAG FLAG RESULT) CMAKE_PUSH_CHECK_STATE() STRING_APPEND(CMAKE_REQUIRED_FLAGS " ${FLAG}") CHECK_C_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() 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() # Check whether a specific warning option is supported. # Intended use is primarily to silence warnings from third-party code. # If *our* code has warnings with gcc[56789] or clang[345678] the # code should be fixed, rather than silencing the compiler warnings. # # Returns the corresponding "-Wno-