Handle methods that have no parameters
[hiphop-php.git] / CMake / HHVMExtensionConfig.cmake
blob0436a7545ca37df6e875d49dd28d91e22242dc3e
1 # This file holds the configuration mechanism for extensions.
3 # Now, the structure of the globals this uses.
5 # HHVM_EXTENSION_COUNT: <int>
6 # An integer representing the number of extensions that have
7 # been defined.
9 # HHVM_EXTENSIONS_REQUIRED_LIBRARIES: <list of paths>
10 # A list of the additional libraries that need to be linked
11 # against for the enabled extensions.
13 # HHVM_EXTENSIONS_REQUIRED_INCLUDE_DIRS: <list of paths>
14 # A list of the additional include paths that need to be used
15 # in order to compile the enabled extensions.
17 # HHVM_EXTENSIONS_REQUIRED_DEFINES: <list of strings>
18 # A list of the additional defines that need to be used in order
19 # to compile the enabled extensions.
22 # The extensions' internal info is stored in globals, prefixed by
23 # HHVM_EXTENSION_#_ where # represents a number between 0 and
24 # HHVM_EXTENSION_COUNT.
26 # HHVM_EXTENSION_#_NAME: <string>
27 # The name of extension.
29 # HHVM_EXTENSION_#_PRETTY_NAME: <string>
30 # The name of the extension to use in messages.
32 # HHVM_EXTENSION_#_REQUIRED: <ON/OFF>
33 # If ON, then the extension is integral to the function
34 # of HHVM itself, so failing to build it is not an option,
35 # and a FATAL_ERROR should be triggered if dependencies
36 # fail.
38 # HHVM_EXTENSION_#_ROOT_DIR: <string>
39 # The root directory to which all file paths
40 # referenced by the extension are relative to.
42 # HHVM_EXTENSION_#_ENABLED_STATE: <int {0, 1, 2, 3, 4}>
43 # The state of an extension's enabling. If this is 0, then the extension
44 # may be enabled once dependency calculation is performed. If this is 1,
45 # then the extension is enabled, and if it is 2, then it is disabled.
46 # If this is 3, then the extension has been forcefully enabled, and its
47 # dependencies should be checked. If this is 4, then the extension is a
48 # 'wanted' extension, and we should error if dependencies for it can't
49 # be resolved, unless the dependency that fails is an os* or var* dependency,
50 # in which case, we don't error, but just disable the extension.
52 # HHVM_EXTENSION_#_SOURCE_FILES: <list>
53 # The list of files to compile for the extension.
55 # HHVM_EXTENSION_#_HEADER_FILES: <list>
56 # The list of header files that make up this extension.
58 # HHVM_EXTENSION_#_SYSTEMLIB: <list>
59 # The list of php files that make up this extension's own systemlib.
61 # HHVM_EXTENSION_#_DEPENDENCIES: <list>
62 # The list of dependencies of this extension. For details on the specifics
63 # of values in this list, see the documentation of the DEPENDS parameter
64 # of HHVM_DEFINE_EXTENSION.
66 # HHVM_EXTENSION_#_DEPENDENCIES_OPTIONAL: <list>
67 # A list of ON/OFF values mapping to the values in HHVM_EXTENSION_#_DEPENDENCIES.
68 # If the value is ON, then the dependency is optional, and the build should
69 # not fail if the dependency can't be resolved.
71 include(CheckFunctionExists)
72 include(HPHPFunctions)
73 include(Options)
75 # function HHVM_DEFINE_EXTENSION:
76 # This is the function that each individual extension will call. It
77 # defines everything about the extension.
79 # Note that HRE_CURRENT_EXT_PATH should have been defined before calling this,
80 # and it should be set to the root directory to which all paths passed to this
81 # function are relative to.
83 # Parameters:
85 # NAME
86 # The name of the extension. This name will be used in the variable names,
87 # so spaces are not allowed.
89 # [REQUIRED]
90 # This extension is integral to the functioning of HHVM, and
91 # can not be disabled via `-DENABLE_EXTENSION_FOO=Off`.
92 # A FATAL_ERROR will be triggered if dependencies fail to resolve.
94 # [IMPLICIT]
95 # If the library dependencies for this extension fail to resolve,
96 # and it has not be explicitly enabled via `-DENABLE_EXTENSION_FOO=On`,
97 # then it will be implicitly disabled by the build system.
99 # [WANTED] (default)
100 # If the library dependencies for this extension fail to resolve,
101 # and it has not been explicitly disabled with `-DENABLE_EXTENSION_FOO=Off`
102 # a FATAL_ERROR will be triggered, unless the dependency that fails is
103 # an os* or var* dependency, in which case the extension will be implicitly
104 # disabled by the build system.
106 # Note that it does not make sense to specify more than one of the above
107 # three settings as the behavior they imply is mutually exclusive.
108 # Using more than one will result in undefined behavior.
110 # [PRETTY_NAME string]
111 # If passed, use this name when naming the extension in mesages. If this is
112 # not passed, default to NAME.
114 # [IS_ENABLED VARNAME]
115 # If the parameter passed is defined, and has a trueish value,
116 # then the extension will be enabled. This is only used to maintain
117 # backwards compatibility with existing options. All other
118 # extensions can be enabled or disabled with ENABLE_EXTENSION_*.
119 # The ENABLE_EXTENSION_* variables will also be defined for the source
120 # code so that fallbacks may be used where needed.
122 # [SOURCES ...]
123 # The source files of the extension
125 # [HEADERS ...]
126 # The header files of the extension
128 # [SYSTEMLIB ...]
129 # The PHP API of the extension.
131 # [DEPENDS ...]
132 # The dependencies of the extension. Extensions are prefixed
133 # with "ext_", and external libaries with "lib".
134 # "systemlib" is a special dependency that represents the
135 # systemlib header.
137 # A dependency may optionally be followed by "OPTIONAL", which
138 # means that the build won't fail if the dependency is not found.
140 # Dependencies prefixed with "os" represent the OS required to
141 # build the extension. The only valid value for this currently
142 # is osPosix, which represents everything with a valid posix
143 # API, which is most everything except for Windows.
145 # Dependencies prefixed with "var" represent a CMake variable
146 # which must evaluate to a trueish value for the extension to
147 # be enabled. If the value isn't defined, it is assumed to be
148 # false.
150 # If there is a space in an argument with a string in it, and
151 # the argument is a library, the exact version of the library
152 # required is expected to be the second part of the string.
153 # For example, "libFribidi 0.19.6" would require the Fribidi
154 # package to be exactly version 0.19.6.
156 # For libBoost, a single component is expected to be specified
157 # by appending a -componentName to the value, for example
158 # libBoost-variant would require the variant component of libBoost.
159 # This is only required if a library needs to be linked against.
160 # If a boost component is a headers-only library, libBoost is
161 # enough of a dependency.
163 # Note that libFolly is currently a dependency of everything
164 # for the sanity of the Windows port.
165 function(HHVM_DEFINE_EXTENSION extNameIn)
166   if (NOT DEFINED HHVM_EXTENSION_COUNT)
167     set(HHVM_EXTENSION_COUNT 0)
168   endif()
170   set(extensionName "")
171   set(extensionPrettyName "")
172   set(extensionRequired OFF)
173   # If WANTED is specified, then the extension must be explicitly disabled
174   # If IMPLICIT is specified, then the extension will be implicitly disabled
175   # when the dependencies are not found
176   # If neither is specified, we default to WANTED anyway
177   set(extensionEnabledState 4)
178   set(extensionSources)
179   set(extensionHeaders)
180   set(extensionLibrary)
181   set(extensionDependencies)
182   set(extensionDependenciesOptional)
184   # Make sure there are no spaces.
185   string(FIND ${extNameIn} " " extNameSpace)
186   if (NOT ${extNameSpace} EQUAL -1)
187     message(FATAL_ERROR "An extension name cannot have a space in it! Got name '${extNameIn}'.")
188   endif()
190   # Make sure another extension with the same hasn't already
191   # been defined.
192   set(i 0)
193   while (i LESS HHVM_EXTENSION_COUNT)
194     if (${HHVM_EXTENSION_${i}_NAME} STREQUAL ${extNameIn})
195       message(FATAL_ERROR "An extension with the name '${extNameIn}' has already been defined!")
196     endif()
197     math(EXPR i "${i} + 1")
198   endwhile()
199   set(extensionName ${extNameIn})
200   set(extensionPrettyName ${extensionName})
202   set(argumentState 0)
203   foreach (arg ${ARGN})
204     if ("x${arg}" STREQUAL "xPRETTY_NAME")
205       set(argumentState 1)
206     elseif ("x${arg}" STREQUAL "xIS_ENABLED")
207       set(argumentState 2)
208     elseif ("x${arg}" STREQUAL "xSOURCES")
209       set(argumentState 3)
210     elseif ("x${arg}" STREQUAL "xHEADERS")
211       set(argumentState 4)
212     elseif ("x${arg}" STREQUAL "xSYSTEMLIB")
213       set(argumentState 5)
214     elseif ("x${arg}" STREQUAL "xDEPENDS")
215       set(argumentState 7)
216     elseif ("x${arg}" STREQUAL "xREQUIRED")
217       if (NOT ${argumentState} EQUAL 0)
218         message(FATAL_ERROR "The REQUIRED modifier should only be placed immediately after the extension's name! (while processing the '${extensionPrettyName}' extension)")
219       endif()
220       set(extensionRequired ON)
221     elseif ("x${arg}" STREQUAL "xIMPLICIT")
222       if (NOT ${argumentState} EQUAL 0)
223         message(FATAL_ERROR "The IMPLICIT modifier should only be placed immediately after the extension's name! (while processing the '${extensionPrettyName}' extension)")
224       endif()
225       set(extensionEnabledState 0)
226     elseif ("x${arg}" STREQUAL "xWANTED")
227       if (NOT ${argumentState} EQUAL 0)
228         message(FATAL_ERROR "The WANTED modifier should only be placed immediately after the extension's name! (while processing the '${extensionPrettyName}' extension)")
229       endif()
230       set(extensionEnabledState 4)
231     elseif ("x${arg}" STREQUAL "xOPTIONAL")
232       if (${argumentState} EQUAL 7)
233         list(LENGTH extensionDependenciesOptional optDepLen)
234         math(EXPR optDepLen "${optDepLen} - 1")
235         list(REMOVE_AT extensionDependenciesOptional ${optDepLen})
236         list(APPEND extensionDependenciesOptional ON)
237       else()
238         message(FATAL_ERROR "The OPTIONAL modifier is only currently valid in the DEPENDS section of extension '${extensionPrettyName}'!")
239       endif()
240     elseif (${argumentState} EQUAL 0)
241       message(FATAL_ERROR "Unknown argument '${arg}' while processing extension '${extensionPrettyName}'!")
242     elseif (${argumentState} EQUAL 1)
243       # PRETTY_NAME
244       set(extensionPrettyName ${arg})
245       set(argumentState 0)
246     elseif (${argumentState} EQUAL 2)
247       # IS_ENABLED
248       if (DEFINED ${arg})
249         if (${${arg}})
250           set(extensionEnabledState 3)
251         else()
252           set(extensionEnabledState 2)
253         endif()
254       endif()
255       set(argumentState 0)
256     elseif (${argumentState} EQUAL 3)
257       # SOURCES
258       list(FIND extensionSources ${arg} listIDX)
259       if (NOT ${listIDX} EQUAL -1)
260         message(FATAL_ERROR "The file '${arg}' was already specified as a source of '${extensionPrettyName}'!")
261       endif()
262       list(APPEND extensionSources ${arg})
263     elseif (${argumentState} EQUAL 4)
264       # HEADERS
265       list(FIND extensionHeaders ${arg} listIDX)
266       if (NOT ${listIDX} EQUAL -1)
267         message(FATAL_ERROR "The file '${arg}' was already specified as a header of '${extensionPrettyName}'!")
268       endif()
269       list(APPEND extensionHeaders ${arg})
270     elseif (${argumentState} EQUAL 5)
271       # SYSTEMLIB
272       list(FIND extensionLibrary ${arg} listIDX)
273       if (NOT ${listIDX} EQUAL -1)
274         message(FATAL_ERROR "The file '${arg}' was already specified as part of the library of '${extensionPrettyName}'!")
275       endif()
276       list(APPEND extensionLibrary ${arg})
277     elseif (${argumentState} EQUAL 7)
278       # DEPENDS
279       list(FIND extensionDependencies ${arg} listIDX)
280       if (NOT ${listIDX} EQUAL -1)
281         message(FATAL_ERROR "'${arg}' was already specified as a dependency of '${extensionPrettyName}'!")
282       endif()
283       list(APPEND extensionDependencies ${arg})
284       list(APPEND extensionDependenciesOptional OFF)
285     else()
286       message(FATAL_ERROR "An error occurred while processing the arguments of the '${extensionPrettyName}' extension!")
287     endif()
288   endforeach()
290   # Check if the extension has been explicitly enabled or disabled.
291   string(TOUPPER ${extensionName} upperExtName)
292   if (DEFINED ENABLE_EXTENSION_${upperExtName})
293     if (${ENABLE_EXTENSION_${upperExtName}})
294       set(extensionEnabledState 3)
295     elseif (${extensionRequired})
296       message(WARNING "Attempt to explicitly disable the required extension '${extensionPrettyName}' by setting 'ENABLE_EXTENSION_${upperExtName}' was ignored.")
297     else()
298       set(extensionEnabledState 2)
299     endif()
300   endif()
302   # Increment the extension count.
303   set(extensionID ${HHVM_EXTENSION_COUNT})
304   math(EXPR newCount "${HHVM_EXTENSION_COUNT} + 1")
305   set(HHVM_EXTENSION_COUNT ${newCount} PARENT_SCOPE)
307   # And lastly, export the globals.
308   # We put these in the cache to make debugging easier.
309   # The only one that absolutely has to be in the cache is
310   # the ENABLED_STATE, due to it's modification from fairly
311   # arbitrary scope depths. HHVM_EXTENSION_COUNT must NEVER
312   # be in the cache, otherwise this will break.
313   set(HHVM_EXTENSION_${extensionID}_NAME ${extensionName} CACHE INTERNAL "" FORCE)
314   set(HHVM_EXTENSION_${extensionID}_PRETTY_NAME ${extensionPrettyName} CACHE INTERNAL "" FORCE)
315   set(HHVM_EXTENSION_${extensionID}_REQUIRED ${extensionRequired} CACHE INTERNAL "" FORCE)
316   set(HHVM_EXTENSION_${extensionID}_ROOT_DIR ${HRE_CURRENT_EXT_PATH} CACHE INTERNAL "" FORCE)
317   set(HHVM_EXTENSION_${extensionID}_ENABLED_STATE ${extensionEnabledState} CACHE INTERNAL "" FORCE)
318   set(HHVM_EXTENSION_${extensionID}_SOURCE_FILES ${extensionSources} CACHE INTERNAL "" FORCE)
319   set(HHVM_EXTENSION_${extensionID}_HEADER_FILES ${extensionHeaders} CACHE INTERNAL "" FORCE)
320   set(HHVM_EXTENSION_${extensionID}_SYSTEMLIB ${extensionLibrary} CACHE INTERNAL "" FORCE)
321   set(HHVM_EXTENSION_${extensionID}_DEPENDENCIES ${extensionDependencies} CACHE INTERNAL "" FORCE)
322   set(HHVM_EXTENSION_${extensionID}_DEPENDENCIES_OPTIONAL ${extensionDependenciesOptional} CACHE INTERNAL "" FORCE)
323 endfunction()
325 # Call after all of the calls to HHVM_DEFINE_EXTENSION are complete.
327 # This will also add the appropriate libraries, include directories, and
328 # defines for the enabled extensions' dependencies.
329 function(HHVM_EXTENSION_RESOLVE_DEPENDENCIES)
330   set(HHVM_EXTENSIONS_REQUIRED_LIBRARIES "" CACHE INTERNAL "" FORCE)
331   set(HHVM_EXTENSIONS_REQUIRED_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
332   set(HHVM_EXTENSIONS_REQUIRED_DEFINES "" CACHE INTERNAL "" FORCE)
333   set(i 0)
334   while (i LESS HHVM_EXTENSION_COUNT)
335     HHVM_EXTENSION_INTERNAL_RESOLVE_DEPENDENCIES_OF_EXTENSION(wasResolved ${i} " ")
336     string(TOUPPER ${HHVM_EXTENSION_${i}_NAME} upperExtName)
337     if (${wasResolved} EQUAL 1)
338       message(STATUS "Building the ${HHVM_EXTENSION_${i}_PRETTY_NAME} extension.")
340       # Now we need to make sure the dependencies are included and linked in
341       # correctly.
342       set(i2 0)
343       list(LENGTH HHVM_EXTENSION_${i}_DEPENDENCIES depCount)
344       while (i2 LESS depCount)
345         list(GET HHVM_EXTENSION_${i}_DEPENDENCIES ${i2} currentDependency)
346         string(FIND ${currentDependency} "lib" libIdx)
347         if (${libIdx} EQUAL 0)
348           HHVM_EXTENSION_INTERNAL_HANDLE_LIBRARY_DEPENDENCY(${i} ${currentDependency} ON)
349         endif()
350         math(EXPR i2 "${i2} + 1")
351       endwhile()
353       if (HHVM_EXTENSION_${i}_REQUIRED)
354         set(ENABLE_EXTENSION_${upperExtName} ON CACHE INTERNAL "Enable the ${HHVM_EXTENSION_${i}_PRETTY_NAME} extension.")
355       else()
356         set(ENABLE_EXTENSION_${upperExtName} ON CACHE BOOL "Enable the ${HHVM_EXTENSION_${i}_PRETTY_NAME} extension.")
357       endif()
358     else()
359       if (HHVM_EXTENSION_${i}_REQUIRED)
360         message(FATAL_ERROR "Failed to resolve a dependency of the ${HHVM_EXTENSION_${i}_PRETTY_NAME} extension, which is a required extension!")
361       endif()
362       message("Not building the ${HHVM_EXTENSION_${i}_PRETTY_NAME} extension.")
363       set(ENABLE_EXTENSION_${upperExtName} OFF CACHE BOOL "Enable the ${HHVM_EXTENSION_${i}_PRETTY_NAME} extension.")
364     endif()
365     math(EXPR i "${i} + 1")
366   endwhile()
367 endfunction()
369 # This will append the files of the enabled extensions to the following variables:
370 # C_SOURCES: C Source Files
371 # CXX_SOURCES: C++ Source Files
372 # HEADER_SOURCES: C/C++ Header Files
373 # ASM_SOURCES: asm source files appropriate for the current compiler.
374 # PHP_SOURCES: PHP files representing the various extensions' systemlib.
375 function (HHVM_EXTENSION_BUILD_SOURCE_LISTS)
376   set(i 0)
377   while (i LESS HHVM_EXTENSION_COUNT)
378     if (${HHVM_EXTENSION_${i}_ENABLED_STATE} EQUAL 1)
379       HHVM_EXTENSION_INTERNAL_SORT_OUT_SOURCES(${HHVM_EXTENSION_${i}_ROOT_DIR}
380         ${HHVM_EXTENSION_${i}_SOURCE_FILES}
381         ${HHVM_EXTENSION_${i}_HEADER_FILES}
382         ${HHVM_EXTENSION_${i}_SYSTEMLIB}
383       )
384     endif()
385     math(EXPR i "${i} + 1")
386   endwhile()
388   # Propagate the extra files to the parent scope.
389   set(C_SOURCES ${C_SOURCES} PARENT_SCOPE)
390   set(CXX_SOURCES ${CXX_SOURCES} PARENT_SCOPE)
391   set(HEADER_SOURCES ${HEADER_SOURCES} PARENT_SCOPE)
392   set(ASM_SOURCES ${ASM_SOURCES} PARENT_SCOPE)
393   set(PHP_SOURCES ${PHP_SOURCES} PARENT_SCOPE)
394 endfunction()
396 # Sort out all the files into their appropriate variable, as well as transform the paths
397 # to their fully-resolved forms.
398 function (HHVM_EXTENSION_INTERNAL_SORT_OUT_SOURCES rootDir)
399   foreach (fileName ${ARGN})
400     string(LENGTH ${fileName} fileNameLength)
401     string(FIND ${fileName} "." dotPos REVERSE)
402     if (${dotPos} EQUAL -1)
403       message(FATAL_ERROR "No extension on file '${fileName}'!")
404     endif()
405     math(EXPR endPos "${fileNameLength} - ${dotPos}")
406     string(SUBSTRING ${fileName} ${dotPos} ${endPos} fileExtension)
407     string(TOLOWER ${fileExtension} fileExtension)
408     if (${fileExtension} STREQUAL ".c")
409       list(APPEND C_SOURCES "${rootDir}/${fileName}")
410     elseif (${fileExtension} STREQUAL ".cpp" OR ${fileExtension} STREQUAL ".cxx" OR ${fileExtension} STREQUAL ".cc")
411       list(APPEND CXX_SOURCES "${rootDir}/${fileName}")
412     elseif (${fileExtension} STREQUAL ".h" OR ${fileExtension} STREQUAL ".hpp")
413       list(APPEND HEADER_SOURCES "${rootDir}/${fileName}")
414     elseif (${fileExtension} STREQUAL ".s")
415       # AT&T syntax, MSVC doesn't like.
416       if (NOT MSVC)
417         list(APPEND ASM_SOURCES "${rootDir}/${fileName}")
418       endif()
419     elseif (${fileExtension} STREQUAL ".asm")
420       # MASM syntax. MSVC only.
421       if (MSVC)
422         list(APPEND ASM_SOURCES "${rootDir}/${fileName}")
423       endif()
424     elseif (${fileExtension} STREQUAL ".php")
425       list(APPEND PHP_SOURCES "${rootDir}/${fileName}")
426     else()
427       message(FATAL_ERROR "Unknown file extension '${fileExtension}'!")
428     endif()
429   endforeach()
430   set(C_SOURCES ${C_SOURCES} PARENT_SCOPE)
431   set(CXX_SOURCES ${CXX_SOURCES} PARENT_SCOPE)
432   set(HEADER_SOURCES ${HEADER_SOURCES} PARENT_SCOPE)
433   set(ASM_SOURCES ${ASM_SOURCES} PARENT_SCOPE)
434   set(PHP_SOURCES ${PHP_SOURCES} PARENT_SCOPE)
435 endfunction()
437 # Configure the specified target so that it can compile when
438 # linked against the enabled extensions.
439 function(HHVM_CONFIGURE_TARGET_FOR_EXTENSION_DEPENDENCIES targetName)
440   target_link_libraries(${targetName} ${HHVM_EXTENSIONS_REQUIRED_LIBRARIES})
441   target_include_directories(${targetName} PUBLIC ${HHVM_EXTENSIONS_REQUIRED_INCLUDE_DIRS})
442   target_compile_definitions(${targetName} PUBLIC ${HHVM_EXTENSIONS_REQUIRED_DEFINES})
443 endfunction()
446 # Resolve the dependencies of the specified extension, and update it's enabled state.
447 function(HHVM_EXTENSION_INTERNAL_RESOLVE_DEPENDENCIES_OF_EXTENSION resolvedDestVar extensionID)
448   # If already resolved, return that state.
449   if (NOT HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 0 AND
450       NOT HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 3 AND
451       NOT HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 4)
452     set(${resolvedDestVar} ${HHVM_EXTENSION_${extensionID}_ENABLED_STATE} PARENT_SCOPE)
453     return()
454   endif()
456   # If already in resolution stack, it's a circular dependency,
457   # assume for now that it's enabled.
458   list(FIND HHVM_EXTENSION_RESOLUTION_STACK ${HHVM_EXTENSION_${extensionID}_NAME} resIDX)
459   if (NOT ${resIDX} EQUAL -1)
460     set(${resolvedDestVar} 1 PARENT_SCOPE)
461     return()
462   endif()
464   # Go through the dependencies, checking each one recursively in turn.
465   list(LENGTH HHVM_EXTENSION_${extensionID}_DEPENDENCIES depCount)
466   set(i 0)
467   while (i LESS depCount)
468     list(GET HHVM_EXTENSION_${extensionID}_DEPENDENCIES ${i} currentDependency)
470     string(FIND ${currentDependency} "lib" listIDX)
471     if (${listIDX} EQUAL 0)
472       # Library Dependency
473       HHVM_EXTENSION_INTERNAL_HANDLE_LIBRARY_DEPENDENCY(${extensionID} ${currentDependency} OFF)
474       if (HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 2)
475         break()
476       endif()
477     else()
478       string(FIND ${currentDependency} "var" listIDX)
479       if (${listIDX} EQUAL 0)
480         # CMake Variable Dependency
481         string(LENGTH ${currentDependency} depLength)
482         math(EXPR depLength "${depLength} - 3")
483         string(SUBSTRING ${currentDependency} 3 ${depLength} varName)
484         if (DEFINED ${varName})
485           if (NOT ${${varName}})
486             HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${currentDependency} ON)
487             break()
488           endif()
489         else()
490           HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${currentDependency} ON)
491           break()
492         endif()
493       else()
494         string(FIND ${currentDependency} "os" listIDX)
495         if (${listIDX} EQUAL 0)
496           # OS Dependency
497           if (${currentDependency} STREQUAL "osPosix")
498             if (MSVC)
499               HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${currentDependency} ON)
500               break()
501             endif()
502           else()
503             message(FATAL_ERROR "The only OS restriction that is currently valid is 'osPosix', got '${currentDependency}'!")
504           endif()
505         elseif (${currentDependency} STREQUAL "systemlib")
506           # TODO: Mark this somehow?
507         else()
508           message(FATAL_ERROR "Unknown dependency '${currentDependency}' for extension '${HHVM_EXTENSION_${extensionID}_PRETTY_NAME}'!")
509         endif()
510       endif()
511     endif()
513     math(EXPR i "${i} + 1")
514   endwhile()
516   if (HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 0 OR
517       HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 3 OR
518       HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 4)
519     set(HHVM_EXTENSION_${extensionID}_ENABLED_STATE 1 CACHE INTERNAL "" FORCE)
520   endif()
521   set(${resolvedDestVar} ${HHVM_EXTENSION_${extensionID}_ENABLED_STATE} PARENT_SCOPE)
522 endfunction()
524 # Set that an extension was disabled because of the specified dependency not being
525 # possible to resolve.
526 # This optionally takes a third BOOL parameter that should be set to ON only if the
527 # dependency that failed to resolve is an os* or var* dependency.
528 function(HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY extensionID failedDependency)
529   list(FIND HHVM_EXTENSION_${extensionID}_DEPENDENCIES ${failedDependency} depIdx)
530   if (depIdx EQUAL -1)
531     message(FATAL_ERROR "An issue occured while processing the '${failedDependency}' dependency of the ${HHVM_EXTENSION_${extensionID}_PRETTY_NAME} extension!")
532   endif()
533   list(GET HHVM_EXTENSION_${extensionID}_DEPENDENCIES_OPTIONAL ${depIdx} isOptional)
535   if (NOT ${isOptional})
536     if (${HHVM_EXTENSION_${extensionID}_ENABLED_STATE} EQUAL 4 AND (NOT ${ARGC} EQUAL 3 OR NOT "${ARGV2}" STREQUAL "ON"))
537       message(FATAL_ERROR "The ${HHVM_EXTENSION_${extensionID}_PRETTY_NAME} extension is an extension you probably want, but resolving the dependency '${failedDependency}' failed!")
538     elseif (${HHVM_EXTENSION_${extensionID}_ENABLED_STATE} EQUAL 3)
539       message(FATAL_ERROR "The ${HHVM_EXTENSION_${extensionID}_PRETTY_NAME} extension was forcefully enabled, but resolving the dependency '${failedDependency}' failed!")
540     elseif (${HHVM_EXTENSION_${extensionID}_ENABLED_STATE} EQUAL 1)
541       # Currently only triggers for issues with find_package when applying the library dependencies.
542       message(FATAL_ERROR "An error occurred while applying the '${failedDependency}' dependency of the ${HHVM_EXTENSION_${extensionID}_PRETTY_NAME} extension!")
543     endif()
544     message(STATUS "The ${HHVM_EXTENSION_${extensionID}_PRETTY_NAME} extension was disabled because resolving the dependency '${failedDependency}' failed.")
545     set(HHVM_EXTENSION_${extensionID}_ENABLED_STATE 2 CACHE INTERNAL "" FORCE)
546   endif()
547 endfunction()
549 # Add a set of libraries to link against.
550 function(HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES)
551   set(reqLibs ${HHVM_EXTENSIONS_REQUIRED_LIBRARIES})
552   foreach (lib ${ARGN})
553     list(APPEND reqLibs ${lib})
554   endforeach()
555   set(HHVM_EXTENSIONS_REQUIRED_LIBRARIES ${reqLibs} CACHE INTERNAL "" FORCE)
556 endfunction()
558 # Add a set of include directories to use.
559 function(HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS)
560   set(incDirs ${HHVM_EXTENSIONS_REQUIRED_INCLUDE_DIRS})
561   foreach (inc ${ARGN})
562     list(APPEND incDirs ${inc})
563   endforeach()
564   set(HHVM_EXTENSIONS_REQUIRED_INCLUDE_DIRS ${incDirs} CACHE INTERNAL "" FORCE)
565 endfunction()
567 # Add a set of defines to use when compiling.
568 function(HHVM_EXTENSION_INTERNAL_ADD_DEFINES)
569   set(defs ${HHVM_EXTENSIONS_REQUIRED_DEFINES})
570   foreach (def ${ARGN})
571     list(APPEND defs ${def})
572   endforeach()
573   set(HHVM_EXTENSIONS_REQUIRED_DEFINES ${defs} CACHE INTERNAL "" FORCE)
574 endfunction()
576 # This handles all the library dependencies, and determines if the libraries are present.
577 function (HHVM_EXTENSION_INTERNAL_HANDLE_LIBRARY_DEPENDENCY extensionID dependencyName addPaths)
578   string(FIND ${dependencyName} "lib" libIdx)
579   if (NOT libIdx EQUAL 0)
580     message(FATAL_ERROR "Non-library dependency '${dependencyName}' passed to HHVM_EXTENSION_INTERNAL_HANDLE_LIBRARY_DEPENDENCY!")
581   endif()
583   set(requiredVersion)
584   string(LENGTH ${dependencyName} depLength)
585   math(EXPR depLength "${depLength} - 3")
586   string(SUBSTRING ${dependencyName} 3 ${depLength} originalLibraryName)
587   string(FIND ${originalLibraryName} " " spaceIDX)
588   if (NOT ${spaceIDX} EQUAL -1)
589     math(EXPR spaceIDX "${spaceIDX} + 1")
590     string(LENGTH ${originalLibraryName} libNameLength)
591     math(EXPR libNameLength "${libNameLength} - ${spaceIDX}")
592     string(SUBSTRING ${originalLibraryName} ${spaceIDX} ${libNameLength} requiredVersion)
593     math(EXPR spaceIDX "${spaceIDX} - 1")
594     string(SUBSTRING ${originalLibraryName} 0 ${spaceIDX} originalLibraryName)
595   endif()
596   string(TOLOWER ${originalLibraryName} libraryName)
598   # This first check is for libraries that are used by default
599   # Keep these in alphabetical order.
600   if (
601     ${libraryName} STREQUAL "boost" OR
602     ${libraryName} STREQUAL "editline" OR
603     ${libraryName} STREQUAL "fastlz" OR
604     ${libraryName} STREQUAL "folly" OR
605     ${libraryName} STREQUAL "lz4" OR
606     ${libraryName} STREQUAL "mbfl" OR
607     ${libraryName} STREQUAL "mcrouter" OR
608     ${libraryName} STREQUAL "oniguruma" OR
609     ${libraryName} STREQUAL "openssl" OR
610     ${libraryName} STREQUAL "pcre" OR
611     ${libraryName} STREQUAL "readline" OR
612     ${libraryName} STREQUAL "sqlite" OR
613     ${libraryName} STREQUAL "squangle" OR
614     ${libraryName} STREQUAL "webscalesql" OR
615     ${libraryName} STREQUAL "zip" OR
616     ${libraryName} STREQUAL "zlib"
617   )
618     # Nothing to do, they are included by default.
619   elseif (${libraryName} STREQUAL "bzip2")
620     find_package(BZip2 ${requiredVersion})
621     find_package(EXPAT ${requiredVersion})
622     if (NOT BZIP2_INCLUDE_DIR OR NOT BZIP2_LIBRARIES)
623       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
624       return()
625     endif()
627     if (${addPaths})
628       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${BZIP2_INCLUDE_DIR})
629       HHVM_EXTENSION_INTERNAL_ADD_DEFINES(${BZIP2_DEFINITIONS})
630       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${BZIP2_LIBRARIES})
631       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBBZIP2")
632     endif()
633   elseif (${libraryName} STREQUAL "cclient")
634     find_package(CClient ${requiredVersion})
635     if (NOT CCLIENT_INCLUDE_PATH OR NOT CCLIENT_LIBRARY)
636       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
637       return()
638     endif()
640     CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/utf8.h" U8T_DECOMPOSE RECENT_CCLIENT)
641     if (NOT RECENT_CCLIENT)
642       unset(RECENT_CCLIENT CACHE)
643       if (${addPaths})
644         message(FATAL_ERROR "Your version of c-client is too old, you need 2007")
645       else()
646         message(STATUS "Your version of c-client is too old, you need 2007")
647         HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
648         return()
649       endif()
650     endif()
652     if (${addPaths})
653       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${CCLIENT_INCLUDE_PATH})
654       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${CCLIENT_LIBRARY})
655       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBCCLIENT")
657       if (EXISTS "${CCLIENT_INCLUDE_PATH}/linkage.c")
658         CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/linkage.c" auth_gss CCLIENT_HAS_GSS)
659       elseif (EXISTS "${CCLIENT_INCLUDE_PATH}/linkage.h")
660         CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/linkage.h" auth_gss CCLIENT_HAS_GSS)
661       endif()
662       if (NOT CCLIENT_HAS_GSS)
663         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DSKIP_IMAP_GSS=1")
664       endif()
666       if (EXISTS "${CCLIENT_INCLUDE_PATH}/linkage.c")
667         CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/linkage.c" ssl_onceonlyinit CCLIENT_HAS_SSL)
668       elseif (EXISTS "${CCLIENT_INCLUDE_PATH}/linkage.h")
669         CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/linkage.h" ssl_onceonlyinit CCLIENT_HAS_SSL)
670       endif()
671       if (NOT CCLIENT_HAS_SSL)
672         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DSKIP_IMAP_SSL=1")
673       endif()
674     endif()
675   elseif (${libraryName} STREQUAL "curl")
676     find_package(CURL ${requiredVersion})
677     if (NOT CURL_INCLUDE_DIR OR NOT CURL_LIBRARIES)
678       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
679       return()
680     endif()
682     if (${addPaths})
683       set(CMAKE_REQUIRED_LIBRARIES "${CURL_LIBRARIES}")
684       set(CMAKE_REQUIRED_INCLUDES "${CURL_INCLUDE_DIR}")
685       CHECK_FUNCTION_EXISTS("curl_multi_select" HAVE_CURL_MULTI_SELECT)
686       CHECK_FUNCTION_EXISTS("curl_multi_wait" HAVE_CURL_MULTI_WAIT)
687       if (HAVE_CURL_MULTI_SELECT)
688         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_CURL_MULTI_SELECT")
689       endif()
690       if (HAVE_CURL_MULTI_WAIT)
691         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_CURL_MULTI_WAIT")
692       endif()
693       set(CMAKE_REQUIRED_LIBRARIES)
694       set(CMAKE_REQUIRED_INCLUDES)
696       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${CURL_INCLUDE_DIR})
697       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${CURL_LIBRARIES})
698       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBCURL")
699     endif()
700   elseif (${libraryName} STREQUAL "expat")
701     find_package(EXPAT ${requiredVersion})
702     if (NOT EXPAT_INCLUDE_DIRS OR NOT EXPAT_LIBRARY)
703       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
704       return()
705     endif()
707     if (${addPaths})
708       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${EXPAT_INCLUDE_DIRS})
709       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${EXPAT_LIBRARY})
710       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBEXPAT")
711       if (EXPAT_STATIC)
712         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DXML_STATIC")
713       endif()
714     endif()
715   elseif (${libraryName} STREQUAL "freetype")
716     find_package(Freetype ${requiredVersion})
717     if (NOT FREETYPE_INCLUDE_DIRS OR NOT FREETYPE_LIBRARIES)
718       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
719       return()
720     endif()
722     if (${addPaths})
723       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${FREETYPE_INCLUDE_DIRS})
724       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${FREETYPE_LIBRARIES})
725       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBFREETYPE")
726       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_GD_FREETYPE")
727       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DENABLE_GD_TTF")
728     endif()
729   elseif (${libraryName} STREQUAL "fribidi")
730     find_package(fribidi ${requiredVersion})
731     if (NOT FRIBIDI_INCLUDE_DIR OR NOT FRIBIDI_LIBRARY)
732       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
733       return()
734     endif()
736     if (${addPaths})
737       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${FRIBIDI_INCLUDE_DIR})
738       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${FRIBIDI_LIBRARY})
739       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBFRIBIDI")
740     endif()
741   elseif (${libraryName} STREQUAL "glib")
742     find_package(GLIB ${requiredVersion})
743     if (NOT GLIB_INCLUDE_DIR OR NOT GLIB_CONFIG_INCLUDE_DIR)
744       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
745       return()
746     endif()
748     if (${addPaths})
749       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${GLIB_INCLUDE_DIR} ${GLIB_CONFIG_INCLUDE_DIR})
750       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBGLIB")
751     endif()
752   elseif (${libraryName} STREQUAL "gmp")
753     find_package(LibGmp ${requiredVersion})
754     if (NOT GMP_INCLUDE_DIR OR NOT GMP_LIBRARY)
755       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
756       return()
757     endif()
759     if (${addPaths})
760       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${GMP_INCLUDE_DIR})
761       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${GMP_LIBRARY})
762       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBGMP")
763     endif()
764   elseif (${libraryName} STREQUAL "iconv")
765     find_package(Libiconv ${requiredVersion})
766     if (NOT LIBICONV_INCLUDE_DIR)
767       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
768       return()
769     endif()
771     if (${addPaths})
772       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBICONV_INCLUDE_DIR})
773       if (LIBICONV_LIBRARY)
774         HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBICONV_LIBRARY})
775       endif()
776       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_ICONV")
777       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBICONV")
778       if (LIBICONV_CONST)
779         message(STATUS "Using const for input to iconv() call")
780         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DICONV_CONST=const")
781       endif()
782     endif()
783   elseif (${libraryName} STREQUAL "icu")
784     find_package(ICU ${requiredVersion})
785     if (NOT ICU_FOUND OR NOT ICU_DATA_LIBRARIES OR NOT ICU_I18N_LIBRARIES OR NOT ICU_LIBRARIES)
786       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
787       return()
788     endif()
790     if (ICU_VERSION VERSION_LESS "4.2")
791       unset(ICU_FOUND CACHE)
792       unset(ICU_INCLUDE_DIRS CACHE)
793       unset(ICU_LIBRARIES CACHE)
794       if (${addPaths})
795         message(FATAL_ERROR "ICU is too old, found ${ICU_VERSION} and we need 4.2")
796       else()
797         message(STATUS "ICU is too old, found ${ICU_VERSION} and we need 4.2")
798         HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
799         return()
800       endif()
801     endif ()
803     if (${addPaths})
804       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${ICU_INCLUDE_DIRS})
805       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${ICU_DATA_LIBRARIES} ${ICU_I18N_LIBRARIES} ${ICU_LIBRARIES})
806       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBICU")
807     endif()
808   elseif (${libraryName} STREQUAL "intl")
809     find_package(LibIntl ${requiredVersion})
810     if (NOT LIBINTL_INCLUDE_DIRS)
811       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
812       return()
813     endif()
815     if (${addPaths})
816       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBINTL_INCLUDE_DIRS})
817       if (LIBINTL_LIBRARIES)
818         HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBINTL_LIBRARIES})
819       endif()
820       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBINTL")
821     endif()
822   elseif (${libraryName} STREQUAL "jpeg")
823     find_package(LibJpeg ${requiredVersion})
824     if (NOT LIBJPEG_INCLUDE_DIRS OR NOT LIBJPEG_LIBRARIES)
825       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
826       return()
827     endif()
829     if (${addPaths})
830       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBJPEG_INCLUDE_DIRS})
831       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBJPEG_LIBRARIES})
832       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBJPEG")
833       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_GD_JPG")
834     endif()
835   elseif (${libraryName} STREQUAL "jsonc")
836     find_package(Libjsonc ${requiredVersion})
837     if (NOT LIBJSONC_INCLUDE_DIR OR NOT LIBJSONC_LIBRARY)
838       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
839       return()
840     endif()
842     if (${addPaths})
843       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBJSONC_INCLUDE_DIR})
844       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBJSONC_LIBRARY})
845       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBJSONC")
846     endif()
847   elseif (${libraryName} STREQUAL "ldap")
848     find_package(Ldap ${requiredVersion})
849     if (NOT LDAP_INCLUDE_DIR OR NOT LDAP_LIBRARIES)
850       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
851       return()
852     endif()
854     if (${addPaths})
855       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LDAP_INCLUDE_DIR})
856       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LDAP_LIBRARIES})
857       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBLDAP")
858     endif()
859   elseif (${libraryName} STREQUAL "magickwand")
860     find_package(LibMagickWand ${requiredVersion})
861     if (NOT LIBMAGICKWAND_INCLUDE_DIRS OR NOT LIBMAGICKWAND_LIBRARIES OR NOT LIBMAGICKCORE_LIBRARIES)
862       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
863       return()
864     endif()
866     if (${addPaths})
867       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBMAGICKWAND_INCLUDE_DIRS})
868       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBMAGICKWAND_LIBRARIES} ${LIBMAGICKCORE_LIBRARIES})
869       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBMAGICKWAND")
870     endif()
871   elseif (${libraryName} STREQUAL "mcrypt")
872     find_package(Mcrypt ${requiredVersion})
873     if (NOT Mcrypt_INCLUDE_DIR OR NOT Mcrypt_LIB)
874       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
875       return()
876     endif()
878     if (${addPaths})
879       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${Mcrypt_INCLUDE_DIR})
880       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${Mcrypt_LIB})
881       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBMCRYPT")
882     endif()
883   elseif (${libraryName} STREQUAL "memcached")
884     find_package(Libmemcached ${requiredVersion})
885     if (NOT LIBMEMCACHED_INCLUDE_DIR OR NOT LIBMEMCACHED_LIBRARY)
886       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
887       return()
888     endif()
890     if (LIBMEMCACHED_VERSION VERSION_LESS "0.39")
891       unset(LIBMEMCACHED_INCLUDE_DIR CACHE)
892       unset(LIBMEMCACHED_LIBRARY CACHE)
893       unset(LIBMEMCACHED_VERSION CACHE)
894       if (${addPaths})
895         message(FATAL_ERROR "libmemcached is too old, found ${LIBMEMCACHED_VERSION} and we need 0.39")
896       else()
897         message(STATUS "libmemcached is too old, found ${LIBMEMCACHED_VERSION} and we need 0.39")
898         HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
899         return()
900       endif()
901     endif()
903     if (${addPaths})
904       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBMEMCACHED_INCLUDE_DIR})
905       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBMEMCACHED_LIBRARY})
906       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBMEMCACHED")
907     endif()
908   elseif (${libraryName} STREQUAL "mysql")
909     # mysql checks - if we're using async mysql, we use webscalesqlclient from
910     # third-party/ instead
911     if (ENABLE_ASYNC_MYSQL)
912       set(MYSQL_CLIENT_LIB_DIR ${TP_DIR}/webscalesqlclient/src/)
913       set(MYSQL_CLIENT_LIBS
914         ${MYSQL_CLIENT_LIB_DIR}/libmysql/libfbmysqlclient_r.a
915       )
917       if (${addPaths})
918         HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(
919           ${RE2_INCLUDE_DIR}
920           ${TP_DIR}/squangle/src/
921           ${TP_DIR}/webscalesqlclient/src/include/
922         )
923         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DENABLE_ASYNC_MYSQL=1")
924       endif()
925     else()
926       find_package(MySQL ${requiredVersion})
927       if (NOT MYSQL_LIB_DIR OR NOT MYSQL_INCLUDE_DIR OR NOT MYSQL_CLIENT_LIBS)
928         HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
929         return()
930       endif()
932       if (${addPaths})
933         link_directories(${MYSQL_LIB_DIR})
934         HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${MYSQL_INCLUDE_DIR})
935       endif()
936     endif()
938     MYSQL_SOCKET_SEARCH()
939     if (MYSQL_UNIX_SOCK_ADDR)
940       if (${addPaths})
941         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DPHP_MYSQL_UNIX_SOCK_ADDR=\"${MYSQL_UNIX_SOCK_ADDR}\"")
942       endif()
943     elseif (NOT ${addPaths})
944       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
945       return()
946     else()
947       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")
948     endif()
950     if (${addPaths})
951       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${MYSQL_CLIENT_LIBS})
952     endif()
953   elseif (${libraryName} STREQUAL "pgsql")
954     FIND_PATH(PGSQL_INCLUDE_DIR NAMES libpq-fe.h
955       PATHS
956         /usr/include
957         /usr/include/postgresql
958         /usr/include/pgsql
959         /usr/local/include
960         /usr/local/include/postgresql
961         /usr/local/include/pgsql
962       )
963     FIND_LIBRARY(PGSQL_LIBRARY NAMES pq
964       PATHS
965         /lib
966         /usr/lib
967         /usr/local/lib
968     )
969     IF (NOT PGSQL_INCLUDE_DIR OR NOT PGSQL_LIBRARY)
970       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
971       return()
972     endif()
974     if(${addPaths})
975       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${PGSQL_INCLUDE_DIR})
976       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${PGSQL_LIBRARY})
977     endif()
978   elseif (${libraryName} STREQUAL "png")
979     find_package(LibPng ${requiredVersion})
980     if (NOT LIBPNG_INCLUDE_DIRS OR NOT LIBPNG_LIBRARIES)
981       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
982       return()
983     endif()
985     if (${addPaths})
986       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBPNG_INCLUDE_DIRS})
987       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBPNG_LIBRARIES})
988       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBPNG")
989       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_GD_PNG")
990       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DPNG_SKIP_SETJMP_CHECK")
991     endif()
992   elseif (${libraryName} STREQUAL "snappy")
993     find_package(Snappy ${requiredVersion})
994     if (NOT SNAPPY_INCLUDE_DIRS OR NOT SNAPPY_LIBRARIES)
995       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
996       return()
997     endif()
999     if (${addPaths})
1000       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${SNAPPY_INCLUDE_DIRS})
1001       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${SNAPPY_LIBRARIES})
1002     endif()
1003   elseif (${libraryName} STREQUAL "sodium")
1004     find_package(LibSodium ${requiredVersion})
1005     if (NOT LIBSODIUM_INCLUDE_DIRS OR NOT LIBSODIUM_LIBRARIES)
1006       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
1007       return()
1008     endif()
1010     if (${addPaths})
1011       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBSODIUM_INCLUDE_DIRS})
1012       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBSODIUM_LIBRARIES})
1013     endif()
1014   elseif (${libraryName} STREQUAL "vpx")
1015     find_package(LibVpx ${requiredVersion})
1016     if (NOT LIBVPX_INCLUDE_DIRS OR NOT LIBVPX_LIBRARIES)
1017       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
1018       return()
1019     endif()
1021     if (${addPaths})
1022       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBVPX_INCLUDE_DIRS})
1023       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBVPX_LIBRARIES})
1024       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBVPX")
1025     endif()
1026   elseif (${libraryName} STREQUAL "xml2")
1027     find_package(LibXml2 ${requiredVersion})
1028     if (NOT LIBXML2_INCLUDE_DIR OR NOT LIBXML2_LIBRARIES)
1029       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
1030       return()
1031     endif()
1033     if (${addPaths})
1034       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBXML2_INCLUDE_DIR})
1035       HHVM_EXTENSION_INTERNAL_ADD_DEFINES(${LIBXML2_DEFINITIONS})
1036       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBXML2_LIBRARIES})
1037       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBXML2")
1038     endif()
1039   elseif (${libraryName} STREQUAL "xslt")
1040     find_package(LibXslt ${requiredVersion})
1041     if (NOT LIBXSLT_INCLUDE_DIR OR NOT LIBXSLT_LIBRARIES)
1042       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
1043       return()
1044     endif()
1046     if (${addPaths})
1047       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBXSLT_INCLUDE_DIR})
1048       HHVM_EXTENSION_INTERNAL_ADD_DEFINES(${LIBXSLT_DEFINITIONS})
1049       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBXSLT_LIBRARIES} ${LIBXSLT_EXSLT_LIBRARIES})
1050       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBXSLT")
1051       if (LIBXSLT_STATIC)
1052         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DLIBXSLT_STATIC=1")
1053         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DLIBEXSLT_STATIC=1")
1054       endif()
1055     endif()
1056   elseif (${libraryName} STREQUAL "watchmanclient")
1057     find_package(libWatchmanClient ${requiredVersion})
1058     if (NOT WATCHMANCLIENT_INCLUDE_DIRS OR NOT WATCHMANCLIENT_LIBRARIES)
1059       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
1060       return()
1061     endif()
1063     if (${addPaths})
1064       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${WATCHMANCLIENT_INCLUDE_DIRS})
1065       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${WATCHMANCLIENT_LIBRARIES})
1066     endif()
1067   else()
1068     message(FATAL_ERROR "Unknown library '${originalLibraryName}' as a dependency of the '${HHVM_EXTENSION_${extensionID}_PRETTY_NAME}' extension!")
1069   endif()
1070 endfunction()