Add CMake build system
authorChristopher Dykes <cdykes@fb.com>
Thu, 13 Apr 2017 05:25:15 +0000 (22:25 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Thu, 13 Apr 2017 05:35:08 +0000 (22:35 -0700)
Summary: This is for use on Windows only, and does not support Linux or OSX in the slightest. There are probably still a few hacks laying around in it, but it works, and that's good enough for now.

Reviewed By: yfeldblum

Differential Revision: D4873498

fbshipit-source-id: 5952a927037dc1d56c51e71d51ba506d2cd17357

CMake/FindDoubleConversion.cmake [new file with mode: 0755]
CMake/FindGFlags.cmake [new file with mode: 0755]
CMake/FindGMock.cmake [new file with mode: 0755]
CMake/FindGlog.cmake [new file with mode: 0755]
CMake/FindLibEvent.cmake [new file with mode: 0755]
CMake/FindPThread.cmake [new file with mode: 0755]
CMake/FollyCompiler.cmake [new file with mode: 0755]
CMake/FollyFunctions.cmake [new file with mode: 0755]
CMake/folly-config.h.cmake [new file with mode: 0755]
CMake/folly-deps.cmake [new file with mode: 0755]
CMakeLists.txt [new file with mode: 0755]

diff --git a/CMake/FindDoubleConversion.cmake b/CMake/FindDoubleConversion.cmake
new file mode 100755 (executable)
index 0000000..0a967eb
--- /dev/null
@@ -0,0 +1,22 @@
+# Finds libdouble-conversion.
+#
+# This module defines:
+# DOUBLE_CONVERSION_INCLUDE_DIR
+# DOUBLE_CONVERSION_LIBRARY
+#
+
+find_path(DOUBLE_CONVERSION_INCLUDE_DIR double-conversion/double-conversion.h)
+find_library(DOUBLE_CONVERSION_LIBRARY NAMES double-conversion)
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(
+    DOUBLE_CONVERSION DEFAULT_MSG
+    DOUBLE_CONVERSION_LIBRARY DOUBLE_CONVERSION_INCLUDE_DIR)
+
+if (NOT DOUBLE_CONVERSION_FOUND)
+  message(STATUS "Using third-party bundled double-conversion")
+else()
+  message(STATUS "Found double-conversion: ${DOUBLE_CONVERSION_LIBRARY}")
+endif (NOT DOUBLE_CONVERSION_FOUND)
+
+mark_as_advanced(DOUBLE_CONVERSION_INCLUDE_DIR DOUBLE_CONVERSION_LIBRARY)
diff --git a/CMake/FindGFlags.cmake b/CMake/FindGFlags.cmake
new file mode 100755 (executable)
index 0000000..167bdd4
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Find libgflags
+#
+#  LIBGFLAGS_INCLUDE_DIR - where to find gflags/gflags.h, etc.
+#  LIBGFLAGS_LIBRARY     - List of libraries when using libgflags.
+#  LIBGFLAGS_FOUND       - True if libgflags found.
+
+
+IF (LIBGFLAGS_INCLUDE_DIR)
+  # Already in cache, be silent
+  SET(LIBGFLAGS_FIND_QUIETLY TRUE)
+ENDIF ()
+
+FIND_PATH(LIBGFLAGS_INCLUDE_DIR gflags/gflags.h)
+
+FIND_LIBRARY(LIBGFLAGS_LIBRARY gflags)
+
+# handle the QUIETLY and REQUIRED arguments and set LIBGFLAGS_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBGFLAGS DEFAULT_MSG LIBGFLAGS_LIBRARY LIBFLAGS_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(LIBGFLAGS_LIBRARY LIBGFLAGS_INCLUDE_DIR)
diff --git a/CMake/FindGMock.cmake b/CMake/FindGMock.cmake
new file mode 100755 (executable)
index 0000000..d4f6152
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Find libgmock
+#
+#  LIBGMOCK_INCLUDE_DIR - where to find gmock/gmock.h, etc.
+#  LIBGMOCK_LIBRARY     - List of libraries when using libgmock.
+#  LIBGMOCK_FOUND       - True if libgmock found.
+
+
+IF (LIBGMOCK_INCLUDE_DIR)
+  # Already in cache, be silent
+  SET(LIBGMOCK_FIND_QUIETLY TRUE)
+ENDIF ()
+
+FIND_PATH(LIBGMOCK_INCLUDE_DIR gmock/gmock.h)
+
+FIND_LIBRARY(LIBGMOCK_LIBRARY gmock_main)
+
+# handle the QUIETLY and REQUIRED arguments and set LIBGMOCK_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBGMOCK DEFAULT_MSG LIBGMOCK_LIBRARY LIBGMOCK_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(LIBGMOCK_LIBRARY LIBGMOCK_INCLUDE_DIR)
diff --git a/CMake/FindGlog.cmake b/CMake/FindGlog.cmake
new file mode 100755 (executable)
index 0000000..4338159
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Find libglog
+#
+#  LIBGLOG_INCLUDE_DIR - where to find glog/logging.h, etc.
+#  LIBGLOG_LIBRARY     - List of libraries when using libglog.
+#  LIBGLOG_FOUND       - True if libglog found.
+
+
+IF (LIBGLOG_INCLUDE_DIR)
+  # Already in cache, be silent
+  SET(LIBGLOG_FIND_QUIETLY TRUE)
+ENDIF ()
+
+FIND_PATH(LIBGLOG_INCLUDE_DIR glog/logging.h)
+
+FIND_LIBRARY(LIBGLOG_LIBRARY glog)
+
+# handle the QUIETLY and REQUIRED arguments and set LIBGLOG_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBGLOG DEFAULT_MSG LIBGLOG_LIBRARY LIBGLOG_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(LIBGLOG_LIBRARY LIBGLOG_INCLUDE_DIR)
diff --git a/CMake/FindLibEvent.cmake b/CMake/FindLibEvent.cmake
new file mode 100755 (executable)
index 0000000..eca43a4
--- /dev/null
@@ -0,0 +1,37 @@
+# - Find LibEvent (a cross event library)
+# This module defines
+# LIBEVENT_INCLUDE_DIR, where to find LibEvent headers
+# LIBEVENT_LIB, LibEvent libraries
+# LibEvent_FOUND, If false, do not try to use libevent
+
+set(LibEvent_EXTRA_PREFIXES /usr/local /opt/local "$ENV{HOME}")
+foreach(prefix ${LibEvent_EXTRA_PREFIXES})
+  list(APPEND LibEvent_INCLUDE_PATHS "${prefix}/include")
+  list(APPEND LibEvent_LIB_PATHS "${prefix}/lib")
+endforeach()
+
+find_path(LIBEVENT_INCLUDE_DIR event.h PATHS ${LibEvent_INCLUDE_PATHS})
+find_library(LIBEVENT_LIB NAMES event PATHS ${LibEvent_LIB_PATHS})
+
+if (LIBEVENT_LIB AND LIBEVENT_INCLUDE_DIR)
+  set(LibEvent_FOUND TRUE)
+  set(LIBEVENT_LIB ${LIBEVENT_LIB})
+else ()
+  set(LibEvent_FOUND FALSE)
+endif ()
+
+if (LibEvent_FOUND)
+  if (NOT LibEvent_FIND_QUIETLY)
+    message(STATUS "Found libevent: ${LIBEVENT_LIB}")
+  endif ()
+else ()
+  if (LibEvent_FIND_REQUIRED)
+    message(FATAL_ERROR "Could NOT find libevent.")
+  endif ()
+  message(STATUS "libevent NOT found.")
+endif ()
+
+mark_as_advanced(
+    LIBEVENT_LIB
+    LIBEVENT_INCLUDE_DIR
+  )
diff --git a/CMake/FindPThread.cmake b/CMake/FindPThread.cmake
new file mode 100755 (executable)
index 0000000..4eda894
--- /dev/null
@@ -0,0 +1,27 @@
+# - Try to find libpthread
+#
+# Once done this will define
+#
+#  LIBPTHREAD_FOUND - system has libpthread
+#  LIBPTHREAD_INCLUDE_DIRS - the libpthread include directory
+#  LIBPTHREAD_LIBRARIES - Link these to use libpthread
+#  LIBPTHREAD_DEFINITIONS - Compiler switches required for using libpthread
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+
+if (LIBPTHREAD_LIBRARIES AND LIBPTHREAD_INCLUDE_DIRS)
+  set (LIBPTHREAD_FIND_QUIETLY TRUE)
+endif (LIBPTHREAD_LIBRARIES AND LIBPTHREAD_INCLUDE_DIRS)
+
+find_path (LIBPTHREAD_INCLUDE_DIRS NAMES pthread.h)
+find_library (LIBPTHREAD_LIBRARIES NAMES pthread)
+
+include (FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBPTHREAD DEFAULT_MSG
+  LIBPTHREAD_LIBRARIES LIBPTHREAD_INCLUDE_DIRS)
+
+mark_as_advanced(LIBPTHREAD_INCLUDE_DIRS LIBPTHREAD_LIBRARIES LIBPTHREAD_FOUND)
diff --git a/CMake/FollyCompiler.cmake b/CMake/FollyCompiler.cmake
new file mode 100755 (executable)
index 0000000..e01f656
--- /dev/null
@@ -0,0 +1,258 @@
+# Some additional configuration options.\r
+option(MSVC_ENABLE_ALL_WARNINGS "If enabled, pass /Wall to the compiler." ON)\r
+option(MSVC_ENABLE_DEBUG_INLINING "If enabled, enable inlining in the debug configuration. This allows /Zc:inline to be far more effective." OFF)\r
+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)\r
+option(MSVC_ENABLE_LTCG "If enabled, use Link Time Code Generation for Release builds." OFF)\r
+option(MSVC_ENABLE_PARALLEL_BUILD "If enabled, build multiple source files in parallel." ON)\r
+option(MSVC_ENABLE_STATIC_ANALYSIS "If enabled, do more complex static analysis and generate warnings appropriately." OFF)\r
+option(MSVC_USE_STATIC_RUNTIME "If enabled, build against the static, rather than the dynamic, runtime." OFF)\r
+\r
+# Alas, option() doesn't support string values.\r
+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.")\r
+# Validate, and then add the favored architecture.\r
+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")\r
+  message(FATAL_ERROR "MSVC_FAVORED_ARCHITECTURE must be set to one of exactly, 'blend', 'AMD64', 'INTEL64', or 'ATOM'! Got '${MSVC_FAVORED_ARCHITECTURE}' instead!")\r
+endif()\r
+\r
+############################################################\r
+# We need to adjust a couple of the default option sets.\r
+############################################################\r
+\r
+# If the static runtime is requested, we have to\r
+# overwrite some of CMake's defaults.\r
+if (MSVC_USE_STATIC_RUNTIME)\r
+  foreach(flag_var\r
+      CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE\r
+      CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO\r
+      CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE\r
+      CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)\r
+    if (${flag_var} MATCHES "/MD")\r
+      string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")\r
+    endif()\r
+  endforeach()\r
+endif()\r
+\r
+# In order for /Zc:inline, which speeds up the build significantly, to work\r
+# we need to remove the /Ob0 parameter that CMake adds by default, because that\r
+# would normally disable all inlining.\r
+foreach(flag_var CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG)\r
+  if (${flag_var} MATCHES "/Ob0")\r
+    string(REGEX REPLACE "/Ob0" "" ${flag_var} "${${flag_var}}")\r
+  endif()\r
+endforeach()\r
+\r
+# Apply the option set for Folly to the specified target.\r
+function(apply_folly_compile_options_to_target THETARGET)\r
+  # The general options passed:\r
+  target_compile_options(${THETARGET}\r
+    PUBLIC\r
+      #/std:c++latest # Build in C++17 mode\r
+      /EHa # Enable both SEH and C++ Exceptions.\r
+      /Zc:referenceBinding # Disallow temporaries from binding to non-const lvalue references.\r
+      /Zc:rvalueCast # Enforce the standard rules for explicit type conversion.\r
+      /Zc:implicitNoexcept # Enable implicit noexcept specifications where required, such as destructors.\r
+      /Zc:strictStrings # Don't allow conversion from a string literal to mutable characters.\r
+      /Zc:threadSafeInit # Enable thread-safe function-local statics initialization.\r
+      /Zc:throwingNew # Assume operator new throws on failure.\r
+      /permissive- # Be mean, don't allow bad non-standard stuff (C++/CLI, __declspec, etc. are all left intact).\r
+    PRIVATE\r
+      /bigobj # Support objects with > 65k sections. Needed due to templates.\r
+      /favor:${MSVC_FAVORED_ARCHITECTURE} # Architecture to prefer when generating code.\r
+      /Zc:inline # Have the compiler eliminate unreferenced COMDAT functions and data before emitting the object file.\r
+\r
+      $<$<BOOL:${MSVC_ENABLE_ALL_WARNINGS}>:/Wall> # Enable all warnings if requested.\r
+      $<$<BOOL:${MSVC_ENABLE_PARALLEL_BUILD}>:/MP> # Enable multi-processor compilation if requested.\r
+      $<$<BOOL:${MSVC_ENABLE_STATIC_ANALYSIS}>:/analyze> # Enable static analysis if requested.\r
+\r
+      # Debug builds\r
+      $<$<CONFIG:DEBUG>:\r
+        /Gy- # Disable function level linking.\r
+        /GF- # Disable string pooling.\r
+\r
+        $<$<BOOL:${MSVC_ENABLE_DEBUG_INLINING}>:/Ob2> # Add /Ob2 if allowing inlining in debug mode.\r
+      >\r
+\r
+      # Non-debug builds\r
+      $<$<NOT:$<CONFIG:DEBUG>>:\r
+        /GF # Enable string pooling. (this is enabled by default by the optimization level, but we enable it here for clarity)\r
+        /Gw # Optimize global data. (-fdata-sections)\r
+        /Gy # Enable function level linking. (-ffunction-sections)\r
+        /Qpar # Enable parallel code generation.\r
+        /Oi # Enable intrinsic functions.\r
+        /Ot # Favor fast code.\r
+\r
+        $<$<BOOL:${MSVC_ENABLE_LTCG}>:/GL> # Enable link time code generation.\r
+      >\r
+  )\r
+\r
+  target_compile_options(${THETARGET}\r
+    PUBLIC\r
+      /wd4191 # 'type cast' unsafe conversion of function pointers\r
+      /wd4291 # no matching operator delete found\r
+      /wd4309 # '=' truncation of constant value\r
+      /wd4310 # cast truncates constant value\r
+      /wd4366 # result of unary '&' operator may be unaligned\r
+      /wd4587 # behavior change; constructor no longer implicitly called\r
+      /wd4592 # symbol will be dynamically initialized (implementation limitation)\r
+      /wd4723 # potential divide by 0\r
+      /wd4724 # potential mod by 0\r
+      /wd4868 # compiler may not enforce left-to-right evaluation order\r
+      /wd4996 # user deprecated\r
+\r
+      # The warnings that are disabled:\r
+      /wd4068 # Unknown pragma.\r
+      /wd4091 # 'typedef' ignored on left of '' when no variable is declared.\r
+      /wd4146 # Unary minus applied to unsigned type, result still unsigned.\r
+      /wd4800 # Values being forced to bool, this happens many places, and is a "performance warning".\r
+\r
+      # NOTE: glog/logging.h:1116 change to `size_t pcount() const { return size_t(pptr() - pbase()); }`\r
+      # NOTE: gmock/gmock-spec-builders.h:1177 change to `*static_cast<const Action<F>*>(untyped_actions_[size_t(count - 1)]) :`\r
+      # NOTE: gmock/gmock-spec-builders.h:1749 change to `const size_t count = untyped_expectations_.size();`\r
+      # NOTE: gmock/gmock-spec-builders.h:1754 change to `for (size_t i = 0; i < count; i++) {`\r
+      # NOTE: gtest/gtest-printers.h:173 change to `const internal::BiggestInt kBigInt = internal::BiggestInt(value);`\r
+      # NOTE: gtest/internal/gtest-internal.h:890 add `GTEST_DISABLE_MSC_WARNINGS_PUSH_(4365)`\r
+      # NOTE: gtest/internal/gtest-internal.h:894 ass `GTEST_DISABLE_MSC_WARNINGS_POP_()`\r
+      # NOTE: boost/crc.hpp:578 change to `{ return static_cast<unsigned char>(x ^ rem); }`\r
+      # NOTE: boost/regex/v4/match_results.hpp:126 change to `return m_subs[size_type(sub)].length();`\r
+      # NOTE: boost/regex/v4/match_results.hpp:226 change to `return m_subs[size_type(sub)];`\r
+      # NOTE: boost/date_time/adjust_functors.hpp:67 change to `origDayOfMonth_ = short(ymd.day);`\r
+      # NOTE: boost/date_time/adjust_functors.hpp:75 change to `wrap_int2 wi(short(ymd.month));`\r
+      # 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())));`\r
+      # 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;`\r
+      # NOTE: boost/date_time/adjust_functors.hpp:87 change to `day_type dayOfMonth = static_cast<unsigned short>(origDayOfMonth_);`\r
+      # 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;`\r
+      # NOTE: boost/date_time/adjust_functors.hpp:98 change to `origDayOfMonth_ = short(ymd.day);`\r
+      # NOTE: boost/date_time/adjust_functors.hpp:106 change to `wrap_int2 wi(short(ymd.month));`\r
+      # 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())));`\r
+      # 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;`\r
+      # NOTE: boost/date_time/adjust_functors.hpp:116 change to `day_type dayOfMonth = static_cast<unsigned short>(origDayOfMonth_);`\r
+      # 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;`\r
+      # 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);`\r
+      # 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);`\r
+      # 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));`\r
+      # NOTE: boost/thread/future.hpp:1063 change to `locks[std::ptrdiff_t(i)].unlock();`\r
+      # NOTE: boost/thread/win32/basic_recursive_mutex.hpp:47 change to `long const current_thread_id=long(win32::GetCurrentThreadId());`\r
+      # NOTE: boost/thread/win32/basic_recursive_mutex.hpp:53 change to `long const current_thread_id=long(win32::GetCurrentThreadId());`\r
+      # NOTE: boost/thread/win32/basic_recursive_mutex.hpp:64 change to `long const current_thread_id=long(win32::GetCurrentThreadId());`\r
+      # NOTE: boost/thread/win32/basic_recursive_mutex.hpp:78 change to `long const current_thread_id=long(win32::GetCurrentThreadId());`\r
+      # NOTE: boost/thread/win32/basic_recursive_mutex.hpp:84 change to `long const current_thread_id=long(win32::GetCurrentThreadId());`\r
+      # NOTE: boost/thread/win32/condition_variable.hpp:79 change to `detail::win32::ReleaseSemaphore(semaphore,long(count_to_release),0);`\r
+      # NOTE: boost/thread/win32/condition_variable.hpp:84 change to `release(unsigned(detail::interlocked_read_acquire(&waiters)));`\r
+      # NOTE: boost/algorithm/string/detail/classification.hpp:85 change to `std::size_t Size=std::size_t(::boost::distance(Range));`\r
+      /wd4018 # Signed/unsigned mismatch.\r
+      /wd4365 # Signed/unsigned mismatch.\r
+      /wd4388 # Signed/unsigned mismatch on relative comparison operator.\r
+      /wd4389 # Signed/unsigned mismatch on equality comparison operator.\r
+\r
+      # TODO:\r
+      /wd4100 # Unreferenced formal parameter.\r
+      /wd4459 # Declaration of parameter hides global declaration.\r
+      /wd4505 # Unreferenced local function has been removed.\r
+      /wd4701 # Potentially uninitialized local variable used.\r
+      /wd4702 # Unreachable code.\r
+\r
+      # These warnings are disabled because we've\r
+      # enabled all warnings. If all warnings are\r
+      # not enabled, we still need to disable them\r
+      # for consuming libs.\r
+      /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.\r
+      /wd4127 # Conditional expression is constant.\r
+      /wd4200 # Non-standard extension, zero sized array.\r
+      /wd4201 # Non-standard extension used: nameless struct/union.\r
+      /wd4296 # '<' Expression is always false.\r
+      /wd4316 # Object allocated on the heap may not be aligned to 128.\r
+      /wd4324 # Structure was padded due to alignment specifier.\r
+      /wd4355 # 'this' used in base member initializer list.\r
+      /wd4371 # Layout of class may have changed due to fixes in packing.\r
+      /wd4435 # Object layout under /vd2 will change due to virtual base.\r
+      /wd4514 # Unreferenced inline function has been removed. (caused by /Zc:inline)\r
+      /wd4548 # Expression before comma has no effect. I wouldn't disable this normally, but malloc.h triggers this warning.\r
+      /wd4574 # ifdef'd macro was defined to 0.\r
+      /wd4582 # Constructor is not implicitly called.\r
+      /wd4583 # Destructor is not implicitly called.\r
+      /wd4619 # Invalid warning number used in #pragma warning.\r
+      /wd4623 # Default constructor was implicitly defined as deleted.\r
+      /wd4625 # Copy constructor was implicitly defined as deleted.\r
+      /wd4626 # Assignment operator was implicitly defined as deleted.\r
+      /wd4647 # Behavior change in __is_pod.\r
+      /wd4668 # Macro was not defined, replacing with 0.\r
+      /wd4706 # Assignment within conditional expression.\r
+      /wd4710 # Function was not inlined.\r
+      /wd4711 # Function was selected for automated inlining.\r
+      /wd4714 # Function marked as __forceinline not inlined.\r
+      /wd4820 # Padding added after data member.\r
+      /wd5026 # Move constructor was implicitly defined as deleted.\r
+      /wd5027 # Move assignment operator was implicitly defined as deleted.\r
+      /wd5031 # #pragma warning(pop): likely mismatch, popping warning state pushed in different file. This is needed because of how boost does things.\r
+\r
+      # Warnings to treat as errors:\r
+      /we4099 # Mixed use of struct and class on same type names.\r
+      /we4129 # Unknown escape sequence. This is usually caused by incorrect escaping.\r
+      /we4566 # Character cannot be represented in current charset. This is remidied by prefixing string with "u8".\r
+\r
+    PRIVATE\r
+      # Warnings disabled for /analyze\r
+      $<$<BOOL:${MSVC_ENABLE_STATIC_ANALYSIS}>:\r
+        /wd6001 # Using uninitialized memory. This is disabled because it is wrong 99% of the time.\r
+        /wd6011 # Dereferencing potentially NULL pointer.\r
+        /wd6031 # Return value ignored.\r
+        /wd6235 # (<non-zero constant> || <expression>) is always a non-zero constant.\r
+        /wd6237 # (<zero> && <expression>) is always zero. <expression> is never evaluated and may have side effects.\r
+        /wd6239 # (<non-zero constant> && <expression>) always evaluates to the result of <expression>.\r
+        /wd6240 # (<expression> && <non-zero constant>) always evaluates to the result of <expression>.\r
+        /wd6246 # Local declaration hides declaration of same name in outer scope.\r
+        /wd6248 # Setting a SECURITY_DESCRIPTOR's DACL to NULL will result in an unprotected object. This is done by one of the boost headers.\r
+        /wd6255 # _alloca indicates failure by raising a stack overflow exception.\r
+        /wd6262 # Function uses more than x bytes of stack space.\r
+        /wd6271 # Extra parameter passed to format function. The analysis pass doesn't recognize %j or %z, even though the runtime does.\r
+        /wd6285 # (<non-zero constant> || <non-zero constant>) is always true.\r
+        /wd6297 # 32-bit value is shifted then cast to 64-bits. The places this occurs never use more than 32 bits.\r
+        /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.\r
+        /wd6326 # Potential comparison of a constant with another constant.\r
+        /wd6330 # Unsigned/signed mismatch when passed as a parameter.\r
+        /wd6340 # Mismatch on sign when passed as format string value.\r
+        /wd6387 # '<value>' could be '0': This does not adhere to the specification for a function.\r
+        /wd28182 # Dereferencing NULL pointer. '<value>' contains the same NULL value as '<expression>'.\r
+        /wd28251 # Inconsistent annotation for function. This is because we only annotate the declaration and not the definition.\r
+        /wd28278 # Function appears with no prototype in scope.\r
+      >\r
+  )\r
+\r
+  # And the extra defines:\r
+  target_compile_definitions(${THETARGET}\r
+    PUBLIC\r
+      _HAS_AUTO_PTR_ETC=1 # We're building in C++ 17 mode, but certain dependencies (Boost) still have dependencies on unary_function and binary_function, so we have to make sure not to remove them.\r
+      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.\r
+      _CRT_NONSTDC_NO_WARNINGS # Don't deprecate posix names of functions.\r
+      _CRT_SECURE_NO_WARNINGS # Don't deprecate the non _s versions of various standard library functions, because safety is for chumps.\r
+      _SCL_SECURE_NO_WARNINGS # Don't deprecate the non _s versions of various standard library functions, because safety is for chumps.\r
+      _WINSOCK_DEPRECATED_NO_WARNINGS # Don't deprecate pieces of winsock\r
+      WIN32_LEAN_AND_MEAN # Don't include most of Windows.h\r
+      \r
+      _STL_EXTRA_DISABLED_WARNINGS=4365\ 4774\ 4775\ 4987\r
+  )\r
+\r
+  # Ignore a warning about an object file not defining any symbols,\r
+  # these are known, and we don't care.\r
+  set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY STATIC_LIBRARY_FLAGS " /ignore:4221")\r
+\r
+  # The options to pass to the linker:\r
+  set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /INCREMENTAL") # Do incremental linking.\r
+  if (NOT $<TARGET_PROPERTY:${THETARGET},TYPE> STREQUAL "STATIC_LIBRARY")\r
+    set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /OPT:NOREF") # No unreferenced data elimination.\r
+    set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /OPT:NOICF") # No Identical COMDAT folding.\r
+\r
+    set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " /OPT:REF") # Remove unreferenced functions and data.\r
+    set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " /OPT:ICF") # Identical COMDAT folding.\r
+  endif()\r
+\r
+  if (MSVC_ENABLE_FAST_LINK)\r
+    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.\r
+  endif()\r
+\r
+  # Add /GL to the compiler, and /LTCG to the linker\r
+  # if link time code generation is enabled.\r
+  if (MSVC_ENABLE_LTCG)\r
+    set_property(TARGET ${THETARGET} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " /LTCG")\r
+  endif()\r
+endfunction()\r
diff --git a/CMake/FollyFunctions.cmake b/CMake/FollyFunctions.cmake
new file mode 100755 (executable)
index 0000000..61992c6
--- /dev/null
@@ -0,0 +1,281 @@
+function(auto_sources RETURN_VALUE PATTERN SOURCE_SUBDIRS)\r
+  if ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")\r
+    SET(PATH ".")\r
+    if (${ARGC} EQUAL 4)\r
+      list(GET ARGV 3 PATH)\r
+    endif ()\r
+  endif()\r
+\r
+  if ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")\r
+    unset(${RETURN_VALUE})\r
+    file(GLOB SUBDIR_FILES "${PATH}/${PATTERN}")\r
+    list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})\r
+\r
+    file(GLOB subdirs RELATIVE ${PATH} ${PATH}/*)\r
+\r
+    foreach(DIR ${subdirs})\r
+      if (IS_DIRECTORY ${PATH}/${DIR})\r
+        if (NOT "${DIR}" STREQUAL "CMakeFiles")\r
+          file(GLOB_RECURSE SUBDIR_FILES "${PATH}/${DIR}/${PATTERN}")\r
+          list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})\r
+        endif()\r
+      endif()\r
+    endforeach()\r
+  else()\r
+    file(GLOB ${RETURN_VALUE} "${PATTERN}")\r
+\r
+    foreach (PATH ${SOURCE_SUBDIRS})\r
+      file(GLOB SUBDIR_FILES "${PATH}/${PATTERN}")\r
+      list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})\r
+    endforeach()\r
+  endif ()\r
+\r
+  set(${RETURN_VALUE} ${${RETURN_VALUE}} PARENT_SCOPE)\r
+endfunction(auto_sources)\r
+\r
+# Remove all files matching a set of patterns, and,\r
+# optionally, not matching a second set of patterns,\r
+# from a set of lists.\r
+#\r
+# Example:\r
+# This will remove all files in the CPP_SOURCES list\r
+# matching "/test/" or "Test.cpp$", but not matching\r
+# "BobTest.cpp$".\r
+# REMOVE_MATCHES_FROM_LISTS(CPP_SOURCES MATCHES "/test/" "Test.cpp$" IGNORE_MATCHES "BobTest.cpp$")\r
+#\r
+# Parameters:\r
+#\r
+# [...]:\r
+# The names of the lists to remove matches from.\r
+#\r
+# [MATCHES ...]:\r
+# The matches to remove from the lists.\r
+#\r
+# [IGNORE_MATCHES ...]:\r
+# The matches not to remove, even if they match\r
+# the main set of matches to remove.\r
+function(REMOVE_MATCHES_FROM_LISTS)\r
+  set(LISTS_TO_SEARCH)\r
+  set(MATCHES_TO_REMOVE)\r
+  set(MATCHES_TO_IGNORE)\r
+  set(argumentState 0)\r
+  foreach (arg ${ARGN})\r
+    if ("x${arg}" STREQUAL "xMATCHES")\r
+      set(argumentState 1)\r
+    elseif ("x${arg}" STREQUAL "xIGNORE_MATCHES")\r
+      set(argumentState 2)\r
+    elseif (argumentState EQUAL 0)\r
+      list(APPEND LISTS_TO_SEARCH ${arg})\r
+    elseif (argumentState EQUAL 1)\r
+      list(APPEND MATCHES_TO_REMOVE ${arg})\r
+    elseif (argumentState EQUAL 2)\r
+      list(APPEND MATCHES_TO_IGNORE ${arg})\r
+    else()\r
+      message(FATAL_ERROR "Unknown argument state!")\r
+    endif()\r
+  endforeach()\r
+\r
+  foreach (theList ${LISTS_TO_SEARCH})\r
+    foreach (entry ${${theList}})\r
+      foreach (match ${MATCHES_TO_REMOVE})\r
+        if (${entry} MATCHES ${match})\r
+          set(SHOULD_IGNORE OFF)\r
+          foreach (ign ${MATCHES_TO_IGNORE})\r
+            if (${entry} MATCHES ${ign})\r
+              set(SHOULD_IGNORE ON)\r
+              break()\r
+            endif()\r
+          endforeach()\r
+\r
+          if (NOT SHOULD_IGNORE)\r
+            list(REMOVE_ITEM ${theList} ${entry})\r
+          endif()\r
+        endif()\r
+      endforeach()\r
+    endforeach()\r
+    set(${theList} ${${theList}} PARENT_SCOPE)\r
+  endforeach()\r
+endfunction()\r
+\r
+# Automatically create source_group directives for the sources passed in.\r
+function(auto_source_group rootName rootDir)\r
+  file(TO_CMAKE_PATH "${rootDir}" rootDir)\r
+  string(LENGTH "${rootDir}" rootDirLength)\r
+  set(sourceGroups)\r
+  foreach (fil ${ARGN})\r
+    file(TO_CMAKE_PATH "${fil}" filePath)\r
+    string(FIND "${filePath}" "/" rIdx REVERSE)\r
+    if (rIdx EQUAL -1)\r
+      message(FATAL_ERROR "Unable to locate the final forward slash in '${filePath}'!")\r
+    endif()\r
+    string(SUBSTRING "${filePath}" 0 ${rIdx} filePath)\r
+\r
+    string(LENGTH "${filePath}" filePathLength)\r
+    string(FIND "${filePath}" "${rootDir}" rIdx)\r
+    if (rIdx EQUAL 0)\r
+      math(EXPR filePathLength "${filePathLength} - ${rootDirLength}")\r
+      string(SUBSTRING "${filePath}" ${rootDirLength} ${filePathLength} fileGroup)\r
+\r
+      string(REPLACE "/" "\\" fileGroup "${fileGroup}")\r
+      set(fileGroup "\\${rootName}${fileGroup}")\r
+\r
+      list(FIND sourceGroups "${fileGroup}" rIdx)\r
+      if (rIdx EQUAL -1)\r
+        list(APPEND sourceGroups "${fileGroup}")\r
+        source_group("${fileGroup}" REGULAR_EXPRESSION "${filePath}/[^/.]+.(cpp|h)$")\r
+      endif()\r
+    endif()\r
+  endforeach()\r
+endfunction()\r
+\r
+# CMake is a pain and doesn't have an easy way to install only the files\r
+# we actually included in our build :(\r
+function(auto_install_files rootName rootDir)\r
+  file(TO_CMAKE_PATH "${rootDir}" rootDir)\r
+  string(LENGTH "${rootDir}" rootDirLength)\r
+  set(sourceGroups)\r
+  foreach (fil ${ARGN})\r
+    file(TO_CMAKE_PATH "${fil}" filePath)\r
+    string(FIND "${filePath}" "/" rIdx REVERSE)\r
+    if (rIdx EQUAL -1)\r
+      message(FATAL_ERROR "Unable to locate the final forward slash in '${filePath}'!")\r
+    endif()\r
+    string(SUBSTRING "${filePath}" 0 ${rIdx} filePath)\r
+\r
+    string(LENGTH "${filePath}" filePathLength)\r
+    string(FIND "${filePath}" "${rootDir}" rIdx)\r
+    if (rIdx EQUAL 0)\r
+      math(EXPR filePathLength "${filePathLength} - ${rootDirLength}")\r
+      string(SUBSTRING "${filePath}" ${rootDirLength} ${filePathLength} fileGroup)\r
+      install(FILES ${fil} DESTINATION include/${rootName}${fileGroup})\r
+    endif()\r
+  endforeach()\r
+endfunction()\r
+\r
+function(folly_define_tests)\r
+  set(directory_count 0)\r
+  set(test_count 0)\r
+  set(currentArg 0)\r
+  while (currentArg LESS ${ARGC})\r
+    if ("x${ARGV${currentArg}}" STREQUAL "xDIRECTORY")\r
+      math(EXPR currentArg "${currentArg} + 1")\r
+      if (NOT currentArg LESS ${ARGC})\r
+        message(FATAL_ERROR "Expected base directory!")\r
+      endif()\r
+\r
+      set(cur_dir ${directory_count})\r
+      math(EXPR directory_count "${directory_count} + 1")\r
+      set(directory_${cur_dir}_name "${ARGV${currentArg}}")\r
+      # We need a single list of sources to get source_group to work nicely.\r
+      set(directory_${cur_dir}_source_list)\r
+\r
+      math(EXPR currentArg "${currentArg} + 1")\r
+      while (currentArg LESS ${ARGC})\r
+        if ("x${ARGV${currentArg}}" STREQUAL "xDIRECTORY")\r
+          break()\r
+        elseif ("x${ARGV${currentArg}}" STREQUAL "xTEST")\r
+          math(EXPR currentArg "${currentArg} + 1")\r
+          if (NOT currentArg LESS ${ARGC})\r
+            message(FATAL_ERROR "Expected test name!")\r
+          endif()\r
+\r
+          set(cur_test ${test_count})\r
+          math(EXPR test_count "${test_count} + 1")\r
+          set(test_${cur_test}_name "${ARGV${currentArg}}")\r
+          math(EXPR currentArg "${currentArg} + 1")\r
+          set(test_${cur_test}_directory ${cur_dir})\r
+          set(test_${cur_test}_content_dir)\r
+          set(test_${cur_test}_headers)\r
+          set(test_${cur_test}_sources)\r
+          set(test_${cur_test}_tag "NONE")\r
+\r
+          set(argumentState 0)\r
+          while (currentArg LESS ${ARGC})\r
+            if ("x${ARGV${currentArg}}" STREQUAL "xHEADERS")\r
+              set(argumentState 1)\r
+            elseif ("x${ARGV${currentArg}}" STREQUAL "xSOURCES")\r
+              set(argumentState 2)\r
+            elseif ("x${ARGV${currentArg}}" STREQUAL "xCONTENT_DIR")\r
+              math(EXPR currentArg "${currentArg} + 1")\r
+              if (NOT currentArg LESS ${ARGC})\r
+                message(FATAL_ERROR "Expected content directory name!")\r
+              endif()\r
+              set(test_${cur_test}_content_dir "${ARGV${currentArg}}")\r
+            elseif ("x${ARGV${currentArg}}" STREQUAL "xTEST" OR\r
+                    "x${ARGV${currentArg}}" STREQUAL "xDIRECTORY")\r
+              break()\r
+            elseif (argumentState EQUAL 0)\r
+              if ("x${ARGV${currentArg}}" STREQUAL "xHANGING")\r
+                set(test_${cur_test}_tag "HANGING")\r
+              elseif ("x${ARGV${currentArg}}" STREQUAL "xSLOW")\r
+                set(test_${cur_test}_tag "SLOW")\r
+              else()\r
+                message(FATAL_ERROR "Unknown test tag '${ARGV${currentArg}}'!")\r
+              endif()\r
+            elseif (argumentState EQUAL 1)\r
+              list(APPEND test_${cur_test}_headers\r
+                "${FOLLY_DIR}/${directory_${cur_dir}_name}${ARGV${currentArg}}"\r
+              )\r
+            elseif (argumentState EQUAL 2)\r
+              list(APPEND test_${cur_test}_sources\r
+                "${FOLLY_DIR}/${directory_${cur_dir}_name}${ARGV${currentArg}}"\r
+              )\r
+            else()\r
+              message(FATAL_ERROR "Unknown argument state!")\r
+            endif()\r
+            math(EXPR currentArg "${currentArg} + 1")\r
+          endwhile()\r
+\r
+          list(APPEND directory_${cur_dir}_source_list\r
+            ${test_${cur_test}_sources} ${test_${cur_test}_headers})\r
+        else()\r
+          message(FATAL_ERROR "Unknown argument inside directory '${ARGV${currentArg}}'!")\r
+        endif()\r
+      endwhile()\r
+    else()\r
+      message(FATAL_ERROR "Unknown argument '${ARGV${currentArg}}'!")\r
+    endif()\r
+  endwhile()\r
+\r
+  set(cur_dir 0)\r
+  while (cur_dir LESS directory_count)\r
+    source_group("" FILES ${directory_${cur_dir}_source_list})\r
+    math(EXPR cur_dir "${cur_dir} + 1")\r
+  endwhile()\r
+\r
+  set(cur_test 0)\r
+  while (cur_test LESS test_count)\r
+    if ("x${test_${cur_test}_tag}" STREQUAL "xNONE" OR\r
+        ("x${test_${cur_test}_tag}" STREQUAL "xSLOW" AND BUILD_SLOW_TESTS) OR\r
+        ("x${test_${cur_test}_tag}" STREQUAL "xHANGING" AND BUILD_HANGING_TESTS)\r
+    )\r
+      set(cur_test_name ${test_${cur_test}_name})\r
+      set(cur_dir_name ${directory_${test_${cur_test}_directory}_name})\r
+      add_executable(${cur_test_name}\r
+        ${test_${cur_test}_headers}\r
+        ${test_${cur_test}_sources}\r
+      )\r
+      if (NOT "x${test_${cur_test}_content_dir}" STREQUAL "x")\r
+        # Copy the content directory to the output directory tree so that\r
+        # tests can be run easily from Visual Studio without having to change\r
+        # the working directory for each test individually.\r
+        file(\r
+          COPY "${FOLLY_DIR}/${cur_dir_name}${test_${cur_test}_content_dir}"\r
+          DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/folly/${cur_dir_name}${test_${cur_test}_content_dir}"\r
+        )\r
+        add_custom_command(TARGET ${cur_test_name} POST_BUILD COMMAND\r
+          ${CMAKE_COMMAND} ARGS -E copy_directory\r
+            "${FOLLY_DIR}/${cur_dir_name}${test_${cur_test}_content_dir}"\r
+            "$<TARGET_FILE_DIR:${cur_test_name}>/folly/${cur_dir_name}${test_${cur_test}_content_dir}"\r
+          COMMENT "Copying test content for ${cur_test_name}" VERBATIM\r
+        )\r
+      endif()\r
+      # Strip the tailing test directory name for the folder name.\r
+      string(REPLACE "test/" "" test_dir_name "${cur_dir_name}")\r
+      set_property(TARGET ${cur_test_name} PROPERTY FOLDER "Tests/${test_dir_name}")\r
+      target_link_libraries(${cur_test_name} PRIVATE folly_test_support)\r
+      apply_folly_compile_options_to_target(${cur_test_name})\r
+    endif()\r
+    math(EXPR cur_test "${cur_test} + 1")\r
+  endwhile()\r
+endfunction()\r
diff --git a/CMake/folly-config.h.cmake b/CMake/folly-config.h.cmake
new file mode 100755 (executable)
index 0000000..e3c1396
--- /dev/null
@@ -0,0 +1,42 @@
+/*\r
+ * Copyright 2016 Facebook, Inc.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *   http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#pragma once\r
+\r
+#define FOLLY_HAVE_LIBGFLAGS 1\r
+#define FOLLY_UNUSUAL_GFLAGS_NAMESPACE 1\r
+#define FOLLY_GFLAGS_NAMESPACE google\r
+\r
+#define FOLLY_HAVE_IFUNC 0\r
+#define FOLLY_HAVE_MALLOC_H 1\r
+#define FOLLY_HAVE_MEMRCHR 0\r
+#define FOLLY_HAVE_PREADV 0\r
+#define FOLLY_HAVE_PTHREAD_SPINLOCK_T 1\r
+#define FOLLY_HAVE_PWRITEV 0\r
+#define FOLLY_HAVE_SCHED_H 1\r
+#define FOLLY_HAVE_STD__IS_TRIVIALLY_COPYABLE 1\r
+#define FOLLY_HAVE_STD_THIS_THREAD_SLEEP_FOR 1\r
+#define FOLLY_HAVE_UNALIGNED_ACCESS 1\r
+#define FOLLY_HAVE_VLA 0\r
+#define FOLLY_HAVE_WEAK_SYMBOLS 0\r
+\r
+#define FOLLY_VERSION "${PACKAGE_VERSION}"\r
+\r
+//#define FOLLY_HAVE_LIBLZ4 1\r
+//#define FOLLY_HAVE_LIBLZMA 1\r
+//#define FOLLY_HAVE_LIBSNAPPY 1\r
+//#define FOLLY_HAVE_LIBZ 1\r
+//#define FOLLY_HAVE_LIBZSTD 1\r
diff --git a/CMake/folly-deps.cmake b/CMake/folly-deps.cmake
new file mode 100755 (executable)
index 0000000..8f972c5
--- /dev/null
@@ -0,0 +1,18 @@
+find_package(Boost 1.55.0 MODULE\r
+  COMPONENTS\r
+    context\r
+    chrono\r
+    date_time\r
+    filesystem\r
+    program_options\r
+    regex\r
+    system\r
+    thread\r
+  REQUIRED\r
+)\r
+find_package(DoubleConversion MODULE REQUIRED)\r
+find_package(GFlags MODULE REQUIRED)\r
+find_package(GLog MODULE REQUIRED)\r
+find_package(LibEvent MODULE REQUIRED)\r
+find_package(OpenSSL MODULE REQUIRED)\r
+find_package(PThread MODULE REQUIRED)\r
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..030d1c7
--- /dev/null
@@ -0,0 +1,525 @@
+cmake_minimum_required(VERSION 3.4.0 FATAL_ERROR)
+
+# Unfortunately, CMake doesn't easily provide us a way to merge static
+# libraries, which is what we want to do to generate the main folly library, so
+# we do a bit of a workaround here to inject a property into the generated
+# project files that will only get enabled for the folly target. Ugly, but
+# the alternatives are far, far worse.
+if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio 15( 2017)? Win64")
+  set(CMAKE_GENERATOR_TOOLSET "v141</PlatformToolset></PropertyGroup><ItemDefinitionGroup Condition=\"'$(ProjectName)'=='folly'\"><ProjectReference><LinkLibraryDependencies>true</LinkLibraryDependencies></ProjectReference></ItemDefinitionGroup><PropertyGroup><PlatformToolset>v141")
+elseif ("${CMAKE_GENERATOR}" STREQUAL "Visual Studio 14 2015 Win64")
+  set(CMAKE_GENERATOR_TOOLSET "v140</PlatformToolset></PropertyGroup><ItemDefinitionGroup Condition=\"'$(ProjectName)'=='folly'\"><ProjectReference><LinkLibraryDependencies>true</LinkLibraryDependencies></ProjectReference></ItemDefinitionGroup><PropertyGroup><PlatformToolset>v140")
+else()
+  message(FATAL_ERROR "This build script only supports building Folly on 64-bit Windows with Visual Studio 2015 or Visual Studio 2017.")
+endif()
+
+# includes
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+# package information
+set(PACKAGE_NAME      "folly")
+set(PACKAGE_VERSION   "0.58.0-dev")
+set(PACKAGE_STRING    "${PACKAGE_NAME} ${PACKAGE_VERSION}")
+set(PACKAGE_TARNAME   "${PACKAGE_NAME}-${PACKAGE_VERSION}")
+set(PACKAGE_BUGREPORT "https://github.com/facebook/folly/issues")
+
+# 150+ tests in the root folder anyone? No? I didn't think so.
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+project(${PACKAGE_NAME} CXX)
+
+# Check architecture OS
+if (NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
+  message(FATAL_ERROR "Folly requires a 64bit OS")
+endif()
+if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
+  message(FATAL_ERROR "You should only be using CMake to build Folly if you are on Windows!")
+endif()
+
+set(FOLLY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/folly")
+
+# Generate a few tables and create the main config file.
+find_package(PythonInterp REQUIRED)
+add_custom_command(
+  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/folly/build/EscapeTables.cpp
+  COMMAND ${PYTHON_EXECUTABLE} "${FOLLY_DIR}/build/generate_escape_tables.py"
+  DEPENDS ${FOLLY_DIR}/build/generate_escape_tables.py
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/folly/build/
+  COMMENT "Generating the escape tables..." VERBATIM
+)
+add_custom_command(
+  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/folly/build/FormatTables.cpp
+  COMMAND ${PYTHON_EXECUTABLE} "${FOLLY_DIR}/build/generate_format_tables.py"
+  DEPENDS ${FOLLY_DIR}/build/generate_format_tables.py
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/folly/build/
+  COMMENT "Generating the format tables..." VERBATIM
+)
+add_custom_command(
+  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/folly/build/GroupVarintTables.cpp"
+  COMMAND ${PYTHON_EXECUTABLE} "${FOLLY_DIR}/build/generate_varint_tables.py"
+  DEPENDS ${FOLLY_DIR}/build/generate_varint_tables.py
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/folly/build/
+  COMMENT "Generating the group varint tables..." VERBATIM
+)
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/CMake/folly-config.h.cmake
+  ${CMAKE_CURRENT_BINARY_DIR}/folly/folly-config.h
+)
+
+include(FollyCompiler)
+include(FollyFunctions)
+
+# Main folly library files
+auto_sources(files "*.cpp" "RECURSE" "${FOLLY_DIR}")
+auto_sources(hfiles "*.h" "RECURSE" "${FOLLY_DIR}")
+
+# No need for tests or benchmarks, and we can't build most experimental stuff.
+REMOVE_MATCHES_FROM_LISTS(files hfiles
+  MATCHES
+    "/build/"
+    "/experimental/exception_tracer/"
+    "/experimental/hazptr/example/"
+    "/experimental/symbolizer/"
+    "/futures/exercises/"
+    "/test/"
+    "Benchmark.cpp$"
+    "Test.cpp$"
+  IGNORE_MATCHES
+    "/Benchmark.cpp$"
+)
+list(REMOVE_ITEM files
+  ${FOLLY_DIR}/Subprocess.cpp
+  ${FOLLY_DIR}/SingletonStackTrace.cpp
+  ${FOLLY_DIR}/experimental/JSONSchemaTester.cpp
+  ${FOLLY_DIR}/experimental/RCUUtils.cpp
+  ${FOLLY_DIR}/experimental/io/AsyncIO.cpp
+  ${FOLLY_DIR}/experimental/io/HugePageUtil.cpp
+  ${FOLLY_DIR}/futures/test/Benchmark.cpp
+)
+list(REMOVE_ITEM hfiles
+  ${FOLLY_DIR}/Fingerprint.h
+  ${FOLLY_DIR}/detail/SlowFingerprint.h
+  ${FOLLY_DIR}/detail/FingerprintPolynomial.h
+  ${FOLLY_DIR}/experimental/RCURefCount.h
+  ${FOLLY_DIR}/experimental/RCUUtils.h
+  ${FOLLY_DIR}/experimental/io/AsyncIO.h
+)
+
+add_library(folly_base STATIC
+  ${files} ${hfiles}
+  ${CMAKE_CURRENT_BINARY_DIR}/folly/folly-config.h
+  ${CMAKE_CURRENT_BINARY_DIR}/folly/build/EscapeTables.cpp
+  ${CMAKE_CURRENT_BINARY_DIR}/folly/build/FormatTables.cpp
+  ${CMAKE_CURRENT_BINARY_DIR}/folly/build/GroupVarintTables.cpp
+)
+auto_source_group(folly ${FOLLY_DIR} ${files} ${hfiles})
+apply_folly_compile_options_to_target(folly_base)
+target_include_directories(folly_base PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
+# Add the generated files to the correct source group.
+source_group("folly" FILES ${CMAKE_CURRENT_BINARY_DIR}/folly/folly-config.h)
+source_group("folly\\build" FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/folly/build/EscapeTables.cpp
+  ${CMAKE_CURRENT_BINARY_DIR}/folly/build/FingerprintTables.cpp
+  ${CMAKE_CURRENT_BINARY_DIR}/folly/build/FormatTables.cpp
+  ${CMAKE_CURRENT_BINARY_DIR}/folly/build/GroupVarintTables.cpp
+)
+
+include(folly-deps) # Find the required packages
+target_include_directories(folly_base
+  PUBLIC
+    ${DOUBLE_CONVERSION_INCLUDE_DIR}
+    ${LIBGFLAGS_INCLUDE_DIR}
+    ${LIBGLOG_INCLUDE_DIR}
+    ${LIBEVENT_INCLUDE_DIR}
+    ${LIBPTHREAD_INCLUDE_DIRS}
+)
+target_link_libraries(folly_base
+  PUBLIC
+    Boost::chrono
+    Boost::context
+    Boost::date_time
+    Boost::filesystem
+    Boost::program_options
+    Boost::regex
+    Boost::system
+    ${DOUBLE_CONVERSION_LIBRARY}
+    ${LIBEVENT_LIB}
+    ${LIBGFLAGS_LIBRARY}
+    ${LIBGLOG_LIBRARY}
+    ${LIBPTHREAD_LIBRARIES}
+    OpenSSL::SSL
+    OpenSSL::Crypto
+    Ws2_32.lib
+)
+
+# Now to generate the fingerprint tables
+add_executable(GenerateFingerprintTables
+  ${FOLLY_DIR}/build/GenerateFingerprintTables.cpp
+)
+apply_folly_compile_options_to_target(GenerateFingerprintTables)
+set_property(TARGET GenerateFingerprintTables PROPERTY FOLDER "Build")
+target_link_libraries(GenerateFingerprintTables PRIVATE folly_base)
+source_group("" FILES ${FOLLY_DIR}/build/GenerateFingerprintTables.cpp)
+
+# Compile the fingerprint tables.
+add_custom_command(
+  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/folly/build/FingerprintTables.cpp
+  COMMAND GenerateFingerprintTables
+  DEPENDS GenerateFingerprintTables
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/folly/build/
+  COMMENT "Generating the fingerprint tables..."
+)
+add_library(folly_fingerprint STATIC
+  ${CMAKE_CURRENT_BINARY_DIR}/folly/build/FingerprintTables.cpp
+  ${FOLLY_DIR}/Fingerprint.h
+  ${FOLLY_DIR}/detail/SlowFingerprint.h
+  ${FOLLY_DIR}/detail/FingerprintPolynomial.h
+)
+apply_folly_compile_options_to_target(folly_fingerprint)
+target_link_libraries(folly_fingerprint PRIVATE folly_base)
+
+# We want to generate a single library and target for folly, but we needed a
+# two-stage compile for the fingerprint tables, so we create a phony source
+# file that we modify whenever the base libraries change, causing folly to be
+# re-linked, making things happy.
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/folly_dep.cpp
+  COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/folly_dep.cpp
+  DEPENDS folly_base folly_fingerprint
+)
+add_library(folly ${CMAKE_CURRENT_BINARY_DIR}/folly_dep.cpp)
+apply_folly_compile_options_to_target(folly)
+source_group("" FILES ${CMAKE_CURRENT_BINARY_DIR}/folly_dep.cpp)
+
+# Rather than list the dependencies in two places, we apply them directly on
+# the folly_base target and then copy them over to the folly target.
+get_target_property(FOLLY_LINK_LIBRARIES folly_base INTERFACE_LINK_LIBRARIES)
+target_link_libraries(folly PUBLIC ${FOLLY_LINK_LIBRARIES})
+target_include_directories(folly PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
+
+install(TARGETS folly
+  EXPORT folly
+  RUNTIME DESTINATION bin
+  LIBRARY DESTINATION lib
+  ARCHIVE DESTINATION lib)
+auto_install_files(folly ${FOLLY_DIR}
+  ${hfiles}
+  ${FOLLY_DIR}/Fingerprint.h
+  ${FOLLY_DIR}/detail/SlowFingerprint.h
+  ${FOLLY_DIR}/detail/FingerprintPolynomial.h
+)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/folly/folly-config.h DESTINATION include/folly)
+install(
+  EXPORT folly
+  DESTINATION share/folly
+  NAMESPACE Folly::
+  FILE folly-targets.cmake
+)
+
+# We need a wrapper config file to do the find_package calls to ensure
+# that all our dependencies are available to link against.
+file(
+  COPY ${CMAKE_CURRENT_SOURCE_DIR}/CMake/folly-deps.cmake
+  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/
+)
+file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/folly-deps.cmake "\ninclude(folly-targets.cmake)\n")
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/folly-deps.cmake DESTINATION share/folly RENAME folly-config.cmake)
+
+option(BUILD_TESTS "If enabled, compile the tests." OFF)
+option(BUILD_HANGING_TESTS "If enabled, compile tests that are known to hang." OFF)
+option(BUILD_SLOW_TESTS "If enabled, compile tests that take a while to run in debug mode." OFF)
+if (BUILD_TESTS)
+  find_package(GMock MODULE REQUIRED)
+
+  add_library(folly_test_support
+    ${FOLLY_DIR}/test/DeterministicSchedule.cpp
+    ${FOLLY_DIR}/test/DeterministicSchedule.h
+    ${FOLLY_DIR}/test/SingletonTestStructs.cpp
+    ${FOLLY_DIR}/test/SocketAddressTestHelper.cpp
+    ${FOLLY_DIR}/test/SocketAddressTestHelper.h
+    ${FOLLY_DIR}/io/async/test/BlockingSocket.h
+    ${FOLLY_DIR}/io/async/test/MockAsyncServerSocket.h
+    ${FOLLY_DIR}/io/async/test/MockAsyncSocket.h
+    ${FOLLY_DIR}/io/async/test/MockAsyncSSLSocket.h
+    ${FOLLY_DIR}/io/async/test/MockAsyncTransport.h
+    ${FOLLY_DIR}/io/async/test/MockAsyncUDPSocket.h
+    ${FOLLY_DIR}/io/async/test/MockTimeoutManager.h
+    ${FOLLY_DIR}/io/async/test/ScopedBoundPort.cpp
+    ${FOLLY_DIR}/io/async/test/ScopedBoundPort.h
+    ${FOLLY_DIR}/io/async/test/SocketPair.cpp
+    ${FOLLY_DIR}/io/async/test/SocketPair.h
+    ${FOLLY_DIR}/io/async/test/TestSSLServer.cpp
+    ${FOLLY_DIR}/io/async/test/TestSSLServer.h
+    ${FOLLY_DIR}/io/async/test/TimeUtil.cpp
+    ${FOLLY_DIR}/io/async/test/TimeUtil.h
+    ${FOLLY_DIR}/io/async/test/UndelayedDestruction.h
+    ${FOLLY_DIR}/io/async/test/Util.h
+  )
+  target_include_directories(folly_test_support
+    PUBLIC
+      ${LIBGMOCK_INCLUDE_DIR}
+  )
+  target_link_libraries(folly_test_support
+    PUBLIC
+      Boost::thread
+      folly
+      ${LIBGMOCK_LIBRARY}
+  )
+  apply_folly_compile_options_to_target(folly_test_support)
+
+  folly_define_tests(
+    DIRECTORY experimental/test/
+      TEST autotimer_test SOURCES AutoTimerTest.cpp
+      TEST bits_test_2 SOURCES BitsTest.cpp
+      TEST bitvector_test SOURCES BitVectorCodingTest.cpp
+      TEST dynamic_parser_test SOURCES DynamicParserTest.cpp
+      TEST eliasfano_test SOURCES EliasFanoCodingTest.cpp
+      TEST event_count_test SOURCES EventCountTest.cpp
+      TEST function_scheduler_test_2 SOURCES FunctionSchedulerTest.cpp
+      TEST future_dag_test SOURCES FutureDAGTest.cpp
+      TEST json_schema_test SOURCES JSONSchemaTest.cpp
+      TEST lock_free_ring_buffer_test SOURCES LockFreeRingBufferTest.cpp
+      #TEST nested_command_line_app_test SOURCES NestedCommandLineAppTest.cpp
+      #TEST program_options_test SOURCES ProgramOptionsTest.cpp
+      # Depends on liburcu
+      #TEST read_mostly_shared_ptr_test SOURCES ReadMostlySharedPtrTest.cpp
+      #TEST ref_count_test SOURCES RefCountTest.cpp
+      TEST stringkeyed_test SOURCES StringKeyedTest.cpp
+      TEST test_util_test SOURCES TestUtilTest.cpp
+      TEST tuple_ops_test SOURCES TupleOpsTest.cpp
+
+    DIRECTORY experimental/io/test/
+      # Depends on libaio
+      #TEST async_io_test SOURCES AsyncIOTest.cpp
+      TEST fs_util_test SOURCES FsUtilTest.cpp
+
+    DIRECTORY fibers/test/
+      TEST fibers_test SOURCES FibersTest.cpp
+
+    DIRECTORY futures/test/
+      TEST futures-test
+        HEADERS
+          ThenCompileTest.h
+        SOURCES
+          BarrierTest.cpp
+          CollectTest.cpp
+          ContextTest.cpp
+          CoreTest.cpp
+          EnsureTest.cpp
+          ExecutorTest.cpp
+          FSMTest.cpp
+          FilterTest.cpp
+          # MSVC SFINAE bug
+          #FutureTest.cpp
+          HeaderCompileTest.cpp
+          InterruptTest.cpp
+          MapTest.cpp
+          NonCopyableLambdaTest.cpp
+          PollTest.cpp
+          PromiseTest.cpp
+          ReduceTest.cpp
+          # MSVC SFINAE bug
+          #RetryingTest.cpp
+          SelfDestructTest.cpp
+          SharedPromiseTest.cpp
+          ThenCompileTest.cpp
+          ThenTest.cpp
+          TimekeeperTest.cpp
+          TimesTest.cpp
+          UnwrapTest.cpp
+          ViaTest.cpp
+          WaitTest.cpp
+          WhenTest.cpp
+          WhileDoTest.cpp
+          WillEqualTest.cpp
+          WindowTest.cpp
+
+    DIRECTORY gen/test/
+      # MSVC bug can't resolve initializer_list constructor properly
+      #TEST base_test SOURCES BaseTest.cpp
+      TEST combine_test SOURCES CombineTest.cpp
+      TEST parallel_map_test SOURCES ParallelMapTest.cpp
+      TEST parallel_test SOURCES ParallelTest.cpp
+
+    DIRECTORY io/test/
+      TEST compression_test SOURCES CompressionTest.cpp
+      TEST iobuf_test SOURCES IOBufTest.cpp
+      TEST iobuf_cursor_test SOURCES IOBufCursorTest.cpp
+      TEST iobuf_queue_test SOURCES IOBufQueueTest.cpp
+      TEST record_io_test SOURCES RecordIOTest.cpp
+      TEST ShutdownSocketSetTest HANGING
+        SOURCES ShutdownSocketSetTest.cpp
+
+    DIRECTORY io/async/test/
+      TEST async_test
+        CONTENT_DIR certs/
+        HEADERS
+          AsyncSocketTest.h
+          AsyncSSLSocketTest.h
+        SOURCES
+          AsyncPipeTest.cpp
+          AsyncSocketExceptionTest.cpp
+          AsyncSocketTest.cpp
+          AsyncSocketTest2.cpp
+          AsyncSSLSocketTest.cpp
+          AsyncSSLSocketTest2.cpp
+          AsyncSSLSocketWriteTest.cpp
+          AsyncTransportTest.cpp
+          # This is disabled because it depends on things that don't exist
+          # on Windows.
+          #EventHandlerTest.cpp
+      TEST async_timeout_test SOURCES AsyncTimeoutTest.cpp
+      TEST AsyncUDPSocketTest SOURCES AsyncUDPSocketTest.cpp
+      TEST DelayedDestructionTest SOURCES DelayedDestructionTest.cpp
+      TEST DelayedDestructionBaseTest SOURCES DelayedDestructionBaseTest.cpp
+      TEST EventBaseTest SOURCES EventBaseTest.cpp
+      TEST EventBaseLocalTest SOURCES EventBaseLocalTest.cpp
+      TEST HHWheelTimerTest SOURCES HHWheelTimerTest.cpp
+      TEST HHWheelTimerSlowTests SLOW
+        SOURCES HHWheelTimerSlowTests.cpp
+      TEST NotificationQueueTest SOURCES NotificationQueueTest.cpp
+      TEST RequestContextTest SOURCES RequestContextTest.cpp
+      TEST ScopedEventBaseThreadTest SOURCES ScopedEventBaseThreadTest.cpp
+      TEST ssl_session_test SOURCES SSLSessionTest.cpp
+      TEST writechain_test SOURCES WriteChainAsyncTransportWrapperTest.cpp
+
+    DIRECTORY io/async/ssl/test/
+      TEST ssl_errors_test SOURCES SSLErrorsTest.cpp
+
+    DIRECTORY portability/test/
+      TEST constexpr_test SOURCES ConstexprTest.cpp
+      TEST libgen-test SOURCES LibgenTest.cpp
+      TEST time-test SOURCES TimeTest.cpp
+
+    DIRECTORY ssl/test/
+      TEST openssl_hash_test SOURCES OpenSSLHashTest.cpp
+
+    DIRECTORY test/
+      TEST ahm_int_stress_test SOURCES AHMIntStressTest.cpp
+      TEST apply_tuple_test SOURCES ApplyTupleTest.cpp
+      TEST arena_test SOURCES ArenaTest.cpp
+      TEST arena_smartptr_test SOURCES ArenaSmartPtrTest.cpp
+      TEST array_test SOURCES ArrayTest.cpp
+      TEST ascii_check_test SOURCES AsciiCaseInsensitiveTest.cpp
+      TEST atomic_bit_set_test SOURCES AtomicBitSetTest.cpp
+      TEST atomic_hash_array_test SOURCES AtomicHashArrayTest.cpp
+      TEST atomic_hash_map_test HANGING
+        SOURCES AtomicHashMapTest.cpp
+      TEST atomic_linked_list_test SOURCES AtomicLinkedListTest.cpp
+      TEST atomic_struct_test SOURCES AtomicStructTest.cpp
+      TEST atomic_unordered_map_test SOURCES AtomicUnorderedMapTest.cpp
+      TEST baton_test SOURCES BatonTest.cpp
+      TEST bit_iterator_test SOURCES BitIteratorTest.cpp
+      TEST bits_test SOURCES BitsTest.cpp
+      TEST cache_locality_test SOURCES CacheLocalityTest.cpp
+      TEST cacheline_padded_test SOURCES CachelinePaddedTest.cpp
+      TEST call_once_test SOURCES CallOnceTest.cpp
+      TEST checksum_test SOURCES ChecksumTest.cpp
+      TEST clock_gettime_wrappers_test SOURCES ClockGettimeWrappersTest.cpp
+      TEST concurrent_skip_list_test SOURCES ConcurrentSkipListTest.cpp
+      TEST container_traits_test SOURCES ContainerTraitsTest.cpp
+      TEST conv_test SOURCES ConvTest.cpp
+      TEST cpu_id_test SOURCES CpuIdTest.cpp
+      TEST demangle_test SOURCES DemangleTest.cpp
+      TEST deterministic_schedule_test SOURCES DeterministicScheduleTest.cpp
+      TEST discriminated_ptr_test SOURCES DiscriminatedPtrTest.cpp
+      TEST dynamic_test SOURCES DynamicTest.cpp
+      TEST dynamic_converter_test SOURCES DynamicConverterTest.cpp
+      TEST dynamic_other_test SOURCES DynamicOtherTest.cpp
+      TEST endian_test SOURCES EndianTest.cpp
+      TEST enumerate_test SOURCES EnumerateTest.cpp
+      TEST evicting_cache_map_test SOURCES EvictingCacheMapTest.cpp
+      TEST exception_test SOURCES ExceptionTest.cpp
+      TEST exception_wrapper_test SOURCES ExceptionWrapperTest.cpp
+      TEST expected_test SOURCES ExpectedTest.cpp
+      TEST fbvector_test SOURCES FBVectorTest.cpp
+      TEST file_test SOURCES FileTest.cpp
+      #TEST file_lock_test SOURCES FileLockTest.cpp
+      TEST file_util_test HANGING
+        SOURCES FileUtilTest.cpp
+      TEST fingerprint_test SOURCES FingerprintTest.cpp
+      TEST foreach_test SOURCES ForeachTest.cpp
+      TEST format_other_test SOURCES FormatOtherTest.cpp
+      TEST format_test SOURCES FormatTest.cpp
+      TEST function_scheduler_test SOURCES FunctionSchedulerTest.cpp
+      TEST function_test SOURCES FunctionTest.cpp
+      TEST function_ref_test SOURCES FunctionRefTest.cpp
+      TEST futex_test SOURCES FutexTest.cpp
+      TEST group_varint_test SOURCES GroupVarintTest.cpp
+      TEST group_varint_test_ssse3 SOURCES GroupVarintTest.cpp
+      TEST has_member_fn_traits_test SOURCES HasMemberFnTraitsTest.cpp
+      TEST hash_test SOURCES HashTest.cpp
+      TEST histogram_test SOURCES HistogramTest.cpp
+      TEST indestructible_test SOURCES IndestructibleTest.cpp
+      TEST indexed_mem_pool_test SOURCES IndexedMemPoolTest.cpp
+      # MSVC Preprocessor stringizing raw string literals bug
+      #TEST json_test SOURCES JsonTest.cpp
+      TEST json_other_test
+        CONTENT_DIR json_test_data/
+        SOURCES
+          JsonOtherTest.cpp
+      TEST lazy_test SOURCES LazyTest.cpp
+      TEST lifosem_test SOURCES LifoSemTests.cpp
+      TEST lock_traits_test SOURCES LockTraitsTest.cpp
+      TEST locks_test SOURCES SmallLocksTest.cpp SpinLockTest.cpp
+      TEST logging_test SOURCES LoggingTest.cpp
+      TEST mallctl_helper_test SOURCES MallctlHelperTest.cpp
+      TEST math_test SOURCES MathTest.cpp
+      TEST map_util_test SOURCES MapUtilTest.cpp
+      TEST memcpy_test SOURCES MemcpyTest.cpp
+      TEST memory_idler_test SOURCES MemoryIdlerTest.cpp
+      TEST memory_mapping_test SOURCES MemoryMappingTest.cpp
+      TEST memory_test SOURCES MemoryTest.cpp
+      TEST merge SOURCES MergeTest.cpp
+      TEST move_wrapper_test SOURCES MoveWrapperTest.cpp
+      TEST mpmc_pipeline_test SOURCES MPMCPipelineTest.cpp
+      TEST mpmc_queue_test SLOW
+        SOURCES MPMCQueueTest.cpp
+      TEST network_address_test HANGING
+        SOURCES
+          IPAddressTest.cpp
+          MacAddressTest.cpp
+          SocketAddressTest.cpp
+      TEST optional_test SOURCES OptionalTest.cpp
+      TEST packed_sync_ptr_test HANGING
+        SOURCES PackedSyncPtrTest.cpp
+      TEST padded_test SOURCES PaddedTest.cpp
+      TEST partial_test SOURCES PartialTest.cpp
+      TEST portability_test SOURCES PortabilityTest.cpp
+      TEST producer_consumer_queue_test SLOW
+        SOURCES ProducerConsumerQueueTest.cpp
+      TEST r_w_spin_lock_test SOURCES RWSpinLockTest.cpp
+      TEST random_test SOURCES RandomTest.cpp
+      TEST range_test SOURCES RangeTest.cpp
+      TEST safe_assert_test SOURCES SafeAssertTest.cpp
+      TEST scope_guard_test SOURCES ScopeGuardTest.cpp
+      # Heavily dependent on drand and srand48
+      #TEST shared_mutex_test SOURCES SharedMutexTest.cpp
+      TEST shell_test SOURCES ShellTest.cpp
+      TEST singleton_test SOURCES SingletonTest.cpp
+      TEST singleton_test_global SOURCES SingletonTestGlobal.cpp
+      TEST singleton_thread_local_test SOURCES SingletonThreadLocalTest.cpp
+      TEST singletonvault_c_test SOURCES SingletonVaultCTest.cpp
+      TEST small_vector_test SOURCES small_vector_test.cpp
+      TEST sorted_vector_types_test SOURCES sorted_vector_test.cpp
+      TEST sparse_byte_set_test SOURCES SparseByteSetTest.cpp
+      TEST spooky_hash_v1_test SOURCES SpookyHashV1Test.cpp
+      TEST spooky_hash_v2_test SOURCES SpookyHashV2Test.cpp
+      TEST string_test SOURCES StringTest.cpp
+      #TEST subprocess_test SOURCES SubprocessTest.cpp
+      TEST synchronized_test SOURCES SynchronizedTest.cpp
+      TEST thread_cached_arena_test SOURCES ThreadCachedArenaTest.cpp
+      TEST thread_cached_int_test SOURCES ThreadCachedIntTest.cpp
+      TEST thread_local_test SOURCES ThreadLocalTest.cpp
+      TEST thread_name_test SOURCES ThreadNameTest.cpp
+      TEST timeout_queue_test SOURCES TimeoutQueueTest.cpp
+      TEST timeseries_histogram_test SOURCES TimeseriesHistogramTest.cpp
+      TEST timeseries_test SOURCES TimeseriesTest.cpp
+      TEST token_bucket_test SOURCES TokenBucketTest.cpp
+      TEST traits_test SOURCES TraitsTest.cpp
+      TEST try_test SOURCES TryTest.cpp
+      TEST unit_test SOURCES UnitTest.cpp
+      TEST uri_test SOURCES UriTest.cpp
+      TEST varint_test SOURCES VarintTest.cpp
+  )
+endif()