FollyCompilerMSVC.cmake 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. # Some additional configuration options.
  2. option(MSVC_ENABLE_ALL_WARNINGS "If enabled, pass /Wall to the compiler." ON)
  3. option(MSVC_ENABLE_DEBUG_INLINING "If enabled, enable inlining in the debug configuration. This allows /Zc:inline to be far more effective." OFF)
  4. option(MSVC_ENABLE_FAST_LINK "If enabled, pass /DEBUG:FASTLINK to the linker. This makes linking faster, but the gtest integration for Visual Studio can't currently handle the .pdbs generated." OFF)
  5. option(MSVC_ENABLE_LEAN_AND_MEAN_WINDOWS "If enabled, define WIN32_LEAN_AND_MEAN to include a smaller subset of Windows.h" ON)
  6. option(MSVC_ENABLE_LTCG "If enabled, use Link Time Code Generation for Release builds." OFF)
  7. option(MSVC_ENABLE_PARALLEL_BUILD "If enabled, build multiple source files in parallel." ON)
  8. option(MSVC_ENABLE_STATIC_ANALYSIS "If enabled, do more complex static analysis and generate warnings appropriately." OFF)
  9. option(MSVC_USE_STATIC_RUNTIME "If enabled, build against the static, rather than the dynamic, runtime." OFF)
  10. option(MSVC_SUPPRESS_BOOST_CONFIG_OUTDATED "If enabled, suppress Boost's warnings about the config being out of date." ON)
  11. # Alas, option() doesn't support string values.
  12. 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.")
  13. # Add a pretty drop-down selector for these values when using the GUI.
  14. set_property(
  15. CACHE MSVC_FAVORED_ARCHITECTURE
  16. PROPERTY STRINGS
  17. blend
  18. AMD64
  19. ATOM
  20. INTEL64
  21. )
  22. # Validate, and then add the favored architecture.
  23. 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")
  24. message(FATAL_ERROR "MSVC_FAVORED_ARCHITECTURE must be set to one of exactly, 'blend', 'AMD64', 'INTEL64', or 'ATOM'! Got '${MSVC_FAVORED_ARCHITECTURE}' instead!")
  25. endif()
  26. set(MSVC_LANGUAGE_VERSION "c++latest" CACHE STRING "One of 'c++14', 'c++17', or 'c++latest'. This determines which version of C++ to compile as.")
  27. set_property(
  28. CACHE MSVC_LANGUAGE_VERSION
  29. PROPERTY STRINGS
  30. "c++14"
  31. "c++17"
  32. "c++latest"
  33. )
  34. ############################################################
  35. # We need to adjust a couple of the default option sets.
  36. ############################################################
  37. # If the static runtime is requested, we have to
  38. # overwrite some of CMake's defaults.
  39. if (MSVC_USE_STATIC_RUNTIME)
  40. foreach(flag_var
  41. CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
  42. CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
  43. CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
  44. CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
  45. if (${flag_var} MATCHES "/MD")
  46. string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
  47. endif()
  48. endforeach()
  49. endif()
  50. # The Ninja generator doesn't de-dup the exception mode flag, so remove the
  51. # default flag so that MSVC doesn't warn about it on every single file.
  52. if ("${CMAKE_GENERATOR}" STREQUAL "Ninja")
  53. foreach(flag_var
  54. CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
  55. CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
  56. CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
  57. CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
  58. if (${flag_var} MATCHES "/EHsc")
  59. string(REGEX REPLACE "/EHsc" "" ${flag_var} "${${flag_var}}")
  60. endif()
  61. endforeach()
  62. endif()
  63. # In order for /Zc:inline, which speeds up the build significantly, to work
  64. # we need to remove the /Ob0 parameter that CMake adds by default, because that
  65. # would normally disable all inlining.
  66. foreach(flag_var CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG)
  67. if (${flag_var} MATCHES "/Ob0")
  68. string(REGEX REPLACE "/Ob0" "" ${flag_var} "${${flag_var}}")
  69. endif()
  70. endforeach()
  71. # Apply the option set for Folly to the specified target.
  72. function(apply_folly_compile_options_to_target THETARGET)
  73. # The general options passed:
  74. target_compile_options(${THETARGET}
  75. PUBLIC
  76. /EHa # Enable both SEH and C++ Exceptions.
  77. /GF # There are bugs with constexpr StringPiece when string pooling is disabled.
  78. /Zc:referenceBinding # Disallow temporaries from binding to non-const lvalue references.
  79. /Zc:rvalueCast # Enforce the standard rules for explicit type conversion.
  80. /Zc:implicitNoexcept # Enable implicit noexcept specifications where required, such as destructors.
  81. /Zc:strictStrings # Don't allow conversion from a string literal to mutable characters.
  82. /Zc:threadSafeInit # Enable thread-safe function-local statics initialization.
  83. /Zc:throwingNew # Assume operator new throws on failure.
  84. /permissive- # Be mean, don't allow bad non-standard stuff (C++/CLI, __declspec, etc. are all left intact).
  85. /std:${MSVC_LANGUAGE_VERSION} # Build in the requested version of C++
  86. PRIVATE
  87. /bigobj # Support objects with > 65k sections. Needed due to templates.
  88. /favor:${MSVC_FAVORED_ARCHITECTURE} # Architecture to prefer when generating code.
  89. /Zc:inline # Have the compiler eliminate unreferenced COMDAT functions and data before emitting the object file.
  90. $<$<BOOL:${MSVC_ENABLE_ALL_WARNINGS}>:/Wall> # Enable all warnings if requested.
  91. $<$<BOOL:${MSVC_ENABLE_PARALLEL_BUILD}>:/MP> # Enable multi-processor compilation if requested.
  92. $<$<BOOL:${MSVC_ENABLE_STATIC_ANALYSIS}>:/analyze> # Enable static analysis if requested.
  93. # Debug builds
  94. $<$<CONFIG:DEBUG>:
  95. /Gy- # Disable function level linking.
  96. $<$<BOOL:${MSVC_ENABLE_DEBUG_INLINING}>:/Ob2> # Add /Ob2 if allowing inlining in debug mode.
  97. >
  98. # Non-debug builds
  99. $<$<NOT:$<CONFIG:DEBUG>>:
  100. /Gw # Optimize global data. (-fdata-sections)
  101. /Gy # Enable function level linking. (-ffunction-sections)
  102. /Qpar # Enable parallel code generation.
  103. /Oi # Enable intrinsic functions.
  104. /Ot # Favor fast code.
  105. $<$<BOOL:${MSVC_ENABLE_LTCG}>:/GL> # Enable link time code generation.
  106. >
  107. )
  108. target_compile_options(${THETARGET}
  109. PUBLIC
  110. /wd4191 # 'type cast' unsafe conversion of function pointers
  111. /wd4291 # no matching operator delete found
  112. /wd4309 # '=' truncation of constant value
  113. /wd4310 # cast truncates constant value
  114. /wd4366 # result of unary '&' operator may be unaligned
  115. /wd4587 # behavior change; constructor no longer implicitly called
  116. /wd4592 # symbol will be dynamically initialized (implementation limitation)
  117. /wd4628 # digraphs not supported with -Ze
  118. /wd4723 # potential divide by 0
  119. /wd4724 # potential mod by 0
  120. /wd4868 # compiler may not enforce left-to-right evaluation order
  121. /wd4996 # user deprecated
  122. # The warnings that are disabled:
  123. /wd4068 # Unknown pragma.
  124. /wd4091 # 'typedef' ignored on left of '' when no variable is declared.
  125. /wd4146 # Unary minus applied to unsigned type, result still unsigned.
  126. /wd4800 # Values being forced to bool, this happens many places, and is a "performance warning".
  127. # NOTE: glog/logging.h:1116 change to `size_t pcount() const { return size_t(pptr() - pbase()); }`
  128. # NOTE: gmock/gmock-spec-builders.h:1177 change to `*static_cast<const Action<F>*>(untyped_actions_[size_t(count - 1)]) :`
  129. # NOTE: gmock/gmock-spec-builders.h:1749 change to `const size_t count = untyped_expectations_.size();`
  130. # NOTE: gmock/gmock-spec-builders.h:1754 change to `for (size_t i = 0; i < count; i++) {`
  131. # NOTE: gtest/gtest-printers.h:173 change to `const internal::BiggestInt kBigInt = internal::BiggestInt(value);`
  132. # NOTE: gtest/internal/gtest-internal.h:890 add `GTEST_DISABLE_MSC_WARNINGS_PUSH_(4365)`
  133. # NOTE: gtest/internal/gtest-internal.h:894 ass `GTEST_DISABLE_MSC_WARNINGS_POP_()`
  134. # NOTE: boost/crc.hpp:578 change to `{ return static_cast<unsigned char>(x ^ rem); }`
  135. # NOTE: boost/regex/v4/match_results.hpp:126 change to `return m_subs[size_type(sub)].length();`
  136. # NOTE: boost/regex/v4/match_results.hpp:226 change to `return m_subs[size_type(sub)];`
  137. # NOTE: boost/date_time/adjust_functors.hpp:67 change to `origDayOfMonth_ = short(ymd.day);`
  138. # NOTE: boost/date_time/adjust_functors.hpp:75 change to `wrap_int2 wi(short(ymd.month));`
  139. # NOTE: boost/date_time/adjust_functors.hpp:82 change to `day_type resultingEndOfMonthDay(cal_type::end_of_month_day(static_cast<unsigned short>(year), static_cast<unsigned short>(wi.as_int())));`
  140. # NOTE: boost/date_time/adjust_functors.hpp:85 change to `return date_type(static_cast<unsigned short>(year), static_cast<unsigned short>(wi.as_int()), resultingEndOfMonthDay) - d;`
  141. # NOTE: boost/date_time/adjust_functors.hpp:87 change to `day_type dayOfMonth = static_cast<unsigned short>(origDayOfMonth_);`
  142. # NOTE: boost/date_time/adjust_functors.hpp:91 change to `return date_type(static_cast<unsigned short>(year), static_cast<unsigned short>(wi.as_int()), dayOfMonth) - d;`
  143. # NOTE: boost/date_time/adjust_functors.hpp:98 change to `origDayOfMonth_ = short(ymd.day);`
  144. # NOTE: boost/date_time/adjust_functors.hpp:106 change to `wrap_int2 wi(short(ymd.month));`
  145. # NOTE: boost/date_time/adjust_functors.hpp:111 change to `day_type resultingEndOfMonthDay(cal_type::end_of_month_day(static_cast<unsigned short>(year), static_cast<unsigned short>(wi.as_int())));`
  146. # NOTE: boost/date_time/adjust_functors.hpp:114 change to `return date_type(static_cast<unsigned short>(year), static_cast<unsigned short>(wi.as_int()), resultingEndOfMonthDay) - d;`
  147. # NOTE: boost/date_time/adjust_functors.hpp:116 change to `day_type dayOfMonth = static_cast<unsigned short>(origDayOfMonth_);`
  148. # NOTE: boost/date_time/adjust_functors.hpp:120 change to `return date_type(static_cast<unsigned short>(year), static_cast<unsigned short>(wi.as_int()), dayOfMonth) - d;`
  149. # NOTE: boost/date_time/gregorian_calendar.ipp:81 change to `unsigned long d = static_cast<unsigned long>(ymd.day + ((153*m + 2)/5) + 365*y + (y/4) - (y/100) + (y/400) - 32045);`
  150. # NOTE: boost/date_time/gregorian/greg_date.hpp:122 change to `unsigned short eom_day = gregorian_calendar::end_of_month_day(ymd.year, ymd.month);`
  151. # NOTE: boost/thread/future.hpp:1050 change to `locks[std::ptrdiff_t(i)]=BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(futures[i].future_->mutex));`
  152. # NOTE: boost/thread/future.hpp:1063 change to `locks[std::ptrdiff_t(i)].unlock();`
  153. # NOTE: boost/thread/win32/basic_recursive_mutex.hpp:47 change to `long const current_thread_id=long(win32::GetCurrentThreadId());`
  154. # NOTE: boost/thread/win32/basic_recursive_mutex.hpp:53 change to `long const current_thread_id=long(win32::GetCurrentThreadId());`
  155. # NOTE: boost/thread/win32/basic_recursive_mutex.hpp:64 change to `long const current_thread_id=long(win32::GetCurrentThreadId());`
  156. # NOTE: boost/thread/win32/basic_recursive_mutex.hpp:78 change to `long const current_thread_id=long(win32::GetCurrentThreadId());`
  157. # NOTE: boost/thread/win32/basic_recursive_mutex.hpp:84 change to `long const current_thread_id=long(win32::GetCurrentThreadId());`
  158. # NOTE: boost/thread/win32/condition_variable.hpp:79 change to `detail::win32::ReleaseSemaphore(semaphore,long(count_to_release),0);`
  159. # NOTE: boost/thread/win32/condition_variable.hpp:84 change to `release(unsigned(detail::interlocked_read_acquire(&waiters)));`
  160. # NOTE: boost/algorithm/string/detail/classification.hpp:85 change to `std::size_t Size=std::size_t(::boost::distance(Range));`
  161. /wd4018 # Signed/unsigned mismatch.
  162. /wd4365 # Signed/unsigned mismatch.
  163. /wd4388 # Signed/unsigned mismatch on relative comparison operator.
  164. /wd4389 # Signed/unsigned mismatch on equality comparison operator.
  165. # TODO:
  166. /wd4100 # Unreferenced formal parameter.
  167. /wd4459 # Declaration of parameter hides global declaration.
  168. /wd4505 # Unreferenced local function has been removed.
  169. /wd4701 # Potentially uninitialized local variable used.
  170. /wd4702 # Unreachable code.
  171. # These warnings are disabled because we've
  172. # enabled all warnings. If all warnings are
  173. # not enabled, we still need to disable them
  174. # for consuming libs.
  175. /wd4061 # 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.
  176. /wd4127 # Conditional expression is constant.
  177. /wd4200 # Non-standard extension, zero sized array.
  178. /wd4201 # Non-standard extension used: nameless struct/union.
  179. /wd4296 # '<' Expression is always false.
  180. /wd4316 # Object allocated on the heap may not be aligned to 128.
  181. /wd4324 # Structure was padded due to alignment specifier.
  182. /wd4355 # 'this' used in base member initializer list.
  183. /wd4371 # Layout of class may have changed due to fixes in packing.
  184. /wd4435 # Object layout under /vd2 will change due to virtual base.
  185. /wd4514 # Unreferenced inline function has been removed. (caused by /Zc:inline)
  186. /wd4548 # Expression before comma has no effect. I wouldn't disable this normally, but malloc.h triggers this warning.
  187. /wd4574 # ifdef'd macro was defined to 0.
  188. /wd4582 # Constructor is not implicitly called.
  189. /wd4583 # Destructor is not implicitly called.
  190. /wd4619 # Invalid warning number used in #pragma warning.
  191. /wd4623 # Default constructor was implicitly defined as deleted.
  192. /wd4625 # Copy constructor was implicitly defined as deleted.
  193. /wd4626 # Assignment operator was implicitly defined as deleted.
  194. /wd4643 # Forward declaring standard library types is not permitted.
  195. /wd4647 # Behavior change in __is_pod.
  196. /wd4668 # Macro was not defined, replacing with 0.
  197. /wd4706 # Assignment within conditional expression.
  198. /wd4710 # Function was not inlined.
  199. /wd4711 # Function was selected for automated inlining.
  200. /wd4714 # Function marked as __forceinline not inlined.
  201. /wd4820 # Padding added after data member.
  202. /wd5026 # Move constructor was implicitly defined as deleted.
  203. /wd5027 # Move assignment operator was implicitly defined as deleted.
  204. /wd5031 # #pragma warning(pop): likely mismatch, popping warning state pushed in different file. This is needed because of how boost does things.
  205. /wd5045 # Compiler will insert Spectre mitigation for memory load if /Qspectre switch is specified.
  206. # Warnings to treat as errors:
  207. /we4099 # Mixed use of struct and class on same type names.
  208. /we4129 # Unknown escape sequence. This is usually caused by incorrect escaping.
  209. /we4566 # Character cannot be represented in current charset. This is remidied by prefixing string with "u8".
  210. PRIVATE
  211. # Warnings disabled for /analyze
  212. $<$<BOOL:${MSVC_ENABLE_STATIC_ANALYSIS}>:
  213. /wd6001 # Using uninitialized memory. This is disabled because it is wrong 99% of the time.
  214. /wd6011 # Dereferencing potentially NULL pointer.
  215. /wd6031 # Return value ignored.
  216. /wd6235 # (<non-zero constant> || <expression>) is always a non-zero constant.
  217. /wd6237 # (<zero> && <expression>) is always zero. <expression> is never evaluated and may have side effects.
  218. /wd6239 # (<non-zero constant> && <expression>) always evaluates to the result of <expression>.
  219. /wd6240 # (<expression> && <non-zero constant>) always evaluates to the result of <expression>.
  220. /wd6246 # Local declaration hides declaration of same name in outer scope.
  221. /wd6248 # Setting a SECURITY_DESCRIPTOR's DACL to NULL will result in an unprotected object. This is done by one of the boost headers.
  222. /wd6255 # _alloca indicates failure by raising a stack overflow exception.
  223. /wd6262 # Function uses more than x bytes of stack space.
  224. /wd6271 # Extra parameter passed to format function. The analysis pass doesn't recognize %j or %z, even though the runtime does.
  225. /wd6285 # (<non-zero constant> || <non-zero constant>) is always true.
  226. /wd6297 # 32-bit value is shifted then cast to 64-bits. The places this occurs never use more than 32 bits.
  227. /wd6308 # 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.
  228. /wd6326 # Potential comparison of a constant with another constant.
  229. /wd6330 # Unsigned/signed mismatch when passed as a parameter.
  230. /wd6340 # Mismatch on sign when passed as format string value.
  231. /wd6387 # '<value>' could be '0': This does not adhere to the specification for a function.
  232. /wd28182 # Dereferencing NULL pointer. '<value>' contains the same NULL value as '<expression>'.
  233. /wd28251 # Inconsistent annotation for function. This is because we only annotate the declaration and not the definition.
  234. /wd28278 # Function appears with no prototype in scope.
  235. >
  236. )
  237. # And the extra defines:
  238. target_compile_definitions(${THETARGET}
  239. PUBLIC
  240. _CRT_NONSTDC_NO_WARNINGS # Don't deprecate posix names of functions.
  241. _CRT_SECURE_NO_WARNINGS # Don't deprecate the non _s versions of various standard library functions, because safety is for chumps.
  242. _SCL_SECURE_NO_WARNINGS # Don't deprecate the non _s versions of various standard library functions, because safety is for chumps.
  243. _ENABLE_EXTENDED_ALIGNED_STORAGE #A type with an extended alignment in VS 15.8 or later
  244. _STL_EXTRA_DISABLED_WARNINGS=4774\ 4987
  245. $<$<BOOL:${MSVC_ENABLE_CPP_LATEST}>:_HAS_AUTO_PTR_ETC=1> # We're building in C++ 17 or greater mode, but certain dependencies (Boost) still have dependencies on unary_function and binary_function, so we have to make sure not to remove them.
  246. $<$<BOOL:${MSVC_ENABLE_LEAN_AND_MEAN_WINDOWS}>:WIN32_LEAN_AND_MEAN> # Don't include most of Windows.h
  247. $<$<BOOL:${MSVC_SUPPRESS_BOOST_CONFIG_OUTDATED}>:BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE> # MSVC moves faster than boost, so add a quick way to disable the messages.
  248. )
  249. # Ignore a warning about an object file not defining any symbols,
  250. # these are known, and we don't care.
  251. set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY STATIC_LIBRARY_FLAGS " /ignore:4221")
  252. # The options to pass to the linker:
  253. set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /INCREMENTAL") # Do incremental linking.
  254. if (NOT $<TARGET_PROPERTY:${THETARGET},TYPE> STREQUAL "STATIC_LIBRARY")
  255. set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /OPT:NOREF") # No unreferenced data elimination.
  256. set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /OPT:NOICF") # No Identical COMDAT folding.
  257. set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " /OPT:REF") # Remove unreferenced functions and data.
  258. set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " /OPT:ICF") # Identical COMDAT folding.
  259. endif()
  260. if (MSVC_ENABLE_FAST_LINK)
  261. set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /DEBUG:FASTLINK") # Generate a partial PDB file that simply references the original object and library files.
  262. endif()
  263. # Add /GL to the compiler, and /LTCG to the linker
  264. # if link time code generation is enabled.
  265. if (MSVC_ENABLE_LTCG)
  266. set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " /LTCG")
  267. endif()
  268. endfunction()
  269. list(APPEND FOLLY_LINK_LIBRARIES Iphlpapi.lib Ws2_32.lib)