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