2 # +----------------------------------------------------------------------+
4 # +----------------------------------------------------------------------+
5 # | Copyright (c) 2010 Facebook, Inc. (http://www.facebook.com) |
6 # | Copyright (c) 1997-2010 The PHP Group |
7 # +----------------------------------------------------------------------+
8 # | This source file is subject to version 3.01 of the PHP license, |
9 # | that is bundled with this package in the file LICENSE, and is |
10 # | available through the world-wide-web at the following url: |
11 # | http://www.php.net/license/3_01.txt |
12 # | If you did not receive a copy of the PHP license and are unable to |
13 # | obtain it through the world-wide-web, please send a note to |
14 # | license@php.net so we can mail you a copy immediately. |
15 # +----------------------------------------------------------------------+
18 include(CheckFunctionExists)
22 if (LIBDL_INCLUDE_DIRS)
23 add_definitions("-DHAVE_LIBDL")
24 include_directories(${LIBDL_INCLUDE_DIRS})
25 if (LIBDL_NEEDS_UNDERSCORE)
26 add_definitions("-DLIBDL_NEEDS_UNDERSCORE")
31 find_package(Glog REQUIRED)
33 add_definitions("-DGOOGLE_GLOG_DLL_DECL=")
35 include_directories(${LIBGLOG_INCLUDE_DIR})
38 find_package(Libinotify)
39 if (LIBINOTIFY_INCLUDE_DIR)
40 include_directories(${LIBINOTIFY_INCLUDE_DIR})
43 # mysql checks - if we're using async mysql, we use fbmysqlclient from
44 # third-party/ instead
45 if (ENABLE_ASYNC_MYSQL)
48 ${TP_DIR}/squangle/src/
49 ${TP_DIR}/fb-mysql/src/include/
51 set(MYSQL_CLIENT_LIB_DIR ${TP_DIR}/fb-mysql/src/)
53 ${MYSQL_CLIENT_LIB_DIR}/libmysql/libfbmysqlclient_r.a
56 find_package(MySQL REQUIRED)
57 link_directories(${MYSQL_LIB_DIR})
58 include_directories(${MYSQL_INCLUDE_DIR})
61 if (MYSQL_UNIX_SOCK_ADDR)
62 add_definitions(-DPHP_MYSQL_UNIX_SOCK_ADDR="${MYSQL_UNIX_SOCK_ADDR}")
64 message(FATAL_ERROR "Could not find MySQL socket path - if you install a MySQL server, this should be automatically detected. Alternatively, specify -DMYSQL_UNIX_SOCK_ADDR=/path/to/mysql.socket ; if you don't care about unix socket support for MySQL, specify -DMYSQL_UNIX_SOCK_ADDR=/dev/null")
69 include_directories(${PCRE_INCLUDE_DIR})
72 find_package(LibEvent REQUIRED)
73 include_directories(${LIBEVENT_INCLUDE_DIR})
75 set(CMAKE_REQUIRED_LIBRARIES "${LIBEVENT_LIB}")
76 CHECK_FUNCTION_EXISTS("evhttp_bind_socket_with_fd" HAVE_CUSTOM_LIBEVENT)
77 if(HAVE_CUSTOM_LIBEVENT)
78 message("Using custom LIBEVENT")
79 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_CUSTOM_LIBEVENT")
81 set(CMAKE_REQUIRED_LIBRARIES)
87 include_directories(${LibXed_INCLUDE_DIR})
89 add_definitions("-DHAVE_LIBXED")
91 message(STATUS "XED is disabled")
95 find_package(CURL REQUIRED)
96 include_directories(${CURL_INCLUDE_DIR})
98 add_definitions("-DCURL_STATICLIB")
101 set(CMAKE_REQUIRED_LIBRARIES "${CURL_LIBRARIES}")
102 CHECK_FUNCTION_EXISTS("curl_multi_select" HAVE_CURL_MULTI_SELECT)
103 CHECK_FUNCTION_EXISTS("curl_multi_wait" HAVE_CURL_MULTI_WAIT)
104 if (HAVE_CURL_MULTI_SELECT)
105 add_definitions("-DHAVE_CURL_MULTI_SELECT")
107 if (HAVE_CURL_MULTI_WAIT)
108 add_definitions("-DHAVE_CURL_MULTI_WAIT")
110 set(CMAKE_REQUIRED_LIBRARIES)
113 find_package(LibXml2 REQUIRED)
114 include_directories(${LIBXML2_INCLUDE_DIR})
115 add_definitions(${LIBXML2_DEFINITIONS})
118 find_package(LibSQLite)
119 if (LIBSQLITE3_INCLUDE_DIR)
120 include_directories(${LIBSQLITE3_INCLUDE_DIR})
123 # libdouble-conversion
124 find_package(DoubleConversion)
125 if (DOUBLE_CONVERSION_INCLUDE_DIR)
126 include_directories(${DOUBLE_CONVERSION_INCLUDE_DIR})
132 include_directories(${LZ4_INCLUDE_DIR})
137 if (FASTLZ_INCLUDE_DIR)
138 include_directories(${FASTLZ_INCLUDE_DIR})
143 if (LIBZIP_INCLUDE_DIR_ZIP AND LIBZIP_INCLUDE_DIR_ZIPCONF)
144 if (LIBZIP_VERSION VERSION_LESS "0.11")
145 unset(LIBZIP_FOUND CACHE)
146 unset(LIBZIP_LIBRARY CACHE)
147 unset(LIBZIP_INCLUDE_DIR_ZIP CACHE)
148 unset(LIBZIP_INCLUDE_DIR_ZIPCONF CACHE)
149 message(STATUS "libzip is too old, found ${LIBZIP_VERSION} and we need 0.11+, using third-party bundled libzip")
151 include_directories(${LIBZIP_INCLUDE_DIR_ZIP} ${LIBZIP_INCLUDE_DIR_ZIPCONF})
152 message(STATUS "Found libzip: ${LIBZIP_LIBRARY} ${LIBZIP_VERSION}")
155 message(STATUS "Using third-party bundled libzip")
159 find_package(ICU REQUIRED)
161 if (ICU_VERSION VERSION_LESS "4.2")
162 unset(ICU_FOUND CACHE)
163 unset(ICU_INCLUDE_DIRS CACHE)
164 unset(ICU_LIBRARIES CACHE)
165 message(FATAL_ERROR "ICU is too old, found ${ICU_VERSION} and we need 4.2")
167 include_directories(${ICU_INCLUDE_DIRS})
169 add_definitions("-DU_EXPORT=")
170 add_definitions("-DU_IMPORT=")
172 # Everything is either in the `icu61` namespace or `icu` namespace, depending
173 # on another definition. There's an implicit `using namespace WHATEVER;` in
174 # ICU4c < 61.1, but now that's opt-in rather than opt-out.
175 add_definitions("-DU_USING_ICU_NAMESPACE=1")
178 # jemalloc/tmalloc and profiler
179 if (USE_GOOGLE_HEAP_PROFILER OR USE_GOOGLE_CPU_PROFILER)
180 FIND_LIBRARY(GOOGLE_PROFILER_LIB profiler)
181 FIND_PATH(GOOGLE_PROFILER_INCLUDE_DIR NAMES google/profiler.h)
182 if (GOOGLE_PROFILER_INCLUDE_DIR)
183 include_directories(${GOOGLE_PROFILER_INCLUDE_DIR})
185 if (GOOGLE_PROFILER_LIB)
186 message(STATUS "Found Google profiler: ${GOOGLE_PROFILER_LIB}")
187 if (USE_GOOGLE_CPU_PROFILER)
188 set(GOOGLE_CPU_PROFILER_ENABLED 1)
191 message(STATUS "Can't find Google profiler")
195 if (USE_GOOGLE_HEAP_PROFILER AND GOOGLE_PROFILER_LIB)
196 FIND_LIBRARY(GOOGLE_TCMALLOC_FULL_LIB tcmalloc)
197 if (GOOGLE_TCMALLOC_FULL_LIB)
198 message(STATUS "Found full tcmalloc: ${GOOGLE_TCMALLOC_FULL_LIB}")
199 set(GOOGLE_HEAP_PROFILER_ENABLED 1)
200 set(GOOGLE_TCMALLOC_ENABLED 1)
202 message(STATUS "Can't find full tcmalloc - heap profiling is disabled")
206 if(USE_JEMALLOC AND NOT GOOGLE_TCMALLOC_ENABLED)
207 add_definitions(-DUSE_JEMALLOC=1)
208 set(JEMALLOC_ENABLED 1)
210 add_definitions(-DNO_JEMALLOC=1)
213 if (USE_TCMALLOC AND NOT JEMALLOC_ENABLED AND NOT GOOGLE_TCMALLOC_ENABLED)
214 FIND_LIBRARY(GOOGLE_TCMALLOC_MIN_LIB tcmalloc_minimal)
215 if (GOOGLE_TCMALLOC_MIN_LIB)
216 message(STATUS "Found minimal tcmalloc: ${GOOGLE_TCMALLOC_MIN_LIB}")
217 set(GOOGLE_TCMALLOC_ENABLED 1)
219 message(STATUS "Can't find minimal tcmalloc")
223 if (GOOGLE_TCMALLOC_ENABLED)
224 add_definitions(-DGOOGLE_TCMALLOC=1)
226 add_definitions(-DNO_TCMALLOC=1)
228 if (GOOGLE_HEAP_PROFILER_ENABLED)
229 add_definitions(-DGOOGLE_HEAP_PROFILER=1)
231 if (GOOGLE_CPU_PROFILER_ENABLED)
232 add_definitions(-DGOOGLE_CPU_PROFILER=1)
236 if (JEMALLOC_ENABLED AND ENABLE_HHPROF)
237 add_definitions(-DENABLE_HHPROF=1)
241 find_package(TBB REQUIRED)
242 if (${TBB_INTERFACE_VERSION} LESS 5005)
243 unset(TBB_FOUND CACHE)
244 unset(TBB_INCLUDE_DIRS CACHE)
245 unset(TBB_LIBRARIES CACHE)
246 message(FATAL_ERROR "TBB is too old, please install at least 3.0(5005), preferably 4.0(6000) or higher")
248 include_directories(${TBB_INCLUDE_DIRS})
249 link_directories(${TBB_LIBRARY_DIRS})
252 find_package(OpenSSL REQUIRED)
253 include_directories(${OPENSSL_INCLUDE_DIR})
255 # LibreSSL explicitly refuses to support RAND_egd()
256 SET(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
257 SET(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
258 INCLUDE(CheckCXXSourceCompiles)
259 CHECK_CXX_SOURCE_COMPILES("#include <openssl/rand.h>
261 return RAND_egd(\"/dev/null\");
262 }" OPENSSL_HAVE_RAND_EGD)
263 if (NOT OPENSSL_HAVE_RAND_EGD)
264 add_definitions("-DOPENSSL_NO_RAND_EGD")
266 CHECK_CXX_SOURCE_COMPILES("#include <openssl/ssl.h>
268 return SSL_set_alpn_protos(nullptr, nullptr, 0);
269 }" OPENSSL_HAVE_ALPN)
270 SET(CMAKE_REQUIRED_INCLUDES)
271 SET(CMAKE_REQUIRED_LIBRARIES)
275 find_package(ZLIB REQUIRED)
276 include_directories(${ZLIB_INCLUDE_DIR})
279 find_package(ONIGURUMA REQUIRED)
280 include_directories(${ONIGURUMA_INCLUDE_DIRS})
281 if (ONIGURUMA_STATIC)
282 add_definitions("-DONIG_EXTERN=extern")
286 find_package(PThread REQUIRED)
287 include_directories(${LIBPTHREAD_INCLUDE_DIRS})
288 if (LIBPTHREAD_STATIC)
289 add_definitions("-DPTW32_STATIC_LIB")
293 NON_DISTRIBUTABLE_BUILD
294 "Use libraries which may result in a binary that can not be legally distributed"
298 # Either Readline or Editline (for hphpd)
299 if(NON_DISTRIBUTABLE_BUILD)
300 find_package(Readline)
302 if (NOT READLINE_INCLUDE_DIR)
303 find_package(Editline)
306 if (NON_DISTRIBUTABLE_BUILD AND READLINE_INCLUDE_DIR)
308 add_definitions("-DREADLINE_STATIC")
310 include_directories(${READLINE_INCLUDE_DIR})
311 elseif (EDITLINE_INCLUDE_DIRS)
312 add_definitions("-DUSE_EDITLINE")
313 include_directories(${EDITLINE_INCLUDE_DIRS})
315 message(FATAL_ERROR "Could not find Readline or Editline")
319 find_package(LibDwarf REQUIRED)
320 include_directories(${LIBDWARF_INCLUDE_DIRS})
321 if (LIBDWARF_CONST_NAME)
322 add_definitions("-DLIBDWARF_CONST_NAME")
324 if (LIBDWARF_USE_INIT_C)
325 add_definitions("-DLIBDWARF_USE_INIT_C")
328 find_package(LibElf REQUIRED)
329 include_directories(${LIBELF_INCLUDE_DIRS})
330 if (ELF_GETSHDRSTRNDX)
331 add_definitions("-DHAVE_ELF_GETSHDRSTRNDX")
335 FIND_LIBRARY(CRYPT_LIB NAMES xcrypt crypt crypto)
336 if (LINUX OR FREEBSD)
337 FIND_LIBRARY (RT_LIB rt)
341 FIND_LIBRARY (CAP_LIB cap)
344 message(FATAL_ERROR "You need to install libcap")
349 FIND_LIBRARY (DL_LIB dl)
350 FIND_LIBRARY (RESOLV_LIB resolv)
354 FIND_LIBRARY (EXECINFO_LIB execinfo)
355 if (NOT EXECINFO_LIB)
356 message(FATAL_ERROR "You need to install libexecinfo")
361 find_library(KERBEROS_LIB NAMES gssapi_krb5)
363 # This is required by Homebrew's libc. See
364 # https://github.com/facebook/hhvm/pull/5728#issuecomment-124290712
367 if (PAM_INCLUDE_PATH)
368 include_directories(${PAM_INCLUDE_PATH})
372 #find_package(BISON REQUIRED)
373 #find_package(FLEX REQUIRED)
375 #if (${FLEX_VERSION} VERSION_LESS 2.5.33)
376 # message(FATAL_ERROR "Flex is too old, found ${FLEX_VERSION} and we need 2.5.33")
379 include_directories(${HPHP_HOME}/hphp)
381 macro(hphp_link target)
382 # oniguruma must remain first for OS X to work -- see below for a somewhat
383 # dogscience explanation. If you deeply understand this, feel free to fix
384 # properly; in particular, two-level namespaces on OS X should allow us to
385 # say *which* copy of the disputed functions we want, but I don' t know
386 # how to get that to work.
388 # oniguruma has some of its own implementations of POSIX regex functions,
389 # like regcomp() an regexec(). We use onig everywhere, for both its own
390 # sepcial functions and for the POSIX replacements. This means that the
391 # linker needs to pick the implementions of the POSIX regex functions from
394 # On Linux, that works out fine, since the linker sees onig on the link
395 # line before (implicitly) libc. However, on OS X, despide the manpage for
396 # ld claiming otherwise about indirect dylib dependencies, as soon as we
397 # include one of the libs here that pull in libSystem.B, the linker will
398 # pick the implementations of those functions from libc, not from onig.
399 # And since we've included the onig headers, which have very slightly
400 # different definintions for some of the key data structures, things go
401 # quite awry -- this manifests as infinite loops or crashes when calling
402 # the PHP split() function.
404 # So make sure to link onig first, so its implementations are picked.
405 target_link_libraries(${target} ${ONIGURUMA_LIBRARIES})
408 target_link_libraries(${target} ${LIBDL_LIBRARIES})
411 if (JEMALLOC_ENABLED)
412 target_link_libraries(${target} jemalloc)
413 add_dependencies(${target} jemalloc)
416 if (GOOGLE_HEAP_PROFILER_ENABLED OR GOOGLE_CPU_PROFILER_ENABLED)
417 target_link_libraries(${target} ${GOOGLE_PROFILER_LIB})
420 if (GOOGLE_HEAP_PROFILER_ENABLED)
421 target_link_libraries(${target} ${GOOGLE_TCMALLOC_FULL_LIB})
422 elseif (GOOGLE_TCMALLOC_ENABLED)
423 target_link_libraries(${target} ${GOOGLE_TCMALLOC_MIN_LIB})
426 add_dependencies(${target} boostMaybeBuild)
427 target_link_libraries(${target} boost)
428 add_dependencies(${target} libsodiumMaybeBuild)
429 target_link_libraries(${target} libsodium)
431 target_link_libraries(${target} ${MYSQL_CLIENT_LIBS})
432 if (ENABLE_ASYNC_MYSQL)
433 target_link_libraries(${target} squangle)
435 target_link_libraries(${target} ${PCRE_LIBRARY})
436 target_link_libraries(${target} ${ICU_DATA_LIBRARIES} ${ICU_I18N_LIBRARIES} ${ICU_LIBRARIES})
437 target_link_libraries(${target} ${LIBEVENT_LIB})
438 target_link_libraries(${target} ${CURL_LIBRARIES})
439 target_link_libraries(${target} ${LIBGLOG_LIBRARY})
440 if (LIBJSONC_LIBRARY)
441 target_link_libraries(${target} ${LIBJSONC_LIBRARY})
444 if (LIBINOTIFY_LIBRARY)
445 target_link_libraries(${target} ${LIBINOTIFY_LIBRARY})
449 target_link_libraries(${target} ${CAP_LIB})
453 target_link_libraries(${target} ${RESOLV_LIB})
454 target_link_libraries(${target} ${DL_LIB})
458 target_link_libraries(${target} ${EXECINFO_LIB})
462 target_link_libraries(${target} ${LIBINTL_LIBRARIES})
463 target_link_libraries(${target} ${KERBEROS_LIB})
466 target_link_libraries(${target} ${PAM_LIBRARY})
470 if (LIBPTHREAD_LIBRARIES)
471 target_link_libraries(${target} ${LIBPTHREAD_LIBRARIES})
474 target_link_libraries(${target} ${TBB_LIBRARIES})
475 target_link_libraries(${target} ${OPENSSL_LIBRARIES})
476 target_link_libraries(${target} ${ZLIB_LIBRARIES})
478 target_link_libraries(${target} ${LIBXML2_LIBRARIES})
480 target_link_libraries(${target} ${LBER_LIBRARIES})
483 target_link_libraries(${target} ${CRYPT_LIB})
486 if (LINUX OR FREEBSD)
487 target_link_libraries(${target} ${RT_LIB})
490 if (LIBSQLITE3_FOUND AND LIBSQLITE3_LIBRARY)
491 target_link_libraries(${target} ${LIBSQLITE3_LIBRARY})
493 target_link_libraries(${target} sqlite3)
496 if (DOUBLE_CONVERSION_FOUND)
497 target_link_libraries(${target} ${DOUBLE_CONVERSION_LIBRARY})
499 target_link_libraries(${target} double-conversion)
503 target_link_libraries(${target} ${LZ4_LIBRARY})
505 target_link_libraries(${target} lz4)
507 # The syntax used for these warnings is unparsable by Apple's Clang
508 add_definitions("-DLZ4_DISABLE_DEPRECATE_WARNINGS=1")
511 target_link_libraries(${target} ${LIBZIP_LIBRARY})
513 target_link_libraries(${target} zip_static)
517 target_link_libraries(${target} ${PCRE_LIBRARY})
519 target_link_libraries(${target} pcre)
522 if (LIBFASTLZ_LIBRARY)
523 target_link_libraries(${target} ${LIBFASTLZ_LIBRARY})
525 target_link_libraries(${target} fastlz)
528 target_link_libraries(${target} timelib)
529 target_link_libraries(${target} folly)
530 target_link_libraries(${target} wangle)
531 target_link_libraries(${target} brotli_enc)
532 target_link_libraries(${target} brotli_dec)
535 target_link_libraries(${target} mcrouter)
539 target_link_libraries(${target} afdt)
541 target_link_libraries(${target} mbfl)
543 if (EDITLINE_LIBRARIES)
544 target_link_libraries(${target} ${EDITLINE_LIBRARIES})
545 elseif (READLINE_LIBRARY)
546 target_link_libraries(${target} ${READLINE_LIBRARY})
550 target_link_libraries(${target} ${LIBDWARF_LIBRARIES})
551 target_link_libraries(${target} ${LIBELF_LIBRARIES})
555 target_link_libraries(${target})
559 target_link_libraries(${target} dbghelp.lib dnsapi.lib)
562 # Check whether atomic operations require -latomic or not
563 # See https://github.com/facebook/hhvm/issues/5217
564 include(CheckCXXSourceCompiles)
565 set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
566 set(CMAKE_REQUIRED_FLAGS "-std=c++1y")
567 CHECK_CXX_SOURCE_COMPILES("
572 struct Test { int64_t val1; int64_t val2; };
574 // Do this to stop modern compilers from optimizing away the libatomic
575 // calls in release builds, making this test always pass in release builds,
576 // and incorrectly think that HHVM doesn't need linking against libatomic.
577 bool (std::atomic<Test>::* volatile x)(void) const =
578 &std::atomic<Test>::is_lock_free;
579 std::cout << (s.*x)() << std::endl;
581 " NOT_REQUIRE_ATOMIC_LINKER_FLAG)
583 if(NOT "${NOT_REQUIRE_ATOMIC_LINKER_FLAG}")
584 message(STATUS "-latomic is required to link hhvm")
585 find_library(ATOMIC_LIBRARY NAMES atomic libatomic.so.1)
586 target_link_libraries(${target} ${ATOMIC_LIBRARY})
588 set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
592 target_link_libraries(${target} ${LibXed_LIBRARY})
594 target_link_libraries(${target} xed)