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