cmake: add checks to generate folly-config.h correctly
authorAdam Simpkins <simpkins@fb.com>
Sat, 13 Jan 2018 00:03:00 +0000 (16:03 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Sat, 13 Jan 2018 00:07:43 +0000 (16:07 -0800)
Summary:
Add proper checks to detect and set the values in folly-config.h correctly.
Previously the code simply hard-coded values that were appropriate for Windows.

This does not yet define all of the settings produced by the autoconf build,
but it lets the CMake-based build largely succeed on Linux systems.

Reviewed By: meyering

Differential Revision: D6710437

fbshipit-source-id: 80490080ee6322995b740ac2a15181d220c6874a

CMake/FollyConfigChecks.cmake [new file with mode: 0644]
CMake/folly-config.h.cmake
CMakeLists.txt

diff --git a/CMake/FollyConfigChecks.cmake b/CMake/FollyConfigChecks.cmake
new file mode 100644 (file)
index 0000000..b7da815
--- /dev/null
@@ -0,0 +1,61 @@
+include(CheckCXXSourceCompiles)
+include(CheckCXXSourceRuns)
+include(CheckFunctionExists)
+include(CheckIncludeFile)
+include(CheckSymbolExists)
+
+CHECK_INCLUDE_FILE_CXX(malloc.h FOLLY_HAVE_MALLOC_H)
+CHECK_INCLUDE_FILE_CXX(bits/functexcept.h FOLLY_HAVE_BITS_FUNCTEXCEPT_H)
+
+if (FOLLY_HAVE_PTHREAD)
+  set(CMAKE_REQUIRED_LIBRARIES
+      "${CMAKE_REQUIRED_LIBRARIES} ${LIBPTHREAD_LIBRARIES}")
+  set(CMAKE_REQUIRED_INCLUDES
+      "${CMAKE_REQUIRED_INCLUDES} ${LIBPTHREAD_INCLUDE_DIRS}")
+endif()
+check_symbol_exists(pthread_atfork pthread.h FOLLY_HAVE_PTHREAD_ATFORK)
+
+# Unfortunately check_symbol_exists() does not work for memrchr():
+# it fails complaining that there are multiple overloaded versions of memrchr()
+check_function_exists(memrchr FOLLY_HAVE_MEMRCHR)
+check_symbol_exists(preadv sys/uio.h FOLLY_HAVE_PREADV)
+check_symbol_exists(pwritev sys/uio.h FOLLY_HAVE_PWRITEV)
+check_symbol_exists(clock_gettime time.h FOLLY_HAVE_CLOCK_GETTIME)
+
+check_cxx_source_compiles("
+  #pragma GCC diagnostic error \"-Wattributes\"
+  extern \"C\" void (*test_ifunc(void))() { return 0; }
+  void func() __attribute__((ifunc(\"test_ifunc\")));
+  int main() { return 0; }"
+  FOLLY_HAVE_IFUNC
+)
+check_cxx_source_compiles("
+  #include <type_traits>
+  const bool val = std::is_trivially_copyable<bool>::value;
+  int main() { return 0; }"
+  FOLLY_HAVE_STD__IS_TRIVIALLY_COPYABLE
+)
+check_cxx_source_runs("
+  int main(int, char**) {
+    char buf[64] = {0};
+    unsigned long *ptr = (unsigned long *)(buf + 1);
+    *ptr = 0xdeadbeef;
+    return (*ptr & 0xff) == 0xef ? 0 : 1;
+  }"
+  FOLLY_HAVE_UNALIGNED_ACCESS
+)
+check_cxx_source_compiles("
+  int main(int argc, char** argv) {
+    unsigned size = argc;
+    char data[size];
+    return 0;
+  }"
+  FOLLY_HAVE_VLA
+)
+check_cxx_source_compiles("
+  extern \"C\" void configure_link_extern_weak_test() __attribute__((weak));
+  int main(int argc, char** argv) {
+    return configure_link_extern_weak_test == nullptr;
+  }"
+  FOLLY_HAVE_WEAK_SYMBOLS
+)
index 1cefa40..0f8a31e 100755 (executable)
 #pragma once\r
 \r
 #cmakedefine FOLLY_HAVE_PTHREAD 1\r
+#cmakedefine FOLLY_HAVE_PTHREAD_ATFORK 1\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_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
+#cmakedefine FOLLY_HAVE_MALLOC_H 1\r
+#cmakedefine FOLLY_HAVE_BITS_FUNCTEXCEPT_H 1\r
+\r
+#cmakedefine FOLLY_HAVE_MEMRCHR 1\r
+#cmakedefine FOLLY_HAVE_PREADV 1\r
+#cmakedefine FOLLY_HAVE_PWRITEV 1\r
+#cmakedefine FOLLY_HAVE_CLOCK_GETTIME 1\r
+\r
+#cmakedefine FOLLY_HAVE_IFUNC 1\r
+#cmakedefine FOLLY_HAVE_STD__IS_TRIVIALLY_COPYABLE 1\r
+#cmakedefine FOLLY_HAVE_UNALIGNED_ACCESS 1\r
+#cmakedefine FOLLY_HAVE_VLA 1\r
+#cmakedefine FOLLY_HAVE_WEAK_SYMBOLS 1\r
 \r
 #define FOLLY_VERSION "${PACKAGE_VERSION}"\r
 \r
index fe6b4a5..9f8573b 100755 (executable)
@@ -16,12 +16,12 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
 
 project(${PACKAGE_NAME} CXX)
 
-# Check target architecture
-if (NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
-  message(FATAL_ERROR "Folly requires a 64bit target architecture.")
-endif()
-
 if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
+  # Check target architecture
+  if (NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
+    message(FATAL_ERROR "Folly requires a 64bit target architecture.")
+  endif()
+
   if (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1920)
     set(MSVC_IS_2017 ON)
   elseif (MSVC_VERSION EQUAL 1900)
@@ -81,10 +81,6 @@ include(folly-deps) # Find the required packages
 if (LIBPTHREAD_FOUND)
   set(FOLLY_HAVE_PTHREAD ON)
 endif()
-configure_file(
-  ${CMAKE_CURRENT_SOURCE_DIR}/CMake/folly-config.h.cmake
-  ${CMAKE_CURRENT_BINARY_DIR}/folly/folly-config.h
-)
 
 if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
   include(FollyCompilerMSVC)
@@ -93,6 +89,12 @@ else()
 endif()
 include(FollyFunctions)
 
+include(FollyConfigChecks)
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/CMake/folly-config.h.cmake
+  ${CMAKE_CURRENT_BINARY_DIR}/folly/folly-config.h
+)
+
 # Main folly library files
 auto_sources(files "*.cpp" "RECURSE" "${FOLLY_DIR}")
 auto_sources(hfiles "*.h" "RECURSE" "${FOLLY_DIR}")