port emitting Expr_::Binop
[hiphop-php.git] / CMake / HPHPCompiler.cmake
blobc16c1a99a501a98c11838ae8172ab8c2a2ee64d3
1 set(FREEBSD FALSE)
2 if("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
3   set(FREEBSD TRUE)
4 endif()
5 set(LINUX FALSE)
6 if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
7   set(LINUX TRUE)
8 endif()
9 set(DARWIN FALSE)
10 if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
11   set(DARWIN TRUE)
12 endif()
13 set(WINDOWS FALSE)
14 if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
15   set(WINDOWS TRUE)
16 endif()
18 # Do this until cmake has a define for ARMv8
19 INCLUDE(CheckCXXSourceCompiles)
20 CHECK_CXX_SOURCE_COMPILES("
21 #ifndef __x86_64__
22 #error Not x64
23 #endif
24 int main() { return 0; }" IS_X64)
26 CHECK_CXX_SOURCE_COMPILES("
27 #ifndef __AARCH64EL__
28 #error Not ARMv8
29 #endif
30 int main() { return 0; }" IS_AARCH64)
32 CHECK_CXX_SOURCE_COMPILES("
33 #ifndef __powerpc64__
34 #error Not PPC64
35 #endif
36 int main() { return 0; }" IS_PPC64)
38 # using Clang or GCC
39 if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
40   # Warnings to disable by name, -Wno-${name}
41   set(DISABLED_NAMED_WARNINGS)
42   list(APPEND DISABLED_NAMED_WARNINGS
43     "error=array-bounds"
44     "error=switch"
45     "attributes"
46     "deprecated"
47     "invalid-offsetof"
48     "register"
49     "sign-compare"
50     "strict-aliasing"
51     "unused-function"
52     "unused-local-typedefs"
53     "unused-result"
54     "write-strings"
55   )
57   # Warnings to disable by name when building C code.
58   set(DISABLED_C_NAMED_WARNINGS)
59   list(APPEND DISABLED_C_NAMED_WARNINGS
60     "missing-field-initializers"
61     "sign-compare"
62   )
64   # General options to pass to both C & C++ compilers
65   set(GENERAL_OPTIONS)
67   # General options to pass to the C++ compiler
68   set(GENERAL_CXX_OPTIONS)
69   list(APPEND GENERAL_CXX_OPTIONS
70     "std=gnu++1z"
71     "fno-omit-frame-pointer"
72     "fno-operator-names"
73     "Wall"
74     "Woverloaded-virtual"
75     "Werror=format-security"
76   )
78   # Options to pass for debug mode to the C++ compiler
79   set(DEBUG_CXX_OPTIONS)
81   # Options to pass for release mode to the C++ compiler
82   set(RELEASE_CXX_OPTIONS)
84   # Suboption of -g in debug mode
85   set(GDB_SUBOPTION)
87   # Enable GCC/LLVM stack-smashing protection
88   if(ENABLE_SSP)
89     list(APPEND GENERAL_OPTIONS
90       # This needs two dashes in the name, so put one here.
91       "-param=ssp-buffer-size=4"
92       "pie"
93       "fPIC"
94     )
95   endif()
97   if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") # using Clang
98     if (IS_X64)
99       list(APPEND GENERAL_OPTIONS
100         # For unclear reasons, our detection for what crc32 intrinsics you have
101         # will cause clang to ICE. Specifying a baseline here works around the
102         # issue. (SSE4.2 has been available on processors for quite some time now.)
103         "msse4.2"
104       )
105       # Also need to pass the right option to ASM files to avoid inconsistencies
106       # in CRC hash function handling
107       set(CMAKE_ASM_FLAGS  "${CMAKE_ASM_FLAGS} -msse4.2")
108     endif()
110     list(APPEND GENERAL_CXX_OPTIONS
111       "Qunused-arguments"
112     )
113     list(APPEND DISABLED_C_NAMED_WARNINGS
114       "unused-command-line-argument"
115     )
116     list(APPEND DISABLED_NAMED_WARNINGS
117       "return-type-c-linkage"
118       "unknown-warning-option"
119       "unused-command-line-argument"
120     )
122     # Enabled GCC/LLVM stack-smashing protection
123     if(ENABLE_SSP)
124       if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.6 OR
125          CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 3.6)
126         list(APPEND GENERAL_OPTIONS "fstack-protector-strong")
127       else()
128         list(APPEND GENERAL_OPTIONS "fstack-protector")
129       endif()
130     endif()
132     if(CLANG_FORCE_LIBSTDCXX)
133       list(APPEND GENERAL_CXX_OPTIONS "stdlib=libstdc++")
134     else()
135       list(APPEND GENERAL_CXX_OPTIONS "stdlib=libc++")
136     endif()
137   else() # using GCC
138     list(APPEND DISABLED_NAMED_WARNINGS
139       "deprecated-declarations"
140       "maybe-uninitialized"
141     )
142     list(APPEND DISABLED_C_NAMED_WARNINGS
143       "maybe-uninitialized"
144       "old-style-declaration"
145     )
146     list(APPEND GENERAL_OPTIONS
147       "ffunction-sections"
148     )
149     list(APPEND GENERAL_CXX_OPTIONS
150       "fdata-sections"
151       "fno-gcse"
152       "fno-canonical-system-headers"
153       "Wvla"
154     )
155     list(APPEND RELEASE_CXX_OPTIONS
156       "-param max-inline-insns-auto=100"
157       "-param early-inlining-insns=200"
158       "-param max-early-inliner-iterations=50"
159       "-param=inline-unit-growth=200"
160       "-param=large-unit-insns=10000"
161     )
163     # Fix problem with GCC 4.9, https://kb.isc.org/article/AA-01167
164     if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9 OR
165        CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.9)
166       list(APPEND GENERAL_OPTIONS "fno-delete-null-pointer-checks")
167     else()
168        message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.9 or greater.")
169     endif()
171     # Warn about a GCC 4.9 bug leading to an incorrect refcounting issue
172     # https://github.com/facebook/hhvm/issues/8011
173     if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
174        message(WARNING "HHVM is known to trigger optimization bugs in GCC 4.9. Upgrading to GCC 5 is recommended. See https://github.com/facebook/hhvm/issues/8011 for more details.")
175     endif()
177     if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.3 OR
178        CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 8.3)
179      message(WARNING "HHVM is primarily tested on GCC 5.0-8.3. Using other versions may produce unexpected results, or may not even build at all.")
180     endif()
182     if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.1 OR
183        CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 5.1)
184       list(APPEND DISABLED_NAMED_WARNINGS "bool-compare")
185       list(APPEND GENERAL_OPTIONS "DFOLLY_HAVE_MALLOC_H")
186     endif()
188     if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0 OR
189        CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 6.0)
190       list(APPEND GENERAL_CXX_OPTIONS "Wno-misleading-indentation")
191     endif()
193     # Enabled GCC/LLVM stack-smashing protection
194     if(ENABLE_SSP)
195       if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.8 OR
196          CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.8)
197         if(LINUX)
198           # https://isisblogs.poly.edu/2011/06/01/relro-relocation-read-only/
199           list(APPEND GENERAL_OPTIONS "Wl,-z,relro,-z,now")
200         endif()
201         if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9 OR
202            CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.9)
203           list(APPEND GENERAL_OPTIONS "fstack-protector-strong")
204         endif()
205       else()
206         list(APPEND GENERAL_OPTIONS "fstack-protector")
207       endif()
208     endif()
210     # X64
211     if(IS_X64)
212       list(APPEND GENERAL_CXX_OPTIONS "mcrc32")
213         if(ENABLE_SSE4_2)
214           list(APPEND GENERAL_CXX_OPTIONS
215           # SSE4.2 has been available on processors for quite some time now. This
216           # allows enabling CRC hash function code
217           "msse4.2"
218           )
219           # Also pass the right option to ASM files to avoid inconsistencies
220           # in CRC hash function handling
221           set(CMAKE_ASM_FLAGS  "${CMAKE_ASM_FLAGS} -msse4.2")
222         endif()
223     endif()
225     # ARM64
226     if(IS_AARCH64)
227       # Force char type to be signed, which is not the case on aarch64.
228       list(APPEND GENERAL_OPTIONS "fsigned-char")
230       # If a CPU was specified, build a -mcpu option for the compiler.
231       set(AARCH64_TARGET_CPU "" CACHE STRING "CPU to tell gcc to optimize for (-mcpu)")
232       if(AARCH64_TARGET_CPU)
233         list(APPEND GENERAL_OPTIONS "mcpu=${AARCH64_TARGET_CPU}")
234         set(CMAKE_ASM_FLAGS  "${CMAKE_ASM_FLAGS} -mcpu=${AARCH64_TARGET_CPU}")
236         # Make sure GCC is not using the fix for errata 843419. This change
237         # interferes with the gold linker. Note that GCC applies this fix
238         # even if you specify an mcpu other than cortex-a53, which is why
239         # it's explicitly being disabled here for any cpu other than
240         # cortex-a53. If you're running a newer pass of the cortex-a53, then
241         # you can likely disable this fix with the following flag too. YMMV
242         if(NOT ${AARCH64_TARGET_CPU} STREQUAL "cortex-a53")
243           list(APPEND GENERAL_OPTIONS "mno-fix-cortex-a53-843419")
244         endif()
245       endif()
246     endif()
248     # PPC64
249     if(NOT IS_PPC64)
250       list(APPEND RELEASE_CXX_OPTIONS "momit-leaf-frame-pointer")
251     endif()
253     if(STATIC_CXX_LIB)
254       set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
255     endif()
257     if (ENABLE_SPLIT_DWARF)
258       set(GDB_SUBOPTION "split-dwarf")
259     endif()
260   endif()
262   # No optimizations for debug builds.
263   # -Og enables some optimizations, but makes debugging harder by optimizing
264   # away some functions and locals. -O0 is more debuggable.
265   # -O0-ggdb was reputed to cause gdb to crash (github #4450)
266   set(CMAKE_C_FLAGS_DEBUG            "-O0 -g${GDB_SUBOPTION}")
267   set(CMAKE_CXX_FLAGS_DEBUG          "-O0 -g${GDB_SUBOPTION}")
268   set(CMAKE_C_FLAGS_DEBUGOPT         "-O2 -g${GDB_SUBOPTION}")
269   set(CMAKE_CXX_FLAGS_DEBUGOPT       "-O2 -g${GDB_SUBOPTION}")
270   set(CMAKE_C_FLAGS_MINSIZEREL       "-Os -DNDEBUG")
271   set(CMAKE_CXX_FLAGS_MINSIZEREL     "-Os -DNDEBUG")
272   set(CMAKE_C_FLAGS_RELEASE          "-O3 -DNDEBUG")
273   set(CMAKE_CXX_FLAGS_RELEASE        "-O3 -DNDEBUG")
274   set(CMAKE_C_FLAGS_RELWITHDEBINFO   "-O2 -g${GDB_SUBOPTION} -DNDEBUG")
275   set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g${GDB_SUBOPTION} -DNDEBUG")
276   set(CMAKE_C_FLAGS                  "${CMAKE_C_FLAGS} -W -Werror=implicit-function-declaration")
278   mark_as_advanced(CMAKE_C_FLAGS_DEBUGOPT CMAKE_CXX_FLAGS_DEBUGOPT)
280   foreach(opt ${DISABLED_NAMED_WARNINGS})
281     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-${opt}")
282   endforeach()
284   foreach(opt ${DISABLED_C_NAMED_WARNINGS})
285     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-${opt}")
286   endforeach()
288   foreach(opt ${GENERAL_OPTIONS})
289     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -${opt}")
290     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -${opt}")
291   endforeach()
293   foreach(opt ${GENERAL_CXX_OPTIONS})
294     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -${opt}")
295   endforeach()
297   foreach(opt ${DEBUG_CXX_OPTIONS})
298     set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -${opt}")
299   endforeach()
301   foreach(opt ${RELEASE_CXX_OPTIONS})
302     set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -${opt}")
303   endforeach()
305   # The ASM part of this makes it more effort than it's worth
306   # to add these to the general flags system.
307   if(ENABLE_AVX2)
308     set(CMAKE_C_FLAGS    "${CMAKE_C_FLAGS} -mavx2 -march=core-avx2")
309     set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -mavx2 -march=core-avx2")
310     set(CMAKE_ASM_FLAGS  "${CMAKE_ASM_FLAGS} -mavx2 -march=core-avx2")
311   endif()
312 # using Intel C++
313 elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
314   set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} -no-ipo -fp-model precise -wd584 -wd1418 -wd1918 -wd383 -wd869 -wd981 -wd424 -wd1419 -wd444 -wd271 -wd2259 -wd1572 -wd1599 -wd82 -wd177 -wd593 -w")
315   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -no-ipo -fp-model precise -wd584 -wd1418 -wd1918 -wd383 -wd869 -wd981 -wd424 -wd1419 -wd444 -wd271 -wd2259 -wd1572 -wd1599 -wd82 -wd177 -wd593 -fno-omit-frame-pointer -Wall -Woverloaded-virtual -Wno-deprecated -w1 -Wno-strict-aliasing -Wno-write-strings -Wno-invalid-offsetof -fno-operator-names")
316 # using Visual Studio C++
317 elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
318   message(WARNING "MSVC support is VERY experimental. It will likely not compile, and is intended for the utterly insane.")
320   ############################################################
321   # First we setup and account for the option sets.
322   ############################################################
324   set(MSVC_GENERAL_OPTIONS)
325   set(MSVC_DISABLED_WARNINGS)
326   set(MSVC_WARNINGS_AS_ERRORS)
327   set(MSVC_ADDITIONAL_DEFINES)
328   set(MSVC_EXE_LINKER_OPTIONS)
329   set(MSVC_DEBUG_OPTIONS)
330   set(MSVC_RELEASE_OPTIONS)
331   set(MSVC_RELEASE_LINKER_OPTIONS)
332   set(MSVC_DEBUG_EXE_LINKER_OPTIONS)
333   set(MSVC_RELEASE_EXE_LINKER_OPTIONS)
335   # Some addional configuration options.
336   set(MSVC_ENABLE_ALL_WARNINGS ON CACHE BOOL "If enabled, pass /Wall to the compiler.")
337   set(MSVC_ENABLE_DEBUG_INLINING ON CACHE BOOL "If enabled, enable inlining in the debug configuration. This allows /Zc:inline to be far more effective, resulting in hphp_runtime_static being ~450mb smaller.")
338   set(MSVC_ENABLE_LTCG OFF CACHE BOOL "If enabled, use Link Time Code Generation for Release builds.")
339   set(MSVC_ENABLE_PARALLEL_BUILD ON CACHE BOOL "If enabled, build multiple source files in parallel.")
340   set(MSVC_ENABLE_PCH ON CACHE BOOL "If enabled, use precompiled headers to speed up the build.")
341   set(MSVC_ENABLE_STATIC_ANALYSIS OFF CACHE BOOL "If enabled, do more complex static analysis and generate warnings appropriately.")
342   set(MSVC_FAVORED_ARCHITECTURE "blend" CACHE STRING "One of 'blend', 'AMD64', 'INTEL64', or 'ATOM'. This tells the compiler to generate code optimized to run best on the specified architecture.")
344   # The general options passed:
345   list(APPEND MSVC_GENERAL_OPTIONS
346     "bigobj" # Support objects with > 65k sections. Needed for folly due to templates.
347     "fp:precise" # Precise floating point model used in every other build, use it here as well.
348     "EHa" # Enable both SEH and C++ Exceptions.
349     "Oy-" # Disable elimination of stack frames.
350     "Zc:inline" # Have the compiler eliminate unreferenced COMDAT functions and data before emitting the object file. This produces significantly less input to the linker, resulting in MUCH faster linking.
351     "Zo" # Enable enhanced optimized debugging. Produces slightly larger pdb files, but the resulting optimized code is much much easier to debug.
352   )
354   # Enable all warnings if requested.
355   if (MSVC_ENABLE_ALL_WARNINGS)
356     list(APPEND MSVC_GENERAL_OPTIONS "Wall")
357   endif()
359   # Enable static analysis if requested.
360   if (MSVC_ENABLE_STATIC_ANALYSIS)
361     list(APPEND MSVC_GENERAL_OPTIONS "analyze")
362   endif()
364   # Enable multi-processor compilation if requested.
365   if (MSVC_ENABLE_PARALLEL_BUILD)
366     list(APPEND MSVC_GENERAL_OPTIONS "MP")
367   endif()
369   # Enable AVX2 codegen if available and requested.
370   if (ENABLE_AVX2)
371     list(APPEND MSVC_GENERAL_OPTIONS "arch:AVX2")
372   endif()
374   # Validate, and then add the favored architecture.
375   if (NOT MSVC_FAVORED_ARCHITECTURE STREQUAL "blend" AND NOT MSVC_FAVORED_ARCHITECTURE STREQUAL "AMD64" AND NOT MSVC_FAVORED_ARCHITECTURE STREQUAL "INTEL64" AND NOT MSVC_FAVORED_ARCHITECTURE STREQUAL "ATOM")
376     message(FATAL_ERROR "MSVC_FAVORED_ARCHITECTURE must be set to one of exactly, 'blend', 'AMD64', 'INTEL64', or 'ATOM'! Got '${MSVC_FAVORED_ARCHITECTURE}' instead!")
377   endif()
378   list(APPEND MSVC_GENERAL_OPTIONS "favor:${MSVC_FAVORED_ARCHITECTURE}")
380   # The warnings that are disabled:
381   list(APPEND MSVC_DISABLED_WARNINGS
382     "4068" # Unknown pragma.
383     "4091" # 'typedef' ignored on left of '' when no variable is declared.
384     "4101" # Unused variables
385     "4103" # Alignment changed after including header. This is needed because boost includes an ABI header that does some #pragma pack push/pop stuff, and we've passed our own packing
386     "4146" # Unary minus applied to unsigned type, result still unsigned.
387     "4250" # Function was inherited via dominance.
388     "4800" # Values being forced to bool, this happens many places, and is a "performance warning".
389   )
391   if (MSVC_ENABLE_ALL_WARNINGS)
392     # These warnings are disabled because we've
393     # enabled all warnings. If all warnings are
394     # not enabled, then these don't need to be
395     # disabled.
396     list(APPEND MSVC_DISABLED_WARNINGS
397       "4061" # Enum value not handled by a case in a switch on an enum. This isn't very helpful because it is produced even if a default statement is present.
398       "4100" # Unreferenced formal parameter.
399       "4127" # Conditional expression is constant.
400       "4131" # Old style declarator used. This is triggered by ext_bc's backend code.
401       "4189" # Local variable is initialized but not referenced.
402       "4191" # Unsafe type cast.
403       "4200" # Non-standard extension, zero sized array.
404       "4201" # Non-standard extension used: nameless struct/union.
405       "4232" # Non-standard extension used: 'pCurrent': address of dllimport.
406       "4245" # Implicit change from signed/unsigned when initializing.
407       "4255" # Implicitly converting fucntion prototype from `()` to `(void)`.
408       "4265" # Class has virtual functions, but destructor is not virtual.
409       "4287" # Unsigned/negative constant mismatch.
410       "4296" # '<' Expression is always false.
411       "4315" # 'this' pointer for member may not be aligned to 8 bytes as expected by the constructor.
412       "4324" # Structure was padded due to alignment specifier.
413       "4355" # 'this' used in base member initializer list.
414       "4365" # Signed/unsigned mismatch.
415       "4371" # Layout of class may have changed due to fixes in packing.
416       "4388" # Signed/unsigned mismatch on relative comparison operator.
417       "4389" # Signed/unsigned mismatch on equality comparison operator.
418       "4435" # Object layout under /vd2 will change due to virtual base.
419       "4456" # Declaration of local hides previous definition of local by the same name.
420       "4457" # Declaration of local hides function parameter.
421       "4458" # Declaration of parameter hides class member.
422       "4459" # Declaration of parameter hides global declaration.
423       "4464" # Relative include path contains "..". This is triggered by the TBB headers.
424       "4505" # Unreferenced local function has been removed. This is mostly the result of things not being needed under MSVC.
425       "4514" # Unreferenced inline function has been removed. (caused by /Zc:inline)
426       "4548" # Expression before comma has no effect. I wouldn't disable this normally, but malloc.h triggers this warning.
427       "4555" # Expression has no effect; expected expression with side-effect. This is triggered by boost/variant.hpp.
428       "4574" # ifdef'd macro was defined to 0.
429       "4582" # Constructor is not implicitly called.
430       "4583" # Destructor is not implicitly called.
431       "4608" # Member has already been initialized by another union member initializer.
432       "4619" # Invalid warning number used in #pragma warning.
433       "4623" # Default constructor was implicitly defined as deleted.
434       "4625" # Copy constructor was implicitly defined as deleted.
435       "4626" # Assignment operator was implicitly defined as deleted.
436       "4647" # __is_pod() has a different value in pervious versions of MSVC.
437       "4668" # Macro was not defined, replacing with 0.
438       "4701" # Potentially uninitialized local variable used.
439       "4702" # Unreachable code.
440       "4706" # Assignment within conditional expression.
441       "4709" # Comma operator within array index expression. This currently just produces false-positives.
442       "4710" # Function was not inlined.
443       "4711" # Function was selected for automated inlining. This produces tens of thousands of warnings in release mode if you leave it enabled, which will completely break Visual Studio, so don't enable it.
444       "4714" # Function marked as __forceinline not inlined.
445       "4774" # Format string expected in argument is not a string literal.
446       "4820" # Padding added after data member.
447       "4917" # A GUID can only be associated with a class. This is triggered by some standard windows headers.
448       "4946" # reinterpret_cast used between related types.
449       "5026" # Move constructor was implicitly defined as deleted.
450       "5027" # Move assignment operator was implicitly defined as deleted.
451       "5031" # #pragma warning(pop): likely mismatch, popping warning state pushed in different file. This is needed because of how boost does things.
452     )
453   endif()
455   if (MSVC_ENABLE_STATIC_ANALYSIS)
456     # Warnings disabled for /analyze
457     list(APPEND MSVC_DISABLED_WARNINGS
458       "6001" # Using uninitialized memory. This is disabled because it is wrong 99% of the time.
459       "6011" # Dereferencing potentially NULL pointer.
460       "6031" # Return value ignored.
461       "6235" # (<non-zero constant> || <expression>) is always a non-zero constant.
462       "6237" # (<zero> && <expression>) is always zero. <expression> is never evaluated and may have side effects.
463       "6239" # (<non-zero constant> && <expression>) always evaluates to the result of <expression>.
464       "6240" # (<expression> && <non-zero constant>) always evaluates to the result of <expression>.
465       "6246" # Local declaration hides declaration of same name in outer scope.
466       "6248" # Setting a SECURITY_DESCRIPTOR's DACL to NULL will result in an unprotected object. This is done by one of the boost headers.
467       "6255" # _alloca indicates failure by raising a stack overflow exception.
468       "6262" # Function uses more than x bytes of stack space.
469       "6271" # Extra parameter passed to format function. The analysis pass doesn't recognize %j or %z, even though the runtime does.
470       "6285" # (<non-zero constant> || <non-zero constant>) is always true.
471       "6297" # 32-bit value is shifted then cast to 64-bits. The places this occurs never use more than 32 bits.
472       "6308" # Realloc might return null pointer: assigning null pointer to '<name>', which is passed as an argument to 'realloc', will cause the original memory to leak.
473       "6326" # Potential comparison of a constant with another constant.
474       "6330" # Unsigned/signed mismatch when passed as a parameter.
475       "6340" # Mismatch on sign when passed as format string value.
476       "6387" # '<value>' could be '0': This does not adhere to the specification for a function.
477       "28182" # Dereferencing NULL pointer. '<value>' contains the same NULL value as '<expression>'.
478       "28251" # Inconsistent annotation for function. This is because we only annotate the declaration and not the definition.
479       "28278" # Function appears with no prototype in scope.
480     )
481   endif()
483   # Warnings disabled to keep it quiet for now,
484   # most of these should be reviewed and re-enabled:
485   list(APPEND MSVC_DISABLED_WARNINGS
486     "4005" # Macro redefinition
487     "4018" # Signed/unsigned mismatch.
488     "4242" # Possible loss of data when returning a value.
489     "4244" # Implicit truncation of data.
490     "4267" # Implicit truncation of data. This really shouldn't be disabled.
491     "4291" # No matching destructor found.
492     "4302" # Pointer casting size difference
493     "4311" # Pointer casting size difference
494     "4312" # Pointer casting size difference
495     "4477" # Parameter to a formatting function isn't the same type as was passed in the format string.
496     "4624" # Destructor was implicitly undefined.
497     "4804" # Unsafe use of type 'bool' in operation. (comparing if bool is <=> scalar)
498     "4805" # Unsafe mix of scalar type and type 'bool' in operation. (comparing if bool is == scalar)
499   )
501   # Warnings to treat as errors:
502   list(APPEND MSVC_WARNINGS_AS_ERRORS
503     "4099" # Mixed use of struct and class on same type names. This was absolutely everywhere, and can cause errors at link-time if not fixed.
504     "4129" # Unknown escape sequence. This is usually caused by incorrect escaping.
505     "4566" # Character cannot be represented in current charset. This is remidied by prefixing string with "u8".
506   )
508   # And the extra defines:
509   list(APPEND MSVC_ADDITIONAL_DEFINES
510     "NOMINMAX" # This is needed because, for some absurd reason, one of the windows headers tries to define "min" and "max" as macros, which messes up most uses of std::numeric_limits.
511     "_CRT_NONSTDC_NO_WARNINGS" # Don't deprecate posix names of functions.
512     "_CRT_SECURE_NO_WARNINGS" # Don't deprecate the non _s versions of various standard library functions, because safety is for chumps.
513     "_SCL_SECURE_NO_WARNINGS" # Don't deprecate the non _s versions of various standard library functions, because safety is for chumps.
514     "_WINSOCK_DEPRECATED_NO_WARNINGS" # Don't deprecate pieces of winsock
515     "YY_NO_UNISTD_H" # Because MSVC doesn't have unistd.h, which is requested by the YACC generated code.
516   )
518   # The options passed to the linker for EXE targets:
519   list(APPEND MSVC_EXE_LINKER_OPTIONS
520     "BASE:0x10000" # Base the program at just over 64k in memory, to play nice with the JIT.
521     "DYNAMICBASE:NO" # Don't randomize the base address.
522     "FIXED" # The program can only be loaded at its preferred base address.
523     "STACK:8388608,8388608" # Set the stack reserve,commit to 8mb. Reserve should probably be higher.
524     "time" # Output some timing information about the link.
525   )
527   # The options to pass to the compiler for debug builds:
528   list(APPEND MSVC_DEBUG_OPTIONS
529     "Gy-" # Disable function level linking.
530     "GF-" # Disable string pooling.
531   )
533   # Add /Ob2 if allowing inlining in debug mode:
534   if (MSVC_ENABLE_DEBUG_INLINING)
535     list(APPEND MSVC_DEBUG_OPTIONS "Ob2")
536   endif()
538   # The options to pass to the compiler for release builds:
539   list(APPEND MSVC_RELEASE_OPTIONS
540     "GF" # Enable string pooling. (this is enabled by default by the optimization level, but we enable it here for clarity)
541     "Gw" # Optimize global data. (-fdata-sections)
542     "Gy" # Enable function level linking. (-ffunction-sections)
543     "Qpar" # Enable parallel code generation. HHVM itself doesn't currently use this, but it's dependencies, TBB for instance, might, so enable it.
544     "Oi" # Enable intrinsic functions.
545     "Ot" # Favor fast code.
546   )
548   # Add /GL to the compiler, and /LTCG to the linker
549   # if link time code generation is enabled.
550   if (MSVC_ENABLE_LTCG)
551     list(APPEND MSVC_RELEASE_OPTIONS "GL")
552     list(APPEND MSVC_RELEASE_LINKER_OPTIONS "LTCG")
553   endif()
555   # The options to pass to the linker for debug builds for EXE targets:
556   list(APPEND MSVC_DEBUG_EXE_LINKER_OPTIONS
557     "OPT:NOREF" # No unreferenced data elimination. (well, mostly)
558     "OPT:NOICF" # No Identical COMDAT folding.
559   )
561   # The options to pass to the linker for release builds for EXE targets:
562   list(APPEND MSVC_RELEASE_EXE_LINKER_OPTIONS
563     "OPT:REF" # Remove unreferenced functions and data.
564     "OPT:ICF" # Identical COMDAT folding.
565   )
567   ############################################################
568   # Now we need to adjust a couple of the default option sets.
569   ############################################################
571   # We need the static runtime.
572   foreach(flag_var
573       CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
574       CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
575       CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
576       CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
577     if (${flag_var} MATCHES "/MD")
578       string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
579     endif()
580   endforeach()
582   # In order for /Zc:inline, which speeds up the build significantly, to work
583   # we need to remove the /Ob0 parameter that CMake adds by default, because that
584   # would normally disable all inlining.
585   foreach(flag_var CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG)
586     if (${flag_var} MATCHES "/Ob0")
587       string(REGEX REPLACE "/Ob0" "" ${flag_var} "${${flag_var}}")
588     endif()
589   endforeach()
591   # Ignore a warning about an object file not defining any symbols,
592   # these are known, and we don't care.
593   set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221")
595   ############################################################
596   # And finally, we can set all the flags we've built up.
597   ############################################################
599   foreach(opt ${MSVC_GENERAL_OPTIONS})
600     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /${opt}")
601     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /${opt}")
602   endforeach()
604   foreach(opt ${MSVC_DISABLED_WARNINGS})
605     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd${opt}")
606     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd${opt}")
607   endforeach()
609   foreach(opt ${MSVC_WARNINGS_AS_ERRORS})
610     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /we${opt}")
611     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /we${opt}")
612   endforeach()
614   foreach(opt ${MSVC_ADDITIONAL_DEFINES})
615     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D ${opt}")
616     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D ${opt}")
617   endforeach()
619   foreach(opt ${MSVC_EXE_LINKER_OPTIONS})
620     set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /${opt}")
621   endforeach()
623   foreach(opt ${MSVC_RELEASE_LINKER_OPTIONS})
624     foreach(flag_var
625         CMAKE_EXE_LINKER_FLAGS_RELEASE CMAKE_EXE_LINKER_FLAGS_MINSIZEREL CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
626         CMAKE_SHARED_LINKER_FLAGS_RELEASE CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
627         CMAKE_STATIC_LINKER_FLAGS_RELEASE CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO)
628       set(${flag_var} "${${flag_var}} /${opt}")
629     endforeach()
630   endforeach()
632   foreach(opt ${MSVC_DEBUG_OPTIONS})
633     set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /${opt}")
634     set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /${opt}")
635   endforeach()
637   foreach(opt ${MSVC_RELEASE_OPTIONS})
638     foreach(flag_var
639         CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
640         CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
641       set(${flag_var} "${${flag_var}} /${opt}")
642     endforeach()
643   endforeach()
645   foreach(opt ${MSVC_DEBUG_EXE_LINKER_OPTIONS})
646     set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /${opt}")
647   endforeach()
649   foreach(opt ${MSVC_RELEASE_EXE_LINKER_OPTIONS})
650     set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /${opt}")
651     set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /${opt}")
652     set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /${opt}")
653   endforeach()
654 else()
655   message("Warning: unknown/unsupported compiler, things may go wrong")
656 endif()
658 include(ThinArchives)