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  SET(MSVC_CRT_TYPE /MT CACHE STRING
100    "Runtime library - specify runtime library for linking (/MT,/MTd,/MD,/MDd)"
101  )
102  SET(VALID_CRT_TYPES /MTd /MDd /MD  /MT)
103  IF (NOT ";${VALID_CRT_TYPES};" MATCHES ";${MSVC_CRT_TYPE};")
104    MESSAGE(FATAL_ERROR "Invalid value ${MSVC_CRT_TYPE} for MSVC_CRT_TYPE, choose one of /MT,/MTd,/MD,/MDd ")
105  ENDIF()
106
107  IF(MSVC_CRT_TYPE MATCHES "/MD")
108   # Dynamic runtime (DLLs), need to install CRT libraries.
109   SET(CMAKE_INSTALL_MFC_LIBRARIES TRUE)# upgrade wizard
110   SET(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT VCCRT)
111   SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS TRUE)
112   SET(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
113   IF(MSVC_CRT_TYPE STREQUAL "/MDd")
114     SET (CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY TRUE)
115   ENDIF()
116   INCLUDE(InstallRequiredSystemLibraries)
117  ENDIF()
118
119  # Enable debug info also in Release build,
120  # and create PDB to be able to analyze crashes.
121  FOREACH(type EXE SHARED MODULE)
122   SET(CMAKE_${type}_LINKER_FLAGS_RELEASE
123     "${CMAKE_${type}_LINKER_FLAGS_RELEASE} /debug")
124   SET(CMAKE_${type}_LINKER_FLAGS_MINSIZEREL
125     "${CMAKE_${type}_LINKER_FLAGS_MINSIZEREL} /debug")
126  ENDFOREACH()
127
128  # Force static runtime libraries
129  # - Choose debugging information:
130  #     /Z7
131  #     Produces an .obj file containing full symbolic debugging
132  #     information for use with the debugger. The symbolic debugging
133  #     information includes the names and types of variables, as well as
134  #     functions and line numbers. No .pdb file is produced by the compiler.
135  #
136  # - Remove preprocessor flag _DEBUG that older cmakes use with Config=Debug,
137  #   it is as defined by Debug runtimes itself (/MTd /MDd)
138
139  FOREACH(lang C CXX)
140    SET(CMAKE_${lang}_FLAGS_RELEASE "${CMAKE_${lang}_FLAGS_RELEASE} /Z7")
141  ENDFOREACH()
142  FOREACH(flag
143   CMAKE_C_FLAGS_RELEASE    CMAKE_C_FLAGS_RELWITHDEBINFO
144   CMAKE_C_FLAGS_DEBUG      CMAKE_C_FLAGS_DEBUG_INIT
145   CMAKE_CXX_FLAGS_RELEASE  CMAKE_CXX_FLAGS_RELWITHDEBINFO
146   CMAKE_CXX_FLAGS_DEBUG    CMAKE_CXX_FLAGS_DEBUG_INIT
147   CMAKE_C_FLAGS_MINSIZEREL  CMAKE_CXX_FLAGS_MINSIZEREL
148   )
149   STRING(REGEX REPLACE "/M[TD][d]?"  "${MSVC_CRT_TYPE}" "${flag}"  "${${flag}}" )
150   STRING(REGEX REPLACE "/D[ ]?_DEBUG"  "" "${flag}" "${${flag}}")
151   STRING(REPLACE "/Zi"  "/Z7" "${flag}" "${${flag}}")
152   IF(NOT "${${flag}}" MATCHES "/Z7")
153    STRING(APPEND ${flag} " /Z7")
154   ENDIF()
155  ENDFOREACH()
156
157  IF(CMAKE_CXX_COMPILER_ID MATCHES Clang)
158     SET(CLANG_CL_FLAGS
159"-Wno-unused-parameter -Wno-unused-command-line-argument -Wno-pointer-sign -Wno-deprecated-register \
160-Wno-missing-braces -Wno-unused-function -msse4.2 "
161    )
162    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CLANG_CL_FLAGS}")
163    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CLANG_CL_FLAGS}")
164  ENDIF()
165
166  # Fix CMake's predefined huge stack size
167  FOREACH(type EXE SHARED MODULE)
168   STRING(REGEX REPLACE "/STACK:([^ ]+)" "" CMAKE_${type}_LINKER_FLAGS "${CMAKE_${type}_LINKER_FLAGS}")
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_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO}")
171   STRING(REGEX REPLACE "/INCREMENTAL:([^ ]+)" "/INCREMENTAL:NO" CMAKE_${type}_LINKER_FLAGS_DEBUG "${CMAKE_${type}_LINKER_FLAGS_DEBUG}")
172   STRING(REGEX REPLACE "/INCREMENTAL$" "/INCREMENTAL:NO" CMAKE_${type}_LINKER_FLAGS_DEBUG "${CMAKE_${type}_LINKER_FLAGS_DEBUG}")
173   SET(CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO} /OPT:REF /release")
174  ENDFOREACH()
175
176
177  # Mark 32 bit executables large address aware so they can
178  # use > 2GB address space
179  IF(CMAKE_SIZEOF_VOID_P MATCHES 4)
180    SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE")
181  ENDIF()
182
183  # Speed up multiprocessor build
184  IF (MSVC_VERSION GREATER 1400 AND (NOT CMAKE_CXX_COMPILER_ID MATCHES Clang))
185    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP")
186    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
187  ENDIF()
188
189  #TODO: update the code and remove the disabled warnings
190  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /we4700 /we4311 /we4477 /we4302 /we4090")
191  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /we4099 /we4700 /we4311 /we4477 /we4302 /we4090")
192  IF(MSVC_VERSION GREATER 1910  AND (NOT CMAKE_CXX_COMPILER_ID MATCHES Clang))
193    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive-")
194  ENDIF()
195  ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_WARNINGS)
196  IF(MYSQL_MAINTAINER_MODE MATCHES "ERR")
197    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
198    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
199    FOREACH(type EXE SHARED MODULE)
200      FOREACH(cfg RELEASE DEBUG RELWITHDEBINFO)
201        SET(CMAKE_${type}_LINKER_FLAGS_${cfg} "${CMAKE_${type}_LINKER_FLAGS_${cfg}} /WX")
202      ENDFOREACH()
203    ENDFOREACH()
204  ENDIF()
205  IF(MSVC_VERSION LESS 1910)
206    # Noisy warning C4800: 'type': forcing value to bool 'true' or 'false' (performance warning),
207    # removed in VS2017
208    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4800")
209  ELSEIF (NOT (CMAKE_CXX_COMPILER_ID MATCHES Clang))
210    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /d2OptimizeHugeFunctions")
211  ENDIF()
212ENDIF()
213
214# Always link with socket library
215STRING(APPEND CMAKE_C_STANDARD_LIBRARIES " ws2_32.lib")
216STRING(APPEND CMAKE_CXX_STANDARD_LIBRARIES " ws2_32.lib")
217
218# System checks
219SET(SIGNAL_WITH_VIO_CLOSE 1) # Something that runtime team needs
220
221# IPv6 constants appeared in Vista SDK first. We need to define them in any case if they are
222# not in headers, to handle dual mode sockets correctly.
223CHECK_SYMBOL_EXISTS(IPPROTO_IPV6 "winsock2.h" HAVE_IPPROTO_IPV6)
224IF(NOT HAVE_IPPROTO_IPV6)
225  SET(HAVE_IPPROTO_IPV6 41)
226ENDIF()
227CHECK_SYMBOL_EXISTS(IPV6_V6ONLY  "winsock2.h;ws2ipdef.h" HAVE_IPV6_V6ONLY)
228IF(NOT HAVE_IPV6_V6ONLY)
229  SET(IPV6_V6ONLY 27)
230ENDIF()
231
232# Some standard functions exist there under different
233# names (e.g popen is _popen or strok_r is _strtok_s)
234# If a replacement function exists, HAVE_FUNCTION is
235# defined to 1. CMake variable <function_name> will also
236# be defined to the replacement name.
237# So for example, CHECK_FUNCTION_REPLACEMENT(popen _popen)
238# will define HAVE_POPEN to 1 and set variable named popen
239# to _popen. If the header template, one needs to have
240# cmakedefine popen @popen@ which will expand to
241# define popen _popen after CONFIGURE_FILE
242
243MACRO(CHECK_FUNCTION_REPLACEMENT function replacement)
244  STRING(TOUPPER ${function} function_upper)
245  CHECK_FUNCTION_EXISTS(${function} HAVE_${function_upper})
246  IF(NOT HAVE_${function_upper})
247    CHECK_FUNCTION_EXISTS(${replacement}  HAVE_${replacement})
248    IF(HAVE_${replacement})
249      SET(HAVE_${function_upper} 1 )
250      SET(${function} ${replacement})
251    ENDIF()
252  ENDIF()
253ENDMACRO()
254MACRO(CHECK_SYMBOL_REPLACEMENT symbol replacement header)
255  STRING(TOUPPER ${symbol} symbol_upper)
256  CHECK_SYMBOL_EXISTS(${symbol} ${header} HAVE_${symbol_upper})
257  IF(NOT HAVE_${symbol_upper})
258    CHECK_SYMBOL_EXISTS(${replacement} ${header} HAVE_${replacement})
259    IF(HAVE_${replacement})
260      SET(HAVE_${symbol_upper} 1)
261      SET(${symbol} ${replacement})
262    ENDIF()
263  ENDIF()
264ENDMACRO()
265
266CHECK_SYMBOL_REPLACEMENT(S_IROTH _S_IREAD sys/stat.h)
267CHECK_SYMBOL_REPLACEMENT(S_IFIFO _S_IFIFO sys/stat.h)
268CHECK_SYMBOL_REPLACEMENT(SIGQUIT SIGTERM signal.h)
269CHECK_SYMBOL_REPLACEMENT(SIGPIPE SIGINT signal.h)
270CHECK_FUNCTION_REPLACEMENT(popen _popen)
271CHECK_FUNCTION_REPLACEMENT(pclose _pclose)
272CHECK_FUNCTION_REPLACEMENT(access _access)
273CHECK_FUNCTION_REPLACEMENT(strcasecmp _stricmp)
274CHECK_FUNCTION_REPLACEMENT(strncasecmp _strnicmp)
275CHECK_SYMBOL_REPLACEMENT(snprintf _snprintf stdio.h)
276CHECK_FUNCTION_REPLACEMENT(strtok_r strtok_s)
277CHECK_FUNCTION_REPLACEMENT(strtoll _strtoi64)
278CHECK_FUNCTION_REPLACEMENT(strtoull _strtoui64)
279CHECK_FUNCTION_REPLACEMENT(vsnprintf _vsnprintf)
280CHECK_TYPE_SIZE(ssize_t SIZE_OF_SSIZE_T)
281IF(NOT HAVE_SIZE_OF_SSIZE_T)
282 SET(ssize_t SSIZE_T)
283ENDIF()
284
285SET(FN_NO_CASE_SENSE 1)
286SET(USE_SYMDIR 1)
287