1# Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. 2# 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; version 2 of the License. 6# 7# This program is distributed in the hope that it will be useful, 8# but WITHOUT ANY WARRANTY; without even the implied warranty of 9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10# GNU General Public License for more details. 11# 12# You should have received a copy of the GNU General Public License 13# along with this program; if not, write to the Free Software 14# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA 15 16# This file includes Windows specific hacks, mostly around compiler flags 17 18INCLUDE (CheckCSourceCompiles) 19INCLUDE (CheckCXXSourceCompiles) 20INCLUDE (CheckStructHasMember) 21INCLUDE (CheckLibraryExists) 22INCLUDE (CheckFunctionExists) 23INCLUDE (CheckCSourceRuns) 24INCLUDE (CheckSymbolExists) 25INCLUDE (CheckTypeSize) 26 27 28# avoid running system checks by using pre-cached check results 29# system checks are expensive on VS since every tiny program is to be compiled in 30# a VC solution. 31GET_FILENAME_COMPONENT(_SCRIPT_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) 32INCLUDE(${_SCRIPT_DIR}/WindowsCache.cmake) 33 34 35# OS display name (version_compile_os etc). 36# Used by the test suite to ignore bugs on some platforms, 37IF(CMAKE_SIZEOF_VOID_P MATCHES 8) 38 SET(SYSTEM_TYPE "Win64") 39ELSE() 40 SET(SYSTEM_TYPE "Win32") 41ENDIF() 42 43# Intel compiler is almost Visual C++ 44# (same compile flags etc). Set MSVC flag 45IF(CMAKE_C_COMPILER MATCHES "icl") 46 SET(MSVC TRUE) 47ENDIF() 48 49IF(MSVC AND CMAKE_CXX_COMPILER_ID MATCHES Clang) 50 SET(CLANG_CL TRUE) 51ENDIF() 52 53ADD_DEFINITIONS(-D_WINDOWS -D__WIN__ -D_CRT_SECURE_NO_DEPRECATE) 54ADD_DEFINITIONS(-D_WIN32_WINNT=0x0A00) 55# We do not want the windows.h macros min/max 56ADD_DEFINITIONS(-DNOMINMAX) 57# Speed up build process excluding unused header files 58ADD_DEFINITIONS(-DWIN32_LEAN_AND_MEAN) 59 60# Adjust compiler and linker flags 61IF(MINGW AND CMAKE_SIZEOF_VOID_P EQUAL 4) 62 # mininal architecture flags, i486 enables GCC atomics 63 ADD_DEFINITIONS(-march=i486) 64ENDIF() 65 66MACRO(ENABLE_SANITIZERS) 67 IF(NOT MSVC) 68 MESSAGE(FATAL_ERROR "clang-cl or MSVC necessary to enable asan/ubsan") 69 ENDIF() 70 # currently, asan is broken with static CRT. 71 IF(CLANG_CL AND NOT(MSVC_CRT_TYPE STREQUAL "/MD")) 72 SET(MSVC_CRT_TYPE "/MD" CACHE INTERNAL "" FORCE) 73 ENDIF() 74 IF(CMAKE_SIZEOF_VOID_P EQUAL 4) 75 SET(ASAN_ARCH i386) 76 ELSE() 77 SET(ASAN_ARCH x86_64) 78 ENDIF() 79 80 # After installation, clang lib directory should be added to PATH 81 # (e.g C:/Program Files/LLVM/lib/clang/5.0.1/lib/windows) 82 SET(SANITIZER_LIBS) 83 SET(SANITIZER_LINK_LIBRARIES) 84 SET(SANITIZER_COMPILE_FLAGS) 85 IF(WITH_ASAN) 86 IF(CLANG_CL) 87 LIST(APPEND SANITIZER_LIBS 88 clang_rt.asan_dynamic-${ASAN_ARCH}.lib clang_rt.asan_dynamic_runtime_thunk-${ASAN_ARCH}.lib) 89 ENDIF() 90 STRING(APPEND SANITIZER_COMPILE_FLAGS " -fsanitize=address") 91 ENDIF() 92 IF(WITH_UBSAN) 93 STRING(APPEND SANITIZER_COMPILE_FLAGS " -fsanitize=undefined -fno-sanitize=alignment") 94 ENDIF() 95 FOREACH(lib ${SANITIZER_LIBS}) 96 FIND_LIBRARY(${lib}_fullpath ${lib}) 97 IF(NOT ${lib}_fullpath) 98 MESSAGE(FATAL_ERROR "Can't enable sanitizer : missing ${lib}") 99 ENDIF() 100 LIST(APPEND CMAKE_REQUIRED_LIBRARIES ${${lib}_fullpath}) 101 STRING(APPEND CMAKE_C_STANDARD_LIBRARIES " \"${${lib}_fullpath}\" ") 102 STRING(APPEND CMAKE_CXX_STANDARD_LIBRARIES " \"${${lib}_fullpath}\" ") 103 ENDFOREACH() 104 STRING(APPEND CMAKE_C_FLAGS ${SANITIZER_COMPILE_FLAGS}) 105 STRING(APPEND CMAKE_CXX_FLAGS ${SANITIZER_COMPILE_FLAGS}) 106ENDMACRO() 107 108 109IF(MSVC) 110 IF(MSVC_VERSION LESS 1920) 111 MESSAGE(FATAL_ERROR "Visual Studio q2019 or later is required") 112 ENDIF() 113 # Disable mingw based pkg-config found in Strawberry perl 114 SET(PKG_CONFIG_EXECUTABLE 0 CACHE INTERNAL "") 115 116 SET(MSVC_CRT_TYPE /MT CACHE STRING 117 "Runtime library - specify runtime library for linking (/MT,/MTd,/MD,/MDd)" 118 ) 119 SET(VALID_CRT_TYPES /MTd /MDd /MD /MT) 120 IF (NOT ";${VALID_CRT_TYPES};" MATCHES ";${MSVC_CRT_TYPE};") 121 MESSAGE(FATAL_ERROR "Invalid value ${MSVC_CRT_TYPE} for MSVC_CRT_TYPE, choose one of /MT,/MTd,/MD,/MDd ") 122 ENDIF() 123 124 IF(MSVC_CRT_TYPE MATCHES "/MD") 125 # Dynamic runtime (DLLs), need to install CRT libraries. 126 SET(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT VCCRT) 127 SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS TRUE) 128 IF(MSVC_CRT_TYPE STREQUAL "/MDd") 129 SET (CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY TRUE) 130 ENDIF() 131 INCLUDE(InstallRequiredSystemLibraries) 132 ENDIF() 133 134 IF(WITH_ASAN AND (NOT CLANG_CL)) 135 SET(DYNAMIC_UCRT_LINK_DEFAULT OFF) 136 ELSE() 137 SET(DYNAMIC_UCRT_LINK_DEFAULT ON) 138 ENDIF() 139 140 OPTION(DYNAMIC_UCRT_LINK "Link Universal CRT dynamically, if MSVC_CRT_TYPE=/MT" ${DYNAMIC_UCRT_LINK_DEFAULT}) 141 SET(DYNAMIC_UCRT_LINKER_OPTION " /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib") 142 143 # Enable debug info also in Release build, 144 # and create PDB to be able to analyze crashes. 145 FOREACH(type EXE SHARED MODULE) 146 SET(CMAKE_${type}_LINKER_FLAGS_RELEASE 147 "${CMAKE_${type}_LINKER_FLAGS_RELEASE} /debug") 148 SET(CMAKE_${type}_LINKER_FLAGS_MINSIZEREL 149 "${CMAKE_${type}_LINKER_FLAGS_MINSIZEREL} /debug") 150 ENDFOREACH() 151 152 # Force runtime libraries 153 # Compile with /Zi to get debugging information 154 155 FOREACH(lang C CXX) 156 SET(CMAKE_${lang}_FLAGS_RELEASE "${CMAKE_${lang}_FLAGS_RELEASE} /Zi") 157 ENDFOREACH() 158 FOREACH(flag 159 CMAKE_C_FLAGS CMAKE_CXX_FLAGS 160 CMAKE_C_FLAGS_INIT CMAKE_CXX_FLAGS_INIT 161 CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO 162 CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG_INIT 163 CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO 164 CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG_INIT 165 CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL 166 ) 167 STRING(REGEX REPLACE "/M[TD][d]?" "${MSVC_CRT_TYPE}" "${flag}" "${${flag}}" ) 168 STRING(REPLACE "/ZI " "/Zi " "${flag}" "${${flag}}") 169 IF((NOT "${${flag}}" MATCHES "/Zi") AND (NOT "${${flag}}" MATCHES "/Z7")) 170 STRING(APPEND ${flag} " /Zi") 171 ENDIF() 172 ENDFOREACH() 173 174 IF(WITH_ASAN OR WITH_UBSAN) 175 # Workaround something Linux specific 176 SET(SECURITY_HARDENED 0 CACHE INTERNAL "" FORCE) 177 ENABLE_SANITIZERS() 178 ENDIF() 179 180 IF(CLANG_CL) 181 SET(CLANG_CL_FLAGS 182"-Wno-unknown-warning-option -Wno-unused-private-field \ 183-Wno-unused-parameter -Wno-inconsistent-missing-override \ 184-Wno-unused-command-line-argument -Wno-pointer-sign \ 185-Wno-deprecated-register -Wno-missing-braces \ 186-Wno-unused-function -Wno-unused-local-typedef -msse4.2 " 187 ) 188 IF(CMAKE_SIZEOF_VOID_P MATCHES 8) 189 STRING(APPEND CLANG_CL_FLAGS "-mpclmul ") 190 ENDIF() 191 STRING(APPEND CMAKE_C_FLAGS " ${CLANG_CL_FLAGS} ${MSVC_CRT_TYPE}") 192 STRING(APPEND CMAKE_CXX_FLAGS " ${CLANG_CL_FLAGS} ${MSVC_CRT_TYPE}") 193 ENDIF() 194 195 FOREACH(type EXE SHARED MODULE) 196 STRING(REGEX REPLACE "/STACK:([^ ]+)" "" CMAKE_${type}_LINKER_FLAGS "${CMAKE_${type}_LINKER_FLAGS}") 197 IF(WITH_ASAN) 198 SET(build_types RELWITHDEBINFO DEBUG) 199 ELSE() 200 SET(build_types RELWITHDEBINFO) 201 ENDIF() 202 FOREACH(btype ${build_types}) 203 STRING(REGEX REPLACE "/INCREMENTAL:([^ ]+)" "/INCREMENTAL:NO" CMAKE_${type}_LINKER_FLAGS_${btype} "${CMAKE_${type}_LINKER_FLAGS_${btype}}") 204 STRING(REGEX REPLACE "/INCREMENTAL$" "/INCREMENTAL:NO" CMAKE_${type}_LINKER_FLAGS_${btype} "${CMAKE_${type}_LINKER_FLAGS_${btype}}") 205 ENDFOREACH() 206 IF(NOT CLANG_CL) 207 STRING(APPEND CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO " /release /OPT:REF,ICF") 208 ENDIF() 209 IF(DYNAMIC_UCRT_LINK AND (MSVC_CRT_TYPE STREQUAL "/MT")) 210 FOREACH(config RELEASE RELWITHDEBINFO DEBUG MINSIZEREL) 211 STRING(APPEND CMAKE_${type}_LINKER_FLAGS_${config} ${DYNAMIC_UCRT_LINKER_OPTION}) 212 ENDFOREACH() 213 ENDIF() 214 ENDFOREACH() 215 216 217 # Mark 32 bit executables large address aware so they can 218 # use > 2GB address space 219 IF(CMAKE_SIZEOF_VOID_P MATCHES 4) 220 STRING(APPEND CMAKE_EXE_LINKER_FLAGS " /LARGEADDRESSAWARE") 221 ENDIF() 222 223 # Speed up multiprocessor build 224 IF (NOT CLANG_CL) 225 STRING(APPEND CMAKE_C_FLAGS " /MP") 226 STRING(APPEND CMAKE_CXX_FLAGS " /MP") 227 STRING(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " /Gw") 228 STRING(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " /Gw") 229 ENDIF() 230 231 #TODO: update the code and remove the disabled warnings 232 STRING(APPEND CMAKE_C_FLAGS " /we4700 /we4311 /we4477 /we4302 /we4090") 233 STRING(APPEND CMAKE_CXX_FLAGS " /we4099 /we4700 /we4311 /we4477 /we4302 /we4090") 234 IF(MSVC_VERSION GREATER 1910 AND NOT CLANG_CL) 235 STRING(APPEND CMAKE_CXX_FLAGS " /permissive-") 236 STRING(APPEND CMAKE_C_FLAGS " /diagnostics:caret") 237 STRING(APPEND CMAKE_CXX_FLAGS " /diagnostics:caret") 238 ENDIF() 239 ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_WARNINGS) 240 IF(MYSQL_MAINTAINER_MODE MATCHES "ERR") 241 STRING(APPEND CMAKE_C_FLAGS " /WX") 242 STRING(APPEND CMAKE_CXX_FLAGS " /WX") 243 FOREACH(type EXE SHARED MODULE) 244 FOREACH(cfg RELEASE DEBUG RELWITHDEBINFO) 245 SET(CMAKE_${type}_LINKER_FLAGS_${cfg} "${CMAKE_${type}_LINKER_FLAGS_${cfg}} /WX") 246 ENDFOREACH() 247 ENDFOREACH() 248 ENDIF() 249 IF(MSVC_VERSION LESS 1910) 250 # Noisy warning C4800: 'type': forcing value to bool 'true' or 'false' (performance warning), 251 # removed in VS2017 252 STRING(APPEND CMAKE_CXX_FLAGS " /wd4800") 253 ELSEIF (NOT CLANG_CL) 254 STRING(APPEND CMAKE_CXX_FLAGS " /d2OptimizeHugeFunctions") 255 ENDIF() 256ENDIF() 257 258# Always link with socket/synchronization libraries 259STRING(APPEND CMAKE_C_STANDARD_LIBRARIES " ws2_32.lib synchronization.lib") 260STRING(APPEND CMAKE_CXX_STANDARD_LIBRARIES " ws2_32.lib synchronization.lib") 261 262# System checks 263SET(SIGNAL_WITH_VIO_CLOSE 1) # Something that runtime team needs 264 265# IPv6 constants appeared in Vista SDK first. We need to define them in any case if they are 266# not in headers, to handle dual mode sockets correctly. 267CHECK_SYMBOL_EXISTS(IPPROTO_IPV6 "winsock2.h" HAVE_IPPROTO_IPV6) 268IF(NOT HAVE_IPPROTO_IPV6) 269 SET(HAVE_IPPROTO_IPV6 41) 270ENDIF() 271CHECK_SYMBOL_EXISTS(IPV6_V6ONLY "winsock2.h;ws2ipdef.h" HAVE_IPV6_V6ONLY) 272IF(NOT HAVE_IPV6_V6ONLY) 273 SET(IPV6_V6ONLY 27) 274ENDIF() 275 276# Some standard functions exist there under different 277# names (e.g popen is _popen or strok_r is _strtok_s) 278# If a replacement function exists, HAVE_FUNCTION is 279# defined to 1. CMake variable <function_name> will also 280# be defined to the replacement name. 281# So for example, CHECK_FUNCTION_REPLACEMENT(popen _popen) 282# will define HAVE_POPEN to 1 and set variable named popen 283# to _popen. If the header template, one needs to have 284# cmakedefine popen @popen@ which will expand to 285# define popen _popen after CONFIGURE_FILE 286 287MACRO(CHECK_FUNCTION_REPLACEMENT function replacement) 288 STRING(TOUPPER ${function} function_upper) 289 CHECK_FUNCTION_EXISTS(${function} HAVE_${function_upper}) 290 IF(NOT HAVE_${function_upper}) 291 CHECK_FUNCTION_EXISTS(${replacement} HAVE_${replacement}) 292 IF(HAVE_${replacement}) 293 SET(HAVE_${function_upper} 1 ) 294 SET(${function} ${replacement}) 295 ENDIF() 296 ENDIF() 297ENDMACRO() 298MACRO(CHECK_SYMBOL_REPLACEMENT symbol replacement header) 299 STRING(TOUPPER ${symbol} symbol_upper) 300 CHECK_SYMBOL_EXISTS(${symbol} ${header} HAVE_${symbol_upper}) 301 IF(NOT HAVE_${symbol_upper}) 302 CHECK_SYMBOL_EXISTS(${replacement} ${header} HAVE_${replacement}) 303 IF(HAVE_${replacement}) 304 SET(HAVE_${symbol_upper} 1) 305 SET(${symbol} ${replacement}) 306 ENDIF() 307 ENDIF() 308ENDMACRO() 309 310CHECK_SYMBOL_REPLACEMENT(S_IROTH _S_IREAD sys/stat.h) 311CHECK_SYMBOL_REPLACEMENT(S_IFIFO _S_IFIFO sys/stat.h) 312CHECK_SYMBOL_REPLACEMENT(SIGQUIT SIGTERM signal.h) 313CHECK_SYMBOL_REPLACEMENT(SIGPIPE SIGINT signal.h) 314CHECK_FUNCTION_REPLACEMENT(popen _popen) 315CHECK_FUNCTION_REPLACEMENT(pclose _pclose) 316CHECK_FUNCTION_REPLACEMENT(access _access) 317CHECK_FUNCTION_REPLACEMENT(strcasecmp _stricmp) 318CHECK_FUNCTION_REPLACEMENT(strncasecmp _strnicmp) 319CHECK_SYMBOL_REPLACEMENT(snprintf _snprintf stdio.h) 320CHECK_FUNCTION_REPLACEMENT(strtok_r strtok_s) 321CHECK_FUNCTION_REPLACEMENT(strtoll _strtoi64) 322CHECK_FUNCTION_REPLACEMENT(strtoull _strtoui64) 323CHECK_FUNCTION_REPLACEMENT(vsnprintf _vsnprintf) 324CHECK_TYPE_SIZE(ssize_t SIZE_OF_SSIZE_T) 325IF(NOT HAVE_SIZE_OF_SSIZE_T) 326 SET(ssize_t SSIZE_T) 327ENDIF() 328 329SET(FN_NO_CASE_SENSE 1) 330SET(USE_SYMDIR 1) 331 332# Force static C runtime for targets in current directory 333# (useful to get rid of MFC dll's dependency, or in installer) 334MACRO(FORCE_STATIC_CRT) 335 FOREACH(flag 336 CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO 337 CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG_INIT 338 CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO 339 CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG_INIT 340 CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL 341 ) 342 STRING(REGEX REPLACE "/MD[d]?" "/MT" "${flag}" "${${flag}}" ) 343 STRING(REPLACE "${DYNAMIC_UCRT_LINKER_OPTION}" "" "${flag}" "${${flag}}") 344 ENDFOREACH() 345ENDMACRO() 346