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 49ADD_DEFINITIONS(-D_WINDOWS -D__WIN__ -D_CRT_SECURE_NO_DEPRECATE) 50ADD_DEFINITIONS(-D_WIN32_WINNT=0x0A00) 51# We do not want the windows.h macros min/max 52ADD_DEFINITIONS(-DNOMINMAX) 53# Speed up build process excluding unused header files 54ADD_DEFINITIONS(-DWIN32_LEAN_AND_MEAN) 55 56# Adjust compiler and linker flags 57IF(MINGW AND CMAKE_SIZEOF_VOID_P EQUAL 4) 58 # mininal architecture flags, i486 enables GCC atomics 59 ADD_DEFINITIONS(-march=i486) 60ENDIF() 61 62FUNCTION(ENABLE_ASAN) 63 IF(NOT (MSVC AND CMAKE_CXX_COMPILER_ID MATCHES Clang)) 64 MESSAGE(FATAL_ERROR "clang-cl is necessary to enable asan") 65 ENDIF() 66 # currently, asan is broken with static CRT. 67 IF(NOT(MSVC_CRT_TYPE STREQUAL "/MD")) 68 MESSAGE(FATAL_ERROR "-DWITH_ASAN cmake parameter also requires -DMSVC_CRT_TYPE=/MD") 69 ENDIF() 70 IF(CMAKE_SIZEOF_VOID_P EQUAL 4) 71 MESSAGE(FATAL_ERROR "-DWITH_ASAN on Windows requires 64bit build") 72 ENDIF() 73 # After installation, clang lib directory should be added to PATH 74 # (e.g C:/Program Files/LLVM/lib/clang/5.0.1/lib/windows) 75 FIND_LIBRARY(CLANG_RT_ASAN_DYNAMIC clang_rt.asan_dynamic-x86_64.lib) 76 IF(NOT CLANG_RT_ASAN_DYNAMIC) 77 MESSAGE(FATAL_ERROR "Can't enable ASAN : missing clang_rt.asan_dynamic-x86_64.lib") 78 ENDIF() 79 80 FIND_LIBRARY(CLANG_RT_ASAN_DYNAMIC_THUNK clang_rt.asan_dynamic_runtime_thunk-x86_64.lib) 81 IF(NOT CLANG_RT_ASAN_DYNAMIC_THUNK) 82 MESSAGE(FATAL_ERROR "Can't enable ASAN : missing clang_rt.asan_dynamic_runtime_thunk-x86_64.lib") 83 ENDIF() 84 85 STRING(APPEND CMAKE_C_FLAGS " -fsanitize=address") 86 STRING(APPEND CMAKE_CXX_FLAGS " -fsanitize=address") 87 88 LINK_LIBRARIES(${CLANG_RT_ASAN_DYNAMIC} ${CLANG_RT_ASAN_DYNAMIC_THUNK}) 89ENDFUNCTION() 90 91 92IF(MSVC) 93 IF(WITH_ASAN) 94 ENABLE_ASAN() 95 ENDIF() 96 97 # Disable mingw based pkg-config found in Strawberry perl 98 SET(PKG_CONFIG_EXECUTABLE 0 CACHE INTERNAL "") 99 100 SET(MSVC_CRT_TYPE /MD CACHE STRING 101 "Runtime library - specify runtime library for linking (/MT,/MTd,/MD,/MDd)" 102 ) 103 SET(VALID_CRT_TYPES /MTd /MDd /MD /MT) 104 IF (NOT ";${VALID_CRT_TYPES};" MATCHES ";${MSVC_CRT_TYPE};") 105 MESSAGE(FATAL_ERROR "Invalid value ${MSVC_CRT_TYPE} for MSVC_CRT_TYPE, choose one of /MT,/MTd,/MD,/MDd ") 106 ENDIF() 107 108 IF(MSVC_CRT_TYPE MATCHES "/MD") 109 # Dynamic runtime (DLLs), need to install CRT libraries. 110 SET(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT VCCRT) 111 SET(CMAKE_INSTALL_UCRT_LIBRARIES TRUE) 112 IF(MSVC_CRT_TYPE STREQUAL "/MDd") 113 SET (CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY TRUE) 114 ENDIF() 115 INCLUDE(InstallRequiredSystemLibraries) 116 ENDIF() 117 118 # Enable debug info also in Release build, 119 # and create PDB to be able to analyze crashes. 120 FOREACH(type EXE SHARED MODULE) 121 SET(CMAKE_${type}_LINKER_FLAGS_RELEASE 122 "${CMAKE_${type}_LINKER_FLAGS_RELEASE} /debug") 123 SET(CMAKE_${type}_LINKER_FLAGS_MINSIZEREL 124 "${CMAKE_${type}_LINKER_FLAGS_MINSIZEREL} /debug") 125 ENDFOREACH() 126 127 # Force static runtime libraries 128 # - Choose debugging information: 129 # /Z7 130 # Produces an .obj file containing full symbolic debugging 131 # information for use with the debugger. The symbolic debugging 132 # information includes the names and types of variables, as well as 133 # functions and line numbers. No .pdb file is produced by the compiler. 134 # 135 # - Remove preprocessor flag _DEBUG that older cmakes use with Config=Debug, 136 # it is as defined by Debug runtimes itself (/MTd /MDd) 137 138 FOREACH(lang C CXX) 139 SET(CMAKE_${lang}_FLAGS_RELEASE "${CMAKE_${lang}_FLAGS_RELEASE} /Z7") 140 ENDFOREACH() 141 FOREACH(flag 142 CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO 143 CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG_INIT 144 CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO 145 CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG_INIT 146 CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL 147 ) 148 STRING(REGEX REPLACE "/M[TD][d]?" "${MSVC_CRT_TYPE}" "${flag}" "${${flag}}" ) 149 STRING(REGEX REPLACE "/D[ ]?_DEBUG" "" "${flag}" "${${flag}}") 150 STRING(REPLACE "/Zi" "/Z7" "${flag}" "${${flag}}") 151 IF(NOT "${${flag}}" MATCHES "/Z7") 152 STRING(APPEND ${flag} " /Z7") 153 ENDIF() 154 ENDFOREACH() 155 156 IF(CMAKE_CXX_COMPILER_ID MATCHES Clang) 157 SET(CLANG_CL_FLAGS 158"-Wno-unused-parameter -Wno-unused-command-line-argument -Wno-pointer-sign -Wno-deprecated-register \ 159-Wno-missing-braces -Wno-unused-function -msse4.2 " 160 ) 161 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CLANG_CL_FLAGS}") 162 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CLANG_CL_FLAGS}") 163 ENDIF() 164 165 # Fix CMake's predefined huge stack size 166 FOREACH(type EXE SHARED MODULE) 167 STRING(REGEX REPLACE "/STACK:([^ ]+)" "" CMAKE_${type}_LINKER_FLAGS "${CMAKE_${type}_LINKER_FLAGS}") 168 STRING(REGEX REPLACE "/INCREMENTAL:([^ ]+)" "/INCREMENTAL:NO" CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO}") 169 STRING(REGEX REPLACE "/INCREMENTAL$" "/INCREMENTAL:NO" CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO}") 170 STRING(REGEX REPLACE "/INCREMENTAL:([^ ]+)" "/INCREMENTAL:NO" CMAKE_${type}_LINKER_FLAGS_DEBUG "${CMAKE_${type}_LINKER_FLAGS_DEBUG}") 171 STRING(REGEX REPLACE "/INCREMENTAL$" "/INCREMENTAL:NO" CMAKE_${type}_LINKER_FLAGS_DEBUG "${CMAKE_${type}_LINKER_FLAGS_DEBUG}") 172 SET(CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO} /OPT:REF /release") 173 ENDFOREACH() 174 175 176 # Mark 32 bit executables large address aware so they can 177 # use > 2GB address space 178 IF(CMAKE_SIZEOF_VOID_P MATCHES 4) 179 SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") 180 ENDIF() 181 182 # Speed up multiprocessor build 183 IF (MSVC_VERSION GREATER 1400 AND (NOT CMAKE_CXX_COMPILER_ID MATCHES Clang)) 184 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") 185 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") 186 ENDIF() 187 188 #TODO: update the code and remove the disabled warnings 189 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /we4700 /we4311 /we4477 /we4302 /we4090") 190 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /we4099 /we4700 /we4311 /we4477 /we4302 /we4090") 191 IF(MSVC_VERSION GREATER 1910 AND (NOT CMAKE_CXX_COMPILER_ID MATCHES Clang)) 192 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive-") 193 ENDIF() 194 ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_WARNINGS) 195 IF(MYSQL_MAINTAINER_MODE MATCHES "ERR") 196 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") 197 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX") 198 FOREACH(type EXE SHARED MODULE) 199 FOREACH(cfg RELEASE DEBUG RELWITHDEBINFO) 200 SET(CMAKE_${type}_LINKER_FLAGS_${cfg} "${CMAKE_${type}_LINKER_FLAGS_${cfg}} /WX") 201 ENDFOREACH() 202 ENDFOREACH() 203 ENDIF() 204 IF(MSVC_VERSION LESS 1910) 205 # Noisy warning C4800: 'type': forcing value to bool 'true' or 'false' (performance warning), 206 # removed in VS2017 207 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4800") 208 ELSEIF (NOT (CMAKE_CXX_COMPILER_ID MATCHES Clang)) 209 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /d2OptimizeHugeFunctions") 210 ENDIF() 211ENDIF() 212 213# Always link with socket library 214STRING(APPEND CMAKE_C_STANDARD_LIBRARIES " ws2_32.lib") 215STRING(APPEND CMAKE_CXX_STANDARD_LIBRARIES " ws2_32.lib") 216 217# System checks 218SET(SIGNAL_WITH_VIO_CLOSE 1) # Something that runtime team needs 219 220# IPv6 constants appeared in Vista SDK first. We need to define them in any case if they are 221# not in headers, to handle dual mode sockets correctly. 222CHECK_SYMBOL_EXISTS(IPPROTO_IPV6 "winsock2.h" HAVE_IPPROTO_IPV6) 223IF(NOT HAVE_IPPROTO_IPV6) 224 SET(HAVE_IPPROTO_IPV6 41) 225ENDIF() 226CHECK_SYMBOL_EXISTS(IPV6_V6ONLY "winsock2.h;ws2ipdef.h" HAVE_IPV6_V6ONLY) 227IF(NOT HAVE_IPV6_V6ONLY) 228 SET(IPV6_V6ONLY 27) 229ENDIF() 230 231# Some standard functions exist there under different 232# names (e.g popen is _popen or strok_r is _strtok_s) 233# If a replacement function exists, HAVE_FUNCTION is 234# defined to 1. CMake variable <function_name> will also 235# be defined to the replacement name. 236# So for example, CHECK_FUNCTION_REPLACEMENT(popen _popen) 237# will define HAVE_POPEN to 1 and set variable named popen 238# to _popen. If the header template, one needs to have 239# cmakedefine popen @popen@ which will expand to 240# define popen _popen after CONFIGURE_FILE 241 242MACRO(CHECK_FUNCTION_REPLACEMENT function replacement) 243 STRING(TOUPPER ${function} function_upper) 244 CHECK_FUNCTION_EXISTS(${function} HAVE_${function_upper}) 245 IF(NOT HAVE_${function_upper}) 246 CHECK_FUNCTION_EXISTS(${replacement} HAVE_${replacement}) 247 IF(HAVE_${replacement}) 248 SET(HAVE_${function_upper} 1 ) 249 SET(${function} ${replacement}) 250 ENDIF() 251 ENDIF() 252ENDMACRO() 253MACRO(CHECK_SYMBOL_REPLACEMENT symbol replacement header) 254 STRING(TOUPPER ${symbol} symbol_upper) 255 CHECK_SYMBOL_EXISTS(${symbol} ${header} HAVE_${symbol_upper}) 256 IF(NOT HAVE_${symbol_upper}) 257 CHECK_SYMBOL_EXISTS(${replacement} ${header} HAVE_${replacement}) 258 IF(HAVE_${replacement}) 259 SET(HAVE_${symbol_upper} 1) 260 SET(${symbol} ${replacement}) 261 ENDIF() 262 ENDIF() 263ENDMACRO() 264 265CHECK_SYMBOL_REPLACEMENT(S_IROTH _S_IREAD sys/stat.h) 266CHECK_SYMBOL_REPLACEMENT(S_IFIFO _S_IFIFO sys/stat.h) 267CHECK_SYMBOL_REPLACEMENT(SIGQUIT SIGTERM signal.h) 268CHECK_SYMBOL_REPLACEMENT(SIGPIPE SIGINT signal.h) 269CHECK_FUNCTION_REPLACEMENT(popen _popen) 270CHECK_FUNCTION_REPLACEMENT(pclose _pclose) 271CHECK_FUNCTION_REPLACEMENT(access _access) 272CHECK_FUNCTION_REPLACEMENT(strcasecmp _stricmp) 273CHECK_FUNCTION_REPLACEMENT(strncasecmp _strnicmp) 274CHECK_SYMBOL_REPLACEMENT(snprintf _snprintf stdio.h) 275CHECK_FUNCTION_REPLACEMENT(strtok_r strtok_s) 276CHECK_FUNCTION_REPLACEMENT(strtoll _strtoi64) 277CHECK_FUNCTION_REPLACEMENT(strtoull _strtoui64) 278CHECK_FUNCTION_REPLACEMENT(vsnprintf _vsnprintf) 279CHECK_TYPE_SIZE(ssize_t SIZE_OF_SSIZE_T) 280IF(NOT HAVE_SIZE_OF_SSIZE_T) 281 SET(ssize_t SSIZE_T) 282ENDIF() 283 284SET(FN_NO_CASE_SENSE 1) 285SET(USE_SYMDIR 1) 286 287# Force static C runtime for targets in current directory 288# (useful to get rid of MFC dll's dependency, or in installer) 289MACRO(FORCE_STATIC_CRT) 290 FOREACH(flag 291 CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO 292 CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG_INIT 293 CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO 294 CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG_INIT 295 CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL 296 ) 297 STRING(REGEX REPLACE "/MD[d]?" "/MT" "${flag}" "${${flag}}" ) 298 ENDFOREACH() 299ENDMACRO() 300