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(CheckCXXSymbolExists)
17include(CheckIncludeFileCXX)
18include(CheckFunctionExists)
19include(CMakePushCheckState)
20
21set(
22  BOOST_LINK_STATIC "auto"
23  CACHE STRING
24  "Whether to link against boost statically or dynamically."
25)
26if("${BOOST_LINK_STATIC}" STREQUAL "auto")
27  # Default to linking boost statically on Windows with MSVC
28  if(MSVC)
29    set(FOLLY_BOOST_LINK_STATIC ON)
30  else()
31    set(FOLLY_BOOST_LINK_STATIC OFF)
32  endif()
33else()
34  set(FOLLY_BOOST_LINK_STATIC "${BOOST_LINK_STATIC}")
35endif()
36set(Boost_USE_STATIC_LIBS "${FOLLY_BOOST_LINK_STATIC}")
37
38find_package(Boost 1.51.0 MODULE
39  COMPONENTS
40    context
41    filesystem
42    program_options
43    regex
44    system
45    thread
46  REQUIRED
47)
48list(APPEND FOLLY_LINK_LIBRARIES ${Boost_LIBRARIES})
49list(APPEND FOLLY_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIRS})
50
51find_package(DoubleConversion MODULE REQUIRED)
52list(APPEND FOLLY_LINK_LIBRARIES ${DOUBLE_CONVERSION_LIBRARY})
53list(APPEND FOLLY_INCLUDE_DIRECTORIES ${DOUBLE_CONVERSION_INCLUDE_DIR})
54
55find_package(Gflags MODULE)
56set(FOLLY_HAVE_LIBGFLAGS ${LIBGFLAGS_FOUND})
57if(LIBGFLAGS_FOUND)
58  list(APPEND FOLLY_LINK_LIBRARIES ${LIBGFLAGS_LIBRARY})
59  list(APPEND FOLLY_INCLUDE_DIRECTORIES ${LIBGFLAGS_INCLUDE_DIR})
60  set(FOLLY_LIBGFLAGS_LIBRARY ${LIBGFLAGS_LIBRARY})
61  set(FOLLY_LIBGFLAGS_INCLUDE ${LIBGFLAGS_INCLUDE_DIR})
62endif()
63
64find_package(Glog MODULE)
65set(FOLLY_HAVE_LIBGLOG ${GLOG_FOUND})
66list(APPEND FOLLY_LINK_LIBRARIES ${GLOG_LIBRARY})
67list(APPEND FOLLY_INCLUDE_DIRECTORIES ${GLOG_INCLUDE_DIR})
68
69find_package(LibEvent MODULE REQUIRED)
70list(APPEND FOLLY_LINK_LIBRARIES ${LIBEVENT_LIB})
71list(APPEND FOLLY_INCLUDE_DIRECTORIES ${LIBEVENT_INCLUDE_DIR})
72
73find_package(ZLIB MODULE)
74set(FOLLY_HAVE_LIBZ ${ZLIB_FOUND})
75if (ZLIB_FOUND)
76  list(APPEND FOLLY_INCLUDE_DIRECTORIES ${ZLIB_INCLUDE_DIRS})
77  list(APPEND FOLLY_LINK_LIBRARIES ${ZLIB_LIBRARIES})
78  list(APPEND CMAKE_REQUIRED_LIBRARIES ${ZLIB_LIBRARIES})
79endif()
80
81find_package(OpenSSL MODULE REQUIRED)
82list(APPEND FOLLY_LINK_LIBRARIES ${OPENSSL_LIBRARIES})
83list(APPEND FOLLY_INCLUDE_DIRECTORIES ${OPENSSL_INCLUDE_DIR})
84list(APPEND CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
85list(APPEND CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
86check_function_exists(ASN1_TIME_diff FOLLY_HAVE_OPENSSL_ASN1_TIME_DIFF)
87list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
88list(REMOVE_ITEM CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
89if (ZLIB_FOUND)
90    list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES ${ZLIB_LIBRARIES})
91endif()
92
93find_package(BZip2 MODULE)
94set(FOLLY_HAVE_LIBBZ2 ${BZIP2_FOUND})
95if (BZIP2_FOUND)
96  list(APPEND FOLLY_INCLUDE_DIRECTORIES ${BZIP2_INCLUDE_DIRS})
97  list(APPEND FOLLY_LINK_LIBRARIES ${BZIP2_LIBRARIES})
98endif()
99
100find_package(LibLZMA MODULE)
101set(FOLLY_HAVE_LIBLZMA ${LIBLZMA_FOUND})
102if (LIBLZMA_FOUND)
103  list(APPEND FOLLY_INCLUDE_DIRECTORIES ${LIBLZMA_INCLUDE_DIRS})
104  list(APPEND FOLLY_LINK_LIBRARIES ${LIBLZMA_LIBRARIES})
105endif()
106
107find_package(LZ4 MODULE)
108set(FOLLY_HAVE_LIBLZ4 ${LZ4_FOUND})
109if (LZ4_FOUND)
110  list(APPEND FOLLY_INCLUDE_DIRECTORIES ${LZ4_INCLUDE_DIR})
111  list(APPEND FOLLY_LINK_LIBRARIES ${LZ4_LIBRARY})
112endif()
113
114find_package(Zstd MODULE)
115set(FOLLY_HAVE_LIBZSTD ${ZSTD_FOUND})
116if(ZSTD_FOUND)
117  list(APPEND FOLLY_INCLUDE_DIRECTORIES ${ZSTD_INCLUDE_DIR})
118  list(APPEND FOLLY_LINK_LIBRARIES ${ZSTD_LIBRARY})
119endif()
120
121find_package(Snappy MODULE)
122set(FOLLY_HAVE_LIBSNAPPY ${SNAPPY_FOUND})
123if (SNAPPY_FOUND)
124  list(APPEND FOLLY_INCLUDE_DIRECTORIES ${SNAPPY_INCLUDE_DIR})
125  list(APPEND FOLLY_LINK_LIBRARIES ${SNAPPY_LIBRARY})
126endif()
127
128find_package(LibDwarf)
129list(APPEND FOLLY_LINK_LIBRARIES ${LIBDWARF_LIBRARIES})
130list(APPEND FOLLY_INCLUDE_DIRECTORIES ${LIBDWARF_INCLUDE_DIRS})
131
132find_package(Libiberty)
133list(APPEND FOLLY_LINK_LIBRARIES ${LIBIBERTY_LIBRARIES})
134list(APPEND FOLLY_INCLUDE_DIRECTORIES ${LIBIBERTY_INCLUDE_DIRS})
135
136find_package(LibAIO)
137list(APPEND FOLLY_LINK_LIBRARIES ${LIBAIO_LIBRARIES})
138list(APPEND FOLLY_INCLUDE_DIRECTORIES ${LIBAIO_INCLUDE_DIRS})
139
140find_package(LibUring)
141list(APPEND FOLLY_LINK_LIBRARIES ${LIBURING_LIBRARIES})
142list(APPEND FOLLY_INCLUDE_DIRECTORIES ${LIBURING_INCLUDE_DIRS})
143
144find_package(Libsodium)
145list(APPEND FOLLY_LINK_LIBRARIES ${LIBSODIUM_LIBRARIES})
146list(APPEND FOLLY_INCLUDE_DIRECTORIES ${LIBSODIUM_INCLUDE_DIRS})
147
148list(APPEND FOLLY_LINK_LIBRARIES ${CMAKE_DL_LIBS})
149list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
150
151if (PYTHON_EXTENSIONS)
152  find_package(PythonInterp 3.6 REQUIRED)
153  find_package(Cython 0.26 REQUIRED)
154endif ()
155
156find_package(LibUnwind)
157list(APPEND FOLLY_LINK_LIBRARIES ${LIBUNWIND_LIBRARIES})
158list(APPEND FOLLY_INCLUDE_DIRECTORIES ${LIBUNWIND_INCLUDE_DIRS})
159if (LIBUNWIND_FOUND)
160  set(FOLLY_HAVE_LIBUNWIND ON)
161endif()
162if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
163  list(APPEND FOLLY_LINK_LIBRARIES "execinfo")
164endif ()
165
166cmake_push_check_state()
167set(CMAKE_REQUIRED_DEFINITIONS -D_XOPEN_SOURCE)
168check_cxx_symbol_exists(swapcontext ucontext.h FOLLY_HAVE_SWAPCONTEXT)
169cmake_pop_check_state()
170
171set(FOLLY_USE_SYMBOLIZER OFF)
172CHECK_INCLUDE_FILE_CXX(elf.h FOLLY_HAVE_ELF)
173find_package(Backtrace)
174
175set(FOLLY_HAVE_BACKTRACE ${Backtrace_FOUND})
176set(FOLLY_HAVE_DWARF ${LIBDWARF_FOUND})
177if (NOT WIN32 AND NOT APPLE)
178  set(FOLLY_USE_SYMBOLIZER ${FREEBSD_FOLLY_USE_SYMBOLIZER})
179endif()
180message(STATUS "Setting FOLLY_USE_SYMBOLIZER: ${FOLLY_USE_SYMBOLIZER}")
181message(STATUS "Setting FOLLY_HAVE_ELF: ${FOLLY_HAVE_ELF}")
182message(STATUS "Setting FOLLY_HAVE_DWARF: ${FOLLY_HAVE_DWARF}")
183
184# Using clang with libstdc++ requires explicitly linking against libatomic
185check_cxx_source_compiles("
186  #include <atomic>
187  int main(int argc, char** argv) {
188    struct Test { int val; };
189    std::atomic<Test> s;
190    return static_cast<int>(s.is_lock_free());
191  }"
192  FOLLY_CPP_ATOMIC_BUILTIN
193)
194if(NOT FOLLY_CPP_ATOMIC_BUILTIN)
195  list(APPEND CMAKE_REQUIRED_LIBRARIES atomic)
196  list(APPEND FOLLY_LINK_LIBRARIES atomic)
197  check_cxx_source_compiles("
198    #include <atomic>
199    int main(int argc, char** argv) {
200      struct Test { int val; };
201      std::atomic<Test> s2;
202      return static_cast<int>(s2.is_lock_free());
203    }"
204    FOLLY_CPP_ATOMIC_WITH_LIBATOMIC
205  )
206  if (NOT FOLLY_CPP_ATOMIC_WITH_LIBATOMIC)
207    message(
208      FATAL_ERROR "unable to link C++ std::atomic code: you may need \
209      to install GNU libatomic"
210    )
211  endif()
212endif()
213
214check_cxx_source_compiles("
215  #include <type_traits>
216  #if _GLIBCXX_RELEASE
217  int main() {}
218  #endif"
219  FOLLY_STDLIB_LIBSTDCXX
220)
221check_cxx_source_compiles("
222  #include <type_traits>
223  #if _GLIBCXX_RELEASE >= 9
224  int main() {}
225  #endif"
226  FOLLY_STDLIB_LIBSTDCXX_GE_9
227)
228check_cxx_source_compiles("
229  #include <type_traits>
230  #if _LIBCPP_VERSION
231  int main() {}
232  #endif"
233  FOLLY_STDLIB_LIBCXX
234)
235check_cxx_source_compiles("
236  #include <type_traits>
237  #if _LIBCPP_VERSION >= 9000
238  int main() {}
239  #endif"
240  FOLLY_STDLIB_LIBCXX_GE_9
241)
242check_cxx_source_compiles("
243  #include <type_traits>
244  #if _CPPLIB_VER
245  int main() {}
246  #endif"
247  FOLLY_STDLIB_LIBCPP
248)
249
250if (APPLE)
251  list (APPEND CMAKE_REQUIRED_LIBRARIES c++abi)
252  list (APPEND FOLLY_LINK_LIBRARIES c++abi)
253endif ()
254
255if (FOLLY_STDLIB_LIBSTDCXX AND NOT FOLLY_STDLIB_LIBSTDCXX_GE_9)
256  list (APPEND CMAKE_REQUIRED_LIBRARIES stdc++fs)
257  list (APPEND FOLLY_LINK_LIBRARIES stdc++fs)
258endif()
259if (FOLLY_STDLIB_LIBCXX AND NOT FOLLY_STDLIB_LIBCXX_GE_9)
260  list (APPEND CMAKE_REQUIRED_LIBRARIES c++fs)
261  list (APPEND FOLLY_LINK_LIBRARIES c++fs)
262endif ()
263
264option(
265  FOLLY_LIBRARY_SANITIZE_ADDRESS
266  "Build folly with Address Sanitizer enabled."
267  OFF
268)
269
270if ($ENV{WITH_ASAN})
271  message(STATUS "ENV WITH_ASAN is set")
272  set (FOLLY_LIBRARY_SANITIZE_ADDRESS ON)
273endif()
274
275if (FOLLY_LIBRARY_SANITIZE_ADDRESS)
276  if ("${CMAKE_CXX_COMPILER_ID}" MATCHES GNU)
277    set(FOLLY_LIBRARY_SANITIZE_ADDRESS ON)
278    set(FOLLY_ASAN_FLAGS -fsanitize=address,undefined)
279    list(APPEND FOLLY_CXX_FLAGS ${FOLLY_ASAN_FLAGS})
280    # All of the functions in folly/detail/Sse.cpp are intended to be compiled
281    # with ASAN disabled.  They are marked with attributes to disable the
282    # sanitizer, but even so, gcc fails to compile them for some reason when
283    # sanitization is enabled on the compile line.
284    set_source_files_properties(
285      "${PROJECT_SOURCE_DIR}/folly/detail/Sse.cpp"
286      PROPERTIES COMPILE_FLAGS -fno-sanitize=address,undefined
287    )
288  elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES Clang)
289    set(FOLLY_LIBRARY_SANITIZE_ADDRESS ON)
290    set(
291      FOLLY_ASAN_FLAGS
292      -fno-common
293      -fsanitize=address,undefined,integer,nullability
294      -fno-sanitize=unsigned-integer-overflow
295    )
296    list(APPEND FOLLY_CXX_FLAGS ${FOLLY_ASAN_FLAGS})
297  endif()
298endif()
299
300add_library(folly_deps INTERFACE)
301
302find_package(fmt CONFIG)
303if (NOT DEFINED fmt_CONFIG)
304    # Fallback on a normal search on the current system
305    find_package(Fmt MODULE REQUIRED)
306endif()
307target_link_libraries(folly_deps INTERFACE fmt::fmt)
308
309list(REMOVE_DUPLICATES FOLLY_INCLUDE_DIRECTORIES)
310target_include_directories(folly_deps INTERFACE ${FOLLY_INCLUDE_DIRECTORIES})
311target_link_libraries(folly_deps INTERFACE
312  ${FOLLY_LINK_LIBRARIES}
313  ${FOLLY_SHINY_DEPENDENCIES}
314  ${FOLLY_ASAN_FLAGS}
315)
316