1# Copyright (c) Facebook, Inc. and its affiliates.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15include(CheckCXXSourceCompiles)
16include(CheckCXXSourceRuns)
17include(CheckFunctionExists)
18include(CheckIncludeFileCXX)
19include(CheckSymbolExists)
20include(CheckTypeSize)
21include(CheckCXXCompilerFlag)
22
23if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
24  CHECK_INCLUDE_FILE_CXX(malloc_np.h FOLLY_USE_JEMALLOC)
25else()
26  CHECK_INCLUDE_FILE_CXX(jemalloc/jemalloc.h FOLLY_USE_JEMALLOC)
27endif()
28
29if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
30  # clang only rejects unknown warning flags if -Werror=unknown-warning-option
31  # is also specified.
32  check_cxx_compiler_flag(
33    -Werror=unknown-warning-option
34    COMPILER_HAS_UNKNOWN_WARNING_OPTION)
35  if (COMPILER_HAS_UNKNOWN_WARNING_OPTION)
36    set(CMAKE_REQUIRED_FLAGS
37      "${CMAKE_REQUIRED_FLAGS} -Werror=unknown-warning-option")
38  endif()
39
40  check_cxx_compiler_flag(-Wshadow-local COMPILER_HAS_W_SHADOW_LOCAL)
41  check_cxx_compiler_flag(
42    -Wshadow-compatible-local
43    COMPILER_HAS_W_SHADOW_COMPATIBLE_LOCAL)
44  if (COMPILER_HAS_W_SHADOW_LOCAL AND COMPILER_HAS_W_SHADOW_COMPATIBLE_LOCAL)
45    set(FOLLY_HAVE_SHADOW_LOCAL_WARNINGS ON)
46    list(APPEND FOLLY_CXX_FLAGS -Wshadow-compatible-local)
47  endif()
48
49  check_cxx_compiler_flag(-Wnoexcept-type COMPILER_HAS_W_NOEXCEPT_TYPE)
50  if (COMPILER_HAS_W_NOEXCEPT_TYPE)
51    list(APPEND FOLLY_CXX_FLAGS -Wno-noexcept-type)
52  endif()
53
54  check_cxx_compiler_flag(
55      -Wnullability-completeness
56      COMPILER_HAS_W_NULLABILITY_COMPLETENESS)
57  if (COMPILER_HAS_W_NULLABILITY_COMPLETENESS)
58    list(APPEND FOLLY_CXX_FLAGS -Wno-nullability-completeness)
59  endif()
60
61  check_cxx_compiler_flag(
62      -Winconsistent-missing-override
63      COMPILER_HAS_W_INCONSISTENT_MISSING_OVERRIDE)
64  if (COMPILER_HAS_W_INCONSISTENT_MISSING_OVERRIDE)
65    list(APPEND FOLLY_CXX_FLAGS -Wno-inconsistent-missing-override)
66  endif()
67
68  check_cxx_compiler_flag(-faligned-new COMPILER_HAS_F_ALIGNED_NEW)
69  if (COMPILER_HAS_F_ALIGNED_NEW)
70    list(APPEND FOLLY_CXX_FLAGS -faligned-new)
71  endif()
72
73  check_cxx_compiler_flag(-fopenmp COMPILER_HAS_F_OPENMP)
74  if (COMPILER_HAS_F_OPENMP)
75      list(APPEND FOLLY_CXX_FLAGS -fopenmp)
76  endif()
77endif()
78
79set(FOLLY_ORIGINAL_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
80string(REGEX REPLACE
81  "-std=(c|gnu)\\+\\+.."
82  ""
83  CMAKE_REQUIRED_FLAGS
84  "${CMAKE_REQUIRED_FLAGS}")
85
86check_symbol_exists(pthread_atfork pthread.h FOLLY_HAVE_PTHREAD_ATFORK)
87
88check_symbol_exists(accept4 sys/socket.h FOLLY_HAVE_ACCEPT4)
89check_symbol_exists(getrandom sys/random.h FOLLY_HAVE_GETRANDOM)
90check_symbol_exists(preadv sys/uio.h FOLLY_HAVE_PREADV)
91check_symbol_exists(pwritev sys/uio.h FOLLY_HAVE_PWRITEV)
92check_symbol_exists(clock_gettime time.h FOLLY_HAVE_CLOCK_GETTIME)
93check_symbol_exists(pipe2 unistd.h FOLLY_HAVE_PIPE2)
94check_symbol_exists(sendmmsg sys/socket.h FOLLY_HAVE_SENDMMSG)
95check_symbol_exists(recvmmsg sys/socket.h FOLLY_HAVE_RECVMMSG)
96
97check_function_exists(malloc_usable_size FOLLY_HAVE_MALLOC_USABLE_SIZE)
98
99set(CMAKE_REQUIRED_FLAGS "${FOLLY_ORIGINAL_CMAKE_REQUIRED_FLAGS}")
100
101check_cxx_source_compiles("
102  #pragma GCC diagnostic error \"-Wattributes\"
103  extern \"C\" void (*test_ifunc(void))() { return 0; }
104  void func() __attribute__((ifunc(\"test_ifunc\")));
105  int main() { return 0; }"
106  FOLLY_HAVE_IFUNC
107)
108check_cxx_source_compiles("
109  #include <type_traits>
110  const bool val = std::is_trivially_copyable<bool>::value;
111  int main() { return 0; }"
112  FOLLY_HAVE_STD__IS_TRIVIALLY_COPYABLE
113)
114check_cxx_source_runs("
115  int main(int, char**) {
116    char buf[64] = {0};
117    unsigned long *ptr = (unsigned long *)(buf + 1);
118    *ptr = 0xdeadbeef;
119    return (*ptr & 0xff) == 0xef ? 0 : 1;
120  }"
121  FOLLY_HAVE_UNALIGNED_ACCESS
122)
123check_cxx_source_compiles("
124  int main(int argc, char** argv) {
125    unsigned size = argc;
126    char data[size];
127    return 0;
128  }"
129  FOLLY_HAVE_VLA
130)
131check_cxx_source_runs("
132  extern \"C\" int folly_example_undefined_weak_symbol() __attribute__((weak));
133  int main(int argc, char** argv) {
134    auto f = folly_example_undefined_weak_symbol; // null pointer
135    return f ? f() : 0; // must compile, link, and run with null pointer
136  }"
137  FOLLY_HAVE_WEAK_SYMBOLS
138)
139check_cxx_source_runs("
140  #include <dlfcn.h>
141  int main() {
142    void *h = dlopen(\"linux-vdso.so.1\", RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
143    if (h == nullptr) {
144      return -1;
145    }
146    dlclose(h);
147    return 0;
148  }"
149  FOLLY_HAVE_LINUX_VDSO
150)
151
152check_cxx_source_runs("
153  #include <cstddef>
154  #include <cwchar>
155  int main(int argc, char** argv) {
156    return wcstol(L\"01\", nullptr, 10) == 1 ? 0 : 1;
157  }"
158  FOLLY_HAVE_WCHAR_SUPPORT
159)
160
161check_cxx_source_compiles("
162  #include <ext/random>
163  int main(int argc, char** argv) {
164    __gnu_cxx::sfmt19937 rng;
165    return 0;
166  }"
167  FOLLY_HAVE_EXTRANDOM_SFMT19937
168)
169
170check_cxx_source_runs("
171  #include <stdarg.h>
172  #include <stdio.h>
173
174  int call_vsnprintf(const char* fmt, ...) {
175    char buf[256];
176    va_list ap;
177    va_start(ap, fmt);
178    int result = vsnprintf(buf, sizeof(buf), fmt, ap);
179    va_end(ap);
180    return result;
181  }
182
183  int main(int argc, char** argv) {
184    return call_vsnprintf(\"%\", 1) < 0 ? 0 : 1;
185  }"
186  HAVE_VSNPRINTF_ERRORS
187)
188
189if (FOLLY_HAVE_LIBGFLAGS)
190  # Older releases of gflags used the namespace "gflags"; newer releases
191  # use "google" but also make symbols available in the deprecated "gflags"
192  # namespace too.  The folly code internally uses "gflags" unless we tell it
193  # otherwise.
194  list(APPEND CMAKE_REQUIRED_LIBRARIES ${FOLLY_LIBGFLAGS_LIBRARY})
195  list(APPEND CMAKE_REQUIRED_INCLUDES ${FOLLY_LIBGFLAGS_INCLUDE})
196  check_cxx_source_compiles("
197    #include <gflags/gflags.h>
198    int main() {
199      gflags::GetArgv();
200      return 0;
201    }
202    "
203    GFLAGS_NAMESPACE_IS_GFLAGS
204  )
205  list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES ${FOLLY_LIBGFLAGS_LIBRARY})
206  list(REMOVE_ITEM CMAKE_REQUIRED_INCLUDES ${FOLLY_LIBGFLAGS_INCLUDE})
207  if (GFLAGS_NAMESPACE_IS_GFLAGS)
208    set(FOLLY_UNUSUAL_GFLAGS_NAMESPACE OFF)
209    set(FOLLY_GFLAGS_NAMESPACE gflags)
210  else()
211    set(FOLLY_UNUSUAL_GFLAGS_NAMESPACE ON)
212    set(FOLLY_GFLAGS_NAMESPACE google)
213  endif()
214endif()
215