simpler remote worker
[hiphop-php.git] / CMake / HHVMExtensionConfig.cmake
blob9f008346ffd90905df4dc91fb16727f1d0341c58
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 # [HACK_SYSTEMLIB_DIR ...]
132 # A directory containing a Hack library that should be part of the
133 # extension.
135 # [DEPENDS ...]
136 # The dependencies of the extension. Extensions are prefixed
137 # with "ext_", and external libaries with "lib".
138 # "systemlib" is a special dependency that represents the
139 # systemlib header.
141 # A dependency may optionally be followed by "OPTIONAL", which
142 # means that the build won't fail if the dependency is not found.
144 # Dependencies prefixed with "os" represent the OS required to
145 # build the extension. The only valid value for this currently
146 # is osPosix, which represents everything with a valid posix
147 # API, which is most everything except for Windows.
149 # Dependencies prefixed with "var" represent a CMake variable
150 # which must evaluate to a trueish value for the extension to
151 # be enabled. If the value isn't defined, it is assumed to be
152 # false.
154 # If there is a space in an argument with a string in it, and
155 # the argument is a library, the exact version of the library
156 # required is expected to be the second part of the string.
157 # For example, "libFribidi 0.19.6" would require the Fribidi
158 # package to be exactly version 0.19.6.
160 # For libBoost, a single component is expected to be specified
161 # by appending a -componentName to the value, for example
162 # libBoost-variant would require the variant component of libBoost.
163 # This is only required if a library needs to be linked against.
164 # If a boost component is a headers-only library, libBoost is
165 # enough of a dependency.
167 # Note that libFolly is currently a dependency of everything
168 # for the sanity of the Windows port.
169 function(HHVM_DEFINE_EXTENSION extNameIn)
170   if (NOT DEFINED HHVM_EXTENSION_COUNT)
171     set(HHVM_EXTENSION_COUNT 0)
172   endif()
174   set(extensionName "")
175   set(extensionPrettyName "")
176   set(extensionRequired OFF)
177   # If WANTED is specified, then the extension must be explicitly disabled
178   # If IMPLICIT is specified, then the extension will be implicitly disabled
179   # when the dependencies are not found
180   # If neither is specified, we default to WANTED anyway
181   set(extensionEnabledState 4)
182   set(extensionSources)
183   set(extensionHeaders)
184   set(extensionLibrary)
185   set(extensionDependencies)
186   set(extensionDependenciesOptional)
188   # Make sure there are no spaces.
189   string(FIND ${extNameIn} " " extNameSpace)
190   if (NOT ${extNameSpace} EQUAL -1)
191     message(FATAL_ERROR "An extension name cannot have a space in it! Got name '${extNameIn}'.")
192   endif()
194   # Make sure another extension with the same hasn't already
195   # been defined.
196   set(i 0)
197   while (i LESS HHVM_EXTENSION_COUNT)
198     if (${HHVM_EXTENSION_${i}_NAME} STREQUAL ${extNameIn})
199       message(FATAL_ERROR "An extension with the name '${extNameIn}' has already been defined!")
200     endif()
201     math(EXPR i "${i} + 1")
202   endwhile()
203   set(extensionName ${extNameIn})
204   set(extensionPrettyName ${extensionName})
206   set(argumentState 0)
207   foreach (arg ${ARGN})
208     if ("x${arg}" STREQUAL "xPRETTY_NAME")
209       set(argumentState 1)
210     elseif ("x${arg}" STREQUAL "xIS_ENABLED")
211       set(argumentState 2)
212     elseif ("x${arg}" STREQUAL "xSOURCES")
213       set(argumentState 3)
214     elseif ("x${arg}" STREQUAL "xHEADERS")
215       set(argumentState 4)
216     elseif ("x${arg}" STREQUAL "xSYSTEMLIB")
217       set(argumentState 5)
218     elseif ("x${arg}" STREQUAL "xDEPENDS")
219       set(argumentState 7)
220     elseif ("x${arg}" STREQUAL "xHACK_SYSTEMLIB_DIR")
221       set(argumentState 8)
222     elseif ("x${arg}" STREQUAL "xREQUIRED")
223       if (NOT ${argumentState} EQUAL 0)
224         message(FATAL_ERROR "The REQUIRED modifier should only be placed immediately after the extension's name! (while processing the '${extensionPrettyName}' extension)")
225       endif()
226       set(extensionRequired ON)
227     elseif ("x${arg}" STREQUAL "xIMPLICIT")
228       if (NOT ${argumentState} EQUAL 0)
229         message(FATAL_ERROR "The IMPLICIT modifier should only be placed immediately after the extension's name! (while processing the '${extensionPrettyName}' extension)")
230       endif()
231       set(extensionEnabledState 0)
232     elseif ("x${arg}" STREQUAL "xWANTED")
233       if (NOT ${argumentState} EQUAL 0)
234         message(FATAL_ERROR "The WANTED modifier should only be placed immediately after the extension's name! (while processing the '${extensionPrettyName}' extension)")
235       endif()
236       set(extensionEnabledState 4)
237     elseif ("x${arg}" STREQUAL "xOPTIONAL")
238       if (${argumentState} EQUAL 7)
239         list(LENGTH extensionDependenciesOptional optDepLen)
240         math(EXPR optDepLen "${optDepLen} - 1")
241         list(REMOVE_AT extensionDependenciesOptional ${optDepLen})
242         list(APPEND extensionDependenciesOptional ON)
243       else()
244         message(FATAL_ERROR "The OPTIONAL modifier is only currently valid in the DEPENDS section of extension '${extensionPrettyName}'!")
245       endif()
246     elseif (${argumentState} EQUAL 0)
247       message(FATAL_ERROR "Unknown argument '${arg}' while processing extension '${extensionPrettyName}'!")
248     elseif (${argumentState} EQUAL 1)
249       # PRETTY_NAME
250       set(extensionPrettyName ${arg})
251       set(argumentState 0)
252     elseif (${argumentState} EQUAL 2)
253       # IS_ENABLED
254       if (DEFINED ${arg})
255         if (${${arg}})
256           set(extensionEnabledState 3)
257         else()
258           set(extensionEnabledState 2)
259         endif()
260       endif()
261       set(argumentState 0)
262     elseif (${argumentState} EQUAL 3)
263       # SOURCES
264       list(FIND extensionSources ${arg} listIDX)
265       if (NOT ${listIDX} EQUAL -1)
266         message(FATAL_ERROR "The file '${arg}' was already specified as a source of '${extensionPrettyName}'!")
267       endif()
268       list(APPEND extensionSources ${arg})
269     elseif (${argumentState} EQUAL 4)
270       # HEADERS
271       list(FIND extensionHeaders ${arg} listIDX)
272       if (NOT ${listIDX} EQUAL -1)
273         message(FATAL_ERROR "The file '${arg}' was already specified as a header of '${extensionPrettyName}'!")
274       endif()
275       list(APPEND extensionHeaders ${arg})
276     elseif (${argumentState} EQUAL 5)
277       # SYSTEMLIB
278       list(FIND extensionLibrary ${arg} listIDX)
279       if (NOT ${listIDX} EQUAL -1)
280         message(FATAL_ERROR "The file '${arg}' was already specified as part of the library of '${extensionPrettyName}'!")
281       endif()
282       list(APPEND extensionLibrary ${arg})
283     elseif (${argumentState} EQUAL 7)
284       # DEPENDS
285       list(FIND extensionDependencies ${arg} listIDX)
286       if (NOT ${listIDX} EQUAL -1)
287         message(FATAL_ERROR "'${arg}' was already specified as a dependency of '${extensionPrettyName}'!")
288       endif()
289       list(APPEND extensionDependencies ${arg})
290       list(APPEND extensionDependenciesOptional OFF)
291     elseif (${argumentState} EQUAL 8)
292       # HACK_SYSTEMLIB_DIR
293       set(singleFilePath "${CMAKE_CURRENT_BINARY_DIR}/ext_${extensionName}.hack")
294       if(IS_ABSOLUTE ${arg})
295         set(sourceDir ${arg})
296       else()
297         set(sourceDir "${HRE_CURRENT_EXT_PATH}/${arg}")
298       endif()
299       add_custom_command(
300         OUTPUT "${singleFilePath}"
301         COMMAND
302         "${CMAKE_SOURCE_DIR}/hphp/hack/scripts/concatenate_all.sh"
303         "--install_dir=${CMAKE_CURRENT_BINARY_DIR}"
304         "--root=${sourceDir}"
305         "--output_file=${singleFilePath}"
306         VERBATIM
307       )
308       add_custom_target(
309         "ext_${extensionName}_generated_systemlib"
310         DEPENDS
311         "${singleFilePath}"
312       )
313       add_dependencies(generated_systemlib "ext_${extensionName}_generated_systemlib")
314       list(APPEND extensionLibrary "${singleFilePath}")
315     else()
316       message(FATAL_ERROR "An error occurred while processing the arguments of the '${extensionPrettyName}' extension!")
317     endif()
318   endforeach()
320   # Check if the extension has been explicitly enabled or disabled.
321   string(TOUPPER ${extensionName} upperExtName)
322   if (DEFINED ENABLE_EXTENSION_${upperExtName})
323     if (${ENABLE_EXTENSION_${upperExtName}})
324       set(extensionEnabledState 3)
325     elseif (${extensionRequired})
326       message(WARNING "Attempt to explicitly disable the required extension '${extensionPrettyName}' by setting 'ENABLE_EXTENSION_${upperExtName}' was ignored.")
327     else()
328       set(extensionEnabledState 2)
329     endif()
330   endif()
332   # Increment the extension count.
333   set(extensionID ${HHVM_EXTENSION_COUNT})
334   math(EXPR newCount "${HHVM_EXTENSION_COUNT} + 1")
335   set(HHVM_EXTENSION_COUNT ${newCount} PARENT_SCOPE)
337   # And lastly, export the globals.
338   # We put these in the cache to make debugging easier.
339   # The only one that absolutely has to be in the cache is
340   # the ENABLED_STATE, due to it's modification from fairly
341   # arbitrary scope depths. HHVM_EXTENSION_COUNT must NEVER
342   # be in the cache, otherwise this will break.
343   set(HHVM_EXTENSION_${extensionID}_NAME ${extensionName} CACHE INTERNAL "" FORCE)
344   set(HHVM_EXTENSION_${extensionID}_PRETTY_NAME ${extensionPrettyName} CACHE INTERNAL "" FORCE)
345   set(HHVM_EXTENSION_${extensionID}_REQUIRED ${extensionRequired} CACHE INTERNAL "" FORCE)
346   set(HHVM_EXTENSION_${extensionID}_ROOT_DIR ${HRE_CURRENT_EXT_PATH} CACHE INTERNAL "" FORCE)
347   set(HHVM_EXTENSION_${extensionID}_ENABLED_STATE ${extensionEnabledState} CACHE INTERNAL "" FORCE)
348   set(HHVM_EXTENSION_${extensionID}_SOURCE_FILES ${extensionSources} CACHE INTERNAL "" FORCE)
349   set(HHVM_EXTENSION_${extensionID}_HEADER_FILES ${extensionHeaders} CACHE INTERNAL "" FORCE)
350   set(HHVM_EXTENSION_${extensionID}_SYSTEMLIB ${extensionLibrary} CACHE INTERNAL "" FORCE)
351   set(HHVM_EXTENSION_${extensionID}_DEPENDENCIES ${extensionDependencies} CACHE INTERNAL "" FORCE)
352   set(HHVM_EXTENSION_${extensionID}_DEPENDENCIES_OPTIONAL ${extensionDependenciesOptional} CACHE INTERNAL "" FORCE)
353 endfunction()
355 # Call after all of the calls to HHVM_DEFINE_EXTENSION are complete.
357 # This will also add the appropriate libraries, include directories, and
358 # defines for the enabled extensions' dependencies.
359 function(HHVM_EXTENSION_RESOLVE_DEPENDENCIES)
360   set(HHVM_EXTENSIONS_REQUIRED_LIBRARIES "" CACHE INTERNAL "" FORCE)
361   set(HHVM_EXTENSIONS_REQUIRED_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
362   set(HHVM_EXTENSIONS_REQUIRED_DEFINES "" CACHE INTERNAL "" FORCE)
363   set(i 0)
364   while (i LESS HHVM_EXTENSION_COUNT)
365     HHVM_EXTENSION_INTERNAL_RESOLVE_DEPENDENCIES_OF_EXTENSION(wasResolved ${i} " ")
366     string(TOUPPER ${HHVM_EXTENSION_${i}_NAME} upperExtName)
367     if (${wasResolved} EQUAL 1)
368       message(STATUS "Building the ${HHVM_EXTENSION_${i}_PRETTY_NAME} extension.")
370       # Now we need to make sure the dependencies are included and linked in
371       # correctly.
372       set(i2 0)
373       list(LENGTH HHVM_EXTENSION_${i}_DEPENDENCIES depCount)
374       while (i2 LESS depCount)
375         list(GET HHVM_EXTENSION_${i}_DEPENDENCIES ${i2} currentDependency)
376         string(FIND ${currentDependency} "lib" libIdx)
377         if (${libIdx} EQUAL 0)
378           HHVM_EXTENSION_INTERNAL_HANDLE_LIBRARY_DEPENDENCY(${i} ${currentDependency} ON)
379         endif()
380         math(EXPR i2 "${i2} + 1")
381       endwhile()
383       if (HHVM_EXTENSION_${i}_REQUIRED)
384         set(ENABLE_EXTENSION_${upperExtName} ON CACHE INTERNAL "Enable the ${HHVM_EXTENSION_${i}_PRETTY_NAME} extension.")
385       else()
386         set(ENABLE_EXTENSION_${upperExtName} ON CACHE BOOL "Enable the ${HHVM_EXTENSION_${i}_PRETTY_NAME} extension.")
387       endif()
388     else()
389       if (HHVM_EXTENSION_${i}_REQUIRED)
390         message(FATAL_ERROR "Failed to resolve a dependency of the ${HHVM_EXTENSION_${i}_PRETTY_NAME} extension, which is a required extension!")
391       endif()
392       message("Not building the ${HHVM_EXTENSION_${i}_PRETTY_NAME} extension.")
393       set(ENABLE_EXTENSION_${upperExtName} OFF CACHE BOOL "Enable the ${HHVM_EXTENSION_${i}_PRETTY_NAME} extension.")
394     endif()
395     math(EXPR i "${i} + 1")
396   endwhile()
397 endfunction()
399 # This will append the files of the enabled extensions to the following variables:
400 # C_SOURCES: C Source Files
401 # CXX_SOURCES: C++ Source Files
402 # HEADER_SOURCES: C/C++ Header Files
403 # ASM_SOURCES: asm source files appropriate for the current compiler.
404 # PHP_SOURCES: PHP files representing the various extensions' systemlib.
405 function (HHVM_EXTENSION_BUILD_SOURCE_LISTS)
406   set(i 0)
407   while (i LESS HHVM_EXTENSION_COUNT)
408     if (${HHVM_EXTENSION_${i}_ENABLED_STATE} EQUAL 1)
409       HHVM_EXTENSION_INTERNAL_SORT_OUT_SOURCES(${HHVM_EXTENSION_${i}_ROOT_DIR}
410         ${HHVM_EXTENSION_${i}_SOURCE_FILES}
411         ${HHVM_EXTENSION_${i}_HEADER_FILES}
412         ${HHVM_EXTENSION_${i}_SYSTEMLIB}
413       )
414     endif()
415     math(EXPR i "${i} + 1")
416   endwhile()
418   # Propagate the extra files to the parent scope.
419   set(C_SOURCES ${C_SOURCES} PARENT_SCOPE)
420   set(CXX_SOURCES ${CXX_SOURCES} PARENT_SCOPE)
421   set(HEADER_SOURCES ${HEADER_SOURCES} PARENT_SCOPE)
422   set(ASM_SOURCES ${ASM_SOURCES} PARENT_SCOPE)
423   set(PHP_SOURCES ${PHP_SOURCES} PARENT_SCOPE)
424 endfunction()
426 # Sort out all the files into their appropriate variable, as well as transform the paths
427 # to their fully-resolved forms.
428 function (HHVM_EXTENSION_INTERNAL_SORT_OUT_SOURCES rootDir)
429   foreach (fileName ${ARGN})
430     string(LENGTH ${fileName} fileNameLength)
431     string(FIND ${fileName} "." dotPos REVERSE)
432     if (${dotPos} EQUAL -1)
433       message(FATAL_ERROR "No extension on file '${fileName}'!")
434     endif()
435     math(EXPR endPos "${fileNameLength} - ${dotPos}")
436     string(SUBSTRING ${fileName} ${dotPos} ${endPos} fileExtension)
437     string(TOLOWER ${fileExtension} fileExtension)
438     if (${fileExtension} STREQUAL ".c")
439       list(APPEND C_SOURCES "${rootDir}/${fileName}")
440     elseif (${fileExtension} STREQUAL ".cpp" OR ${fileExtension} STREQUAL ".cxx" OR ${fileExtension} STREQUAL ".cc")
441       list(APPEND CXX_SOURCES "${rootDir}/${fileName}")
442     elseif (${fileExtension} STREQUAL ".h" OR ${fileExtension} STREQUAL ".hpp")
443       list(APPEND HEADER_SOURCES "${rootDir}/${fileName}")
444     elseif (${fileExtension} STREQUAL ".s")
445       # AT&T syntax, MSVC doesn't like.
446       if (NOT MSVC)
447         list(APPEND ASM_SOURCES "${rootDir}/${fileName}")
448       endif()
449     elseif (${fileExtension} STREQUAL ".asm")
450       # MASM syntax. MSVC only.
451       if (MSVC)
452         list(APPEND ASM_SOURCES "${rootDir}/${fileName}")
453       endif()
454     elseif (${fileExtension} STREQUAL ".php")
455       list(APPEND PHP_SOURCES "${rootDir}/${fileName}")
456     elseif (${fileExtension} STREQUAL ".hack")
457       # .hack files are used by typechecked systemlib; there's a directory,
458       # and the actual .hack file is generated. As such, it's in the build
459       # directory instead, so we have an absolute path
460       list(APPEND PHP_SOURCES "${fileName}")
461     else()
462       message(FATAL_ERROR "Unknown file extension '${fileExtension}'!")
463     endif()
464   endforeach()
465   set(C_SOURCES ${C_SOURCES} PARENT_SCOPE)
466   set(CXX_SOURCES ${CXX_SOURCES} PARENT_SCOPE)
467   set(HEADER_SOURCES ${HEADER_SOURCES} PARENT_SCOPE)
468   set(ASM_SOURCES ${ASM_SOURCES} PARENT_SCOPE)
469   set(PHP_SOURCES ${PHP_SOURCES} PARENT_SCOPE)
470 endfunction()
472 # Configure the specified target so that it can compile when
473 # linked against the enabled extensions.
474 function(HHVM_CONFIGURE_TARGET_FOR_EXTENSION_DEPENDENCIES targetName)
475   target_link_libraries(${targetName} ${HHVM_EXTENSIONS_REQUIRED_LIBRARIES})
476   target_include_directories(${targetName} PUBLIC ${HHVM_EXTENSIONS_REQUIRED_INCLUDE_DIRS})
477   target_compile_definitions(${targetName} PUBLIC ${HHVM_EXTENSIONS_REQUIRED_DEFINES})
478 endfunction()
481 # Resolve the dependencies of the specified extension, and update it's enabled state.
482 function(HHVM_EXTENSION_INTERNAL_RESOLVE_DEPENDENCIES_OF_EXTENSION resolvedDestVar extensionID)
483   # If already resolved, return that state.
484   if (NOT HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 0 AND
485       NOT HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 3 AND
486       NOT HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 4)
487     set(${resolvedDestVar} ${HHVM_EXTENSION_${extensionID}_ENABLED_STATE} PARENT_SCOPE)
488     return()
489   endif()
491   # If already in resolution stack, it's a circular dependency,
492   # assume for now that it's enabled.
493   list(FIND HHVM_EXTENSION_RESOLUTION_STACK ${HHVM_EXTENSION_${extensionID}_NAME} resIDX)
494   if (NOT ${resIDX} EQUAL -1)
495     set(${resolvedDestVar} 1 PARENT_SCOPE)
496     return()
497   endif()
499   # Go through the dependencies, checking each one recursively in turn.
500   list(LENGTH HHVM_EXTENSION_${extensionID}_DEPENDENCIES depCount)
501   set(i 0)
502   while (i LESS depCount)
503     list(GET HHVM_EXTENSION_${extensionID}_DEPENDENCIES ${i} currentDependency)
505     string(FIND ${currentDependency} "lib" listIDX)
506     if (${listIDX} EQUAL 0)
507       # Library Dependency
508       HHVM_EXTENSION_INTERNAL_HANDLE_LIBRARY_DEPENDENCY(${extensionID} ${currentDependency} OFF)
509       if (HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 2)
510         break()
511       endif()
512     else()
513       string(FIND ${currentDependency} "var" listIDX)
514       if (${listIDX} EQUAL 0)
515         # CMake Variable Dependency
516         string(LENGTH ${currentDependency} depLength)
517         math(EXPR depLength "${depLength} - 3")
518         string(SUBSTRING ${currentDependency} 3 ${depLength} varName)
519         if (DEFINED ${varName})
520           if (NOT ${${varName}})
521             HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${currentDependency} ON)
522             break()
523           endif()
524         else()
525           HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${currentDependency} ON)
526           break()
527         endif()
528       else()
529         string(FIND ${currentDependency} "os" listIDX)
530         if (${listIDX} EQUAL 0)
531           # OS Dependency
532           if (${currentDependency} STREQUAL "osPosix")
533             if (MSVC)
534               HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${currentDependency} ON)
535               break()
536             endif()
537           else()
538             message(FATAL_ERROR "The only OS restriction that is currently valid is 'osPosix', got '${currentDependency}'!")
539           endif()
540         elseif (${currentDependency} STREQUAL "systemlib")
541           # TODO: Mark this somehow?
542         else()
543           message(FATAL_ERROR "Unknown dependency '${currentDependency}' for extension '${HHVM_EXTENSION_${extensionID}_PRETTY_NAME}'!")
544         endif()
545       endif()
546     endif()
548     math(EXPR i "${i} + 1")
549   endwhile()
551   if (HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 0 OR
552       HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 3 OR
553       HHVM_EXTENSION_${extensionID}_ENABLED_STATE EQUAL 4)
554     set(HHVM_EXTENSION_${extensionID}_ENABLED_STATE 1 CACHE INTERNAL "" FORCE)
555   endif()
556   set(${resolvedDestVar} ${HHVM_EXTENSION_${extensionID}_ENABLED_STATE} PARENT_SCOPE)
557 endfunction()
559 # Set that an extension was disabled because of the specified dependency not being
560 # possible to resolve.
561 # This optionally takes a third BOOL parameter that should be set to ON only if the
562 # dependency that failed to resolve is an os* or var* dependency.
563 function(HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY extensionID failedDependency)
564   list(FIND HHVM_EXTENSION_${extensionID}_DEPENDENCIES ${failedDependency} depIdx)
565   if (depIdx EQUAL -1)
566     message(FATAL_ERROR "An issue occured while processing the '${failedDependency}' dependency of the ${HHVM_EXTENSION_${extensionID}_PRETTY_NAME} extension!")
567   endif()
568   list(GET HHVM_EXTENSION_${extensionID}_DEPENDENCIES_OPTIONAL ${depIdx} isOptional)
570   if (NOT ${isOptional})
571     if (${HHVM_EXTENSION_${extensionID}_ENABLED_STATE} EQUAL 4 AND (NOT ${ARGC} EQUAL 3 OR NOT "${ARGV2}" STREQUAL "ON"))
572       message(FATAL_ERROR "The ${HHVM_EXTENSION_${extensionID}_PRETTY_NAME} extension is an extension you probably want, but resolving the dependency '${failedDependency}' failed!")
573     elseif (${HHVM_EXTENSION_${extensionID}_ENABLED_STATE} EQUAL 3)
574       message(FATAL_ERROR "The ${HHVM_EXTENSION_${extensionID}_PRETTY_NAME} extension was forcefully enabled, but resolving the dependency '${failedDependency}' failed!")
575     elseif (${HHVM_EXTENSION_${extensionID}_ENABLED_STATE} EQUAL 1)
576       # Currently only triggers for issues with find_package when applying the library dependencies.
577       message(FATAL_ERROR "An error occurred while applying the '${failedDependency}' dependency of the ${HHVM_EXTENSION_${extensionID}_PRETTY_NAME} extension!")
578     endif()
579     message(STATUS "The ${HHVM_EXTENSION_${extensionID}_PRETTY_NAME} extension was disabled because resolving the dependency '${failedDependency}' failed.")
580     set(HHVM_EXTENSION_${extensionID}_ENABLED_STATE 2 CACHE INTERNAL "" FORCE)
581   endif()
582 endfunction()
584 # Add a set of libraries to link against.
585 function(HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES)
586   set(reqLibs ${HHVM_EXTENSIONS_REQUIRED_LIBRARIES})
587   foreach (lib ${ARGN})
588     list(APPEND reqLibs ${lib})
589   endforeach()
590   set(HHVM_EXTENSIONS_REQUIRED_LIBRARIES ${reqLibs} CACHE INTERNAL "" FORCE)
591 endfunction()
593 # Add a set of include directories to use.
594 function(HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS)
595   set(incDirs ${HHVM_EXTENSIONS_REQUIRED_INCLUDE_DIRS})
596   foreach (inc ${ARGN})
597     list(APPEND incDirs ${inc})
598   endforeach()
599   set(HHVM_EXTENSIONS_REQUIRED_INCLUDE_DIRS ${incDirs} CACHE INTERNAL "" FORCE)
600 endfunction()
602 # Add a set of defines to use when compiling.
603 function(HHVM_EXTENSION_INTERNAL_ADD_DEFINES)
604   set(defs ${HHVM_EXTENSIONS_REQUIRED_DEFINES})
605   foreach (def ${ARGN})
606     list(APPEND defs ${def})
607   endforeach()
608   set(HHVM_EXTENSIONS_REQUIRED_DEFINES ${defs} CACHE INTERNAL "" FORCE)
609 endfunction()
611 # This handles all the library dependencies, and determines if the libraries are present.
612 function (HHVM_EXTENSION_INTERNAL_HANDLE_LIBRARY_DEPENDENCY extensionID dependencyName addPaths)
613   string(FIND ${dependencyName} "lib" libIdx)
614   if (NOT libIdx EQUAL 0)
615     message(FATAL_ERROR "Non-library dependency '${dependencyName}' passed to HHVM_EXTENSION_INTERNAL_HANDLE_LIBRARY_DEPENDENCY!")
616   endif()
618   set(requiredVersion)
619   string(LENGTH ${dependencyName} depLength)
620   math(EXPR depLength "${depLength} - 3")
621   string(SUBSTRING ${dependencyName} 3 ${depLength} originalLibraryName)
622   string(FIND ${originalLibraryName} " " spaceIDX)
623   if (NOT ${spaceIDX} EQUAL -1)
624     math(EXPR spaceIDX "${spaceIDX} + 1")
625     string(LENGTH ${originalLibraryName} libNameLength)
626     math(EXPR libNameLength "${libNameLength} - ${spaceIDX}")
627     string(SUBSTRING ${originalLibraryName} ${spaceIDX} ${libNameLength} requiredVersion)
628     math(EXPR spaceIDX "${spaceIDX} - 1")
629     string(SUBSTRING ${originalLibraryName} 0 ${spaceIDX} originalLibraryName)
630   endif()
631   string(TOLOWER ${originalLibraryName} libraryName)
633   # This first check is for libraries that are used by default
634   # Keep these in alphabetical order.
635   if (
636     ${libraryName} STREQUAL "boost" OR
637     ${libraryName} STREQUAL "editline" OR
638     ${libraryName} STREQUAL "fastlz" OR
639     ${libraryName} STREQUAL "folly" OR
640     ${libraryName} STREQUAL "lz4" OR
641     ${libraryName} STREQUAL "mbfl" OR
642     ${libraryName} STREQUAL "oniguruma" OR
643     ${libraryName} STREQUAL "openssl" OR
644     ${libraryName} STREQUAL "pcre" OR
645     ${libraryName} STREQUAL "readline" OR
646     ${libraryName} STREQUAL "sqlite" OR
647     ${libraryName} STREQUAL "zip" OR
648     ${libraryName} STREQUAL "zlib"
649   )
650     # Nothing to do, they are included by default.
651   elseif (${libraryName} STREQUAL "bzip2")
652     find_package(BZip2 ${requiredVersion})
653     find_package(EXPAT ${requiredVersion})
654     if (NOT BZIP2_INCLUDE_DIR OR NOT BZIP2_LIBRARIES)
655       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
656       return()
657     endif()
659     if (${addPaths})
660       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${BZIP2_INCLUDE_DIR})
661       HHVM_EXTENSION_INTERNAL_ADD_DEFINES(${BZIP2_DEFINITIONS})
662       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${BZIP2_LIBRARIES})
663       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBBZIP2")
664     endif()
665   elseif (${libraryName} STREQUAL "cclient")
666     find_package(CClient ${requiredVersion})
667     if (NOT CCLIENT_INCLUDE_PATH OR NOT CCLIENT_LIBRARY)
668       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
669       return()
670     endif()
672     CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/utf8.h" U8T_DECOMPOSE RECENT_CCLIENT)
673     if (NOT RECENT_CCLIENT)
674       unset(RECENT_CCLIENT CACHE)
675       if (${addPaths})
676         message(FATAL_ERROR "Your version of c-client is too old, you need 2007")
677       else()
678         message(STATUS "Your version of c-client is too old, you need 2007")
679         HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
680         return()
681       endif()
682     endif()
684     if (${addPaths})
685       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${CCLIENT_INCLUDE_PATH})
686       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${CCLIENT_LIBRARY})
687       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBCCLIENT")
689       if (EXISTS "${CCLIENT_INCLUDE_PATH}/linkage.c")
690         CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/linkage.c" auth_gss CCLIENT_HAS_GSS)
691       elseif (EXISTS "${CCLIENT_INCLUDE_PATH}/linkage.h")
692         CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/linkage.h" auth_gss CCLIENT_HAS_GSS)
693       endif()
694       if (NOT CCLIENT_HAS_GSS)
695         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DSKIP_IMAP_GSS=1")
696       endif()
698       if (EXISTS "${CCLIENT_INCLUDE_PATH}/linkage.c")
699         CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/linkage.c" ssl_onceonlyinit CCLIENT_HAS_SSL)
700       elseif (EXISTS "${CCLIENT_INCLUDE_PATH}/linkage.h")
701         CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/linkage.h" ssl_onceonlyinit CCLIENT_HAS_SSL)
702       endif()
703       if (NOT CCLIENT_HAS_SSL)
704         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DSKIP_IMAP_SSL=1")
705       endif()
706     endif()
707   elseif (${libraryName} STREQUAL "curl")
708     find_package(CURL ${requiredVersion})
709     if (NOT CURL_INCLUDE_DIR OR NOT CURL_LIBRARIES)
710       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
711       return()
712     endif()
714     if (${addPaths})
715       set(CMAKE_REQUIRED_LIBRARIES "${CURL_LIBRARIES}")
716       set(CMAKE_REQUIRED_INCLUDES "${CURL_INCLUDE_DIR}")
717       CHECK_FUNCTION_EXISTS("curl_multi_select" HAVE_CURL_MULTI_SELECT)
718       CHECK_FUNCTION_EXISTS("curl_multi_wait" HAVE_CURL_MULTI_WAIT)
719       if (HAVE_CURL_MULTI_SELECT)
720         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_CURL_MULTI_SELECT")
721       endif()
722       if (HAVE_CURL_MULTI_WAIT)
723         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_CURL_MULTI_WAIT")
724       endif()
725       set(CMAKE_REQUIRED_LIBRARIES)
726       set(CMAKE_REQUIRED_INCLUDES)
728       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${CURL_INCLUDE_DIR})
729       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${CURL_LIBRARIES})
730       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBCURL")
731     endif()
732   elseif (${libraryName} STREQUAL "expat")
733     find_package(EXPAT ${requiredVersion})
734     if (NOT EXPAT_INCLUDE_DIRS OR NOT EXPAT_LIBRARY)
735       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
736       return()
737     endif()
739     if (${addPaths})
740       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${EXPAT_INCLUDE_DIRS})
741       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${EXPAT_LIBRARY})
742       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBEXPAT")
743       if (EXPAT_STATIC)
744         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DXML_STATIC")
745       endif()
746     endif()
747   elseif (${libraryName} STREQUAL "freetype")
748     find_package(Freetype ${requiredVersion})
749     if (NOT FREETYPE_INCLUDE_DIRS OR NOT FREETYPE_LIBRARIES)
750       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
751       return()
752     endif()
754     if (${addPaths})
755       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${FREETYPE_INCLUDE_DIRS})
756       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${FREETYPE_LIBRARIES})
757       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBFREETYPE")
758       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_GD_FREETYPE")
759       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DENABLE_GD_TTF")
760     endif()
761   elseif (${libraryName} STREQUAL "fribidi")
762     find_package(fribidi ${requiredVersion})
763     if (NOT FRIBIDI_INCLUDE_DIR OR NOT FRIBIDI_LIBRARY)
764       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
765       return()
766     endif()
768     if (${addPaths})
769       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${FRIBIDI_INCLUDE_DIR})
770       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${FRIBIDI_LIBRARY})
771       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBFRIBIDI")
772     endif()
773   elseif (${libraryName} STREQUAL "glib")
774     find_package(GLIB ${requiredVersion})
775     if (NOT GLIB_INCLUDE_DIR OR NOT GLIB_CONFIG_INCLUDE_DIR)
776       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
777       return()
778     endif()
780     if (${addPaths})
781       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${GLIB_INCLUDE_DIR} ${GLIB_CONFIG_INCLUDE_DIR})
782       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBGLIB")
783     endif()
784   elseif (${libraryName} STREQUAL "gmp")
785     find_package(LibGmp ${requiredVersion})
786     if (NOT GMP_INCLUDE_DIR OR NOT GMP_LIBRARY)
787       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
788       return()
789     endif()
791     if (${addPaths})
792       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${GMP_INCLUDE_DIR})
793       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${GMP_LIBRARY})
794       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBGMP")
795     endif()
796   elseif (${libraryName} STREQUAL "iconv")
797     find_package(Libiconv ${requiredVersion})
798     if (NOT LIBICONV_INCLUDE_DIR)
799       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
800       return()
801     endif()
803     if (${addPaths})
804       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBICONV_INCLUDE_DIR})
805       if (LIBICONV_LIBRARY)
806         HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBICONV_LIBRARY})
807       endif()
808       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_ICONV")
809       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBICONV")
810       if (LIBICONV_CONST)
811         message(STATUS "Using const for input to iconv() call")
812         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DICONV_CONST=const")
813       endif()
814     endif()
815   elseif (${libraryName} STREQUAL "icu")
816     find_package(ICU ${requiredVersion})
817     if (NOT ICU_FOUND OR NOT ICU_DATA_LIBRARIES OR NOT ICU_I18N_LIBRARIES OR NOT ICU_LIBRARIES)
818       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
819       return()
820     endif()
822     if (ICU_VERSION VERSION_LESS "4.2")
823       unset(ICU_FOUND CACHE)
824       unset(ICU_INCLUDE_DIRS CACHE)
825       unset(ICU_LIBRARIES CACHE)
826       if (${addPaths})
827         message(FATAL_ERROR "ICU is too old, found ${ICU_VERSION} and we need 4.2")
828       else()
829         message(STATUS "ICU is too old, found ${ICU_VERSION} and we need 4.2")
830         HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
831         return()
832       endif()
833     endif ()
835     if (${addPaths})
836       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${ICU_INCLUDE_DIRS})
837       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${ICU_DATA_LIBRARIES} ${ICU_I18N_LIBRARIES} ${ICU_LIBRARIES})
838       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBICU")
839     endif()
840   elseif (${libraryName} STREQUAL "intl")
841     find_package(LibIntl ${requiredVersion})
842     if (NOT LIBINTL_INCLUDE_DIRS)
843       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
844       return()
845     endif()
847     if (${addPaths})
848       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBINTL_INCLUDE_DIRS})
849       if (LIBINTL_LIBRARIES)
850         HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBINTL_LIBRARIES})
851       endif()
852       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBINTL")
853     endif()
854   elseif (${libraryName} STREQUAL "jpeg")
855     find_package(LibJpeg ${requiredVersion})
856     if (NOT LIBJPEG_INCLUDE_DIRS OR NOT LIBJPEG_LIBRARIES)
857       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
858       return()
859     endif()
861     if (${addPaths})
862       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBJPEG_INCLUDE_DIRS})
863       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBJPEG_LIBRARIES})
864       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBJPEG")
865       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_GD_JPG")
866     endif()
867   elseif (${libraryName} STREQUAL "jsonc")
868     find_package(Libjsonc ${requiredVersion})
869     if (NOT LIBJSONC_INCLUDE_DIR OR NOT LIBJSONC_LIBRARY)
870       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
871       return()
872     endif()
874     if (${addPaths})
875       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBJSONC_INCLUDE_DIR})
876       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBJSONC_LIBRARY})
877       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBJSONC")
878     endif()
879   elseif (${libraryName} STREQUAL "ldap")
880     find_package(Ldap ${requiredVersion})
881     if (NOT LDAP_INCLUDE_DIR OR NOT LDAP_LIBRARIES)
882       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
883       return()
884     endif()
886     if (${addPaths})
887       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LDAP_INCLUDE_DIR})
888       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LDAP_LIBRARIES})
889       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBLDAP")
890     endif()
891   elseif (${libraryName} STREQUAL "magickwand")
892     find_package(LibMagickWand ${requiredVersion})
893     if (NOT LIBMAGICKWAND_INCLUDE_DIRS OR NOT LIBMAGICKWAND_LIBRARIES OR NOT LIBMAGICKCORE_LIBRARIES)
894       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
895       return()
896     endif()
898     if (${addPaths})
899       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBMAGICKWAND_INCLUDE_DIRS})
900       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBMAGICKWAND_LIBRARIES} ${LIBMAGICKCORE_LIBRARIES})
901       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBMAGICKWAND")
902     endif()
903   elseif (${libraryName} STREQUAL "mcrypt")
904     find_package(Mcrypt ${requiredVersion})
905     if (NOT Mcrypt_INCLUDE_DIR OR NOT Mcrypt_LIB)
906       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
907       return()
908     endif()
910     if (${addPaths})
911       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${Mcrypt_INCLUDE_DIR})
912       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${Mcrypt_LIB})
913       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBMCRYPT")
914     endif()
915   elseif (${libraryName} STREQUAL "memcached")
916     find_package(Libmemcached ${requiredVersion})
917     if (NOT LIBMEMCACHED_INCLUDE_DIR OR NOT LIBMEMCACHED_LIBRARY)
918       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
919       return()
920     endif()
922     if (LIBMEMCACHED_VERSION VERSION_LESS "0.39")
923       unset(LIBMEMCACHED_INCLUDE_DIR CACHE)
924       unset(LIBMEMCACHED_LIBRARY CACHE)
925       unset(LIBMEMCACHED_VERSION CACHE)
926       if (${addPaths})
927         message(FATAL_ERROR "libmemcached is too old, found ${LIBMEMCACHED_VERSION} and we need 0.39")
928       else()
929         message(STATUS "libmemcached is too old, found ${LIBMEMCACHED_VERSION} and we need 0.39")
930         HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
931         return()
932       endif()
933     endif()
935     if (${addPaths})
936       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBMEMCACHED_INCLUDE_DIR})
937       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBMEMCACHED_LIBRARY})
938       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBMEMCACHED")
939     endif()
940   elseif (${libraryName} STREQUAL "mysql")
941     HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(fbmysqlclient)
942     MYSQL_SOCKET_SEARCH()
943     HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DPHP_MYSQL_UNIX_SOCK_ADDR=\"${MYSQL_UNIX_SOCK_ADDR}\"")
944   elseif (${libraryName} STREQUAL "pgsql")
945     FIND_PATH(PGSQL_INCLUDE_DIR NAMES libpq-fe.h
946       PATHS
947         /usr/include
948         /usr/include/postgresql
949         /usr/include/pgsql
950         /usr/local/include
951         /usr/local/include/postgresql
952         /usr/local/include/pgsql
953       )
954     FIND_LIBRARY(PGSQL_LIBRARY NAMES pq
955       PATHS
956         /lib
957         /usr/lib
958         /usr/local/lib
959     )
960     IF (NOT PGSQL_INCLUDE_DIR OR NOT PGSQL_LIBRARY)
961       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
962       return()
963     endif()
965     if(${addPaths})
966       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${PGSQL_INCLUDE_DIR})
967       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${PGSQL_LIBRARY})
968     endif()
969   elseif (${libraryName} STREQUAL "png")
970     find_package(LibPng ${requiredVersion})
971     if (NOT LIBPNG_INCLUDE_DIRS OR NOT LIBPNG_LIBRARIES)
972       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
973       return()
974     endif()
976     if (${addPaths})
977       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBPNG_INCLUDE_DIRS})
978       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBPNG_LIBRARIES})
979       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBPNG")
980       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_GD_PNG")
981       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DPNG_SKIP_SETJMP_CHECK")
982     endif()
983   elseif (${libraryName} STREQUAL "snappy")
984     find_package(Snappy ${requiredVersion})
985     if (NOT SNAPPY_INCLUDE_DIRS OR NOT SNAPPY_LIBRARIES)
986       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
987       return()
988     endif()
990     if (${addPaths})
991       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${SNAPPY_INCLUDE_DIRS})
992       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${SNAPPY_LIBRARIES})
993     endif()
994   elseif (${libraryName} STREQUAL "squangle")
995     HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(squangle)
996   elseif (${libraryName} STREQUAL "thrift")
997     HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(thrift)
998   elseif (${libraryName} STREQUAL "vpx")
999     find_package(LibVpx ${requiredVersion})
1000     if (NOT LIBVPX_INCLUDE_DIRS OR NOT LIBVPX_LIBRARIES)
1001       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
1002       return()
1003     endif()
1005     if (${addPaths})
1006       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBVPX_INCLUDE_DIRS})
1007       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBVPX_LIBRARIES})
1008       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBVPX")
1009     endif()
1010   elseif (${libraryName} STREQUAL "xml2")
1011     find_package(LibXml2 ${requiredVersion})
1012     if (NOT LIBXML2_INCLUDE_DIR OR NOT LIBXML2_LIBRARIES)
1013       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
1014       return()
1015     endif()
1017     if (${addPaths})
1018       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBXML2_INCLUDE_DIR})
1019       HHVM_EXTENSION_INTERNAL_ADD_DEFINES(${LIBXML2_DEFINITIONS})
1020       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBXML2_LIBRARIES})
1021       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBXML2")
1022     endif()
1023   elseif (${libraryName} STREQUAL "xslt")
1024     find_package(LibXslt ${requiredVersion})
1025     if (NOT LIBXSLT_INCLUDE_DIR OR NOT LIBXSLT_LIBRARIES)
1026       HHVM_EXTENSION_INTERNAL_SET_FAILED_DEPENDENCY(${extensionID} ${dependencyName})
1027       return()
1028     endif()
1030     if (${addPaths})
1031       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS(${LIBXSLT_INCLUDE_DIR})
1032       HHVM_EXTENSION_INTERNAL_ADD_DEFINES(${LIBXSLT_DEFINITIONS})
1033       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${LIBXSLT_LIBRARIES} ${LIBXSLT_EXSLT_LIBRARIES})
1034       HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DHAVE_LIBXSLT")
1035       if (LIBXSLT_STATIC)
1036         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DLIBXSLT_STATIC=1")
1037         HHVM_EXTENSION_INTERNAL_ADD_DEFINES("-DLIBEXSLT_STATIC=1")
1038       endif()
1039     endif()
1040   elseif (TARGET "${dependencyName}")
1041     # If we have libfoo, resolve as libfoo
1042     message(STATUS "Resolving extension '${HHVM_EXTENSION_${extensionID}_NAME}' dependency '${dependencyName}' as CMake target")
1043     if (${addPaths})
1044       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${dependencyName})
1045       get_target_property(DEPENDENCY_TARGET_INCLUDE_DIR ${dependencyName} INTERFACE_INCLUDE_DIRECTORIES)
1046       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS("${DEPENDENCY_TARGET_INCLUDE_DIR}")
1047     endif ()
1048   elseif (TARGET "${originalLibraryName}")
1049     # If we have libfoo, resolve as 'foo'; the `lib` prefix is needed for our cmake to consider it to be a
1050     # library dependency, so either case is valid :(
1051     message(STATUS "Resolving extension '${HHVM_EXTENSION_${extensionID}_NAME}' dependency '${dependencyName}' as CMake target '${originalLibraryName}'")
1052     if (${addPaths})
1053       HHVM_EXTENSION_INTERNAL_ADD_LINK_LIBRARIES(${originalLibraryName})
1054       get_target_property(DEPENDENCY_TARGET_INCLUDE_DIR ${originalLibraryName} INTERFACE_INCLUDE_DIRECTORIES)
1055       HHVM_EXTENSION_INTERNAL_ADD_INCLUDE_DIRS("${DEPENDENCY_TARGET_INCLUDE_DIR}")
1056     endif ()
1057   else()
1058     message(FATAL_ERROR "Unknown library '${originalLibraryName}' as a dependency of the '${HHVM_EXTENSION_${extensionID}_PRETTY_NAME}' extension!")
1059   endif()
1060 endfunction()