update version.h
[hiphop-php.git] / CMake / HPHPFunctions.cmake
blob7583b2cb5899266cc4af9a425c34bcda8cbd1a21
1 if (${CMAKE_MAJOR_VERSION} GREATER 2)
2   cmake_policy(SET CMP0026 OLD)
3 endif()
5 include(GNUInstallDirs)
7 function(auto_sources RETURN_VALUE PATTERN SOURCE_SUBDIRS)
9   if ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")
10     SET(PATH ".")
11     if (${ARGC} EQUAL 4)
12       list(GET ARGV 3 PATH)
13     endif ()
14   endif()
16   if ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")
17     unset(${RETURN_VALUE})
18     file(GLOB SUBDIR_FILES "${PATH}/${PATTERN}")
19     list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})
21     file(GLOB subdirs RELATIVE ${PATH} ${PATH}/*)
23     foreach(DIR ${subdirs})
24       if (IS_DIRECTORY ${PATH}/${DIR})
25         if (NOT "${DIR}" STREQUAL "CMakeFiles")
26           file(GLOB_RECURSE SUBDIR_FILES "${PATH}/${DIR}/${PATTERN}")
27           list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})
28         endif()
29       endif()
30     endforeach()
31   else ()
32     file(GLOB ${RETURN_VALUE} "${PATTERN}")
34     foreach (PATH ${SOURCE_SUBDIRS})
35       file(GLOB SUBDIR_FILES "${PATH}/${PATTERN}")
36       list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})
37     endforeach(PATH ${SOURCE_SUBDIRS})
38   endif ()
40   if (${FILTER_OUT})
41     list(REMOVE_ITEM ${RETURN_VALUE} ${FILTER_OUT})
42   endif()
44   set(${RETURN_VALUE} ${${RETURN_VALUE}} PARENT_SCOPE)
45 endfunction(auto_sources)
47 macro(HHVM_SELECT_SOURCES DIR)
48   auto_sources(files "*.cpp" "RECURSE" "${DIR}")
49   foreach(f ${files})
50     if (NOT (${f} MATCHES "(ext_hhvm|/(old-)?tests?/)"))
51       list(APPEND CXX_SOURCES ${f})
52     endif()
53   endforeach()
54   auto_sources(files "*.c" "RECURSE" "${DIR}")
55   foreach(f ${files})
56     if (NOT (${f} MATCHES "(ext_hhvm|/(old-)?tests?/)"))
57       list(APPEND C_SOURCES ${f})
58     endif()
59   endforeach()
60   if (MSVC)
61     auto_sources(files "*.asm" "RECURSE" "${DIR}")
62     foreach(f ${files})
63       if (NOT (${f} MATCHES "(ext_hhvm|/(old-)?tests?/)"))
64         list(APPEND ASM_SOURCES ${f})
65       endif()
66     endforeach()
67   else()
68     auto_sources(files "*.S" "RECURSE" "${DIR}")
69     foreach(f ${files})
70       if (NOT (${f} MATCHES "(ext_hhvm|/(old-)?tests?/)"))
71         list(APPEND ASM_SOURCES ${f})
72       endif()
73     endforeach()
74   endif()
75   auto_sources(files "*.h" "RECURSE" "${DIR}")
76   foreach(f ${files})
77     if (NOT (${f} MATCHES "(/(old-)?tests?/)"))
78       list(APPEND HEADER_SOURCES ${f})
79     endif()
80   endforeach()
81 endmacro(HHVM_SELECT_SOURCES)
83 function(CONTAINS_STRING FILE SEARCH RETURN_VALUE)
84   file(STRINGS ${FILE} FILE_CONTENTS REGEX ".*${SEARCH}.*")
85   if (FILE_CONTENTS)
86     set(${RETURN_VALUE} True PARENT_SCOPE)
87   endif()
88 endfunction(CONTAINS_STRING)
90 macro(MYSQL_SOCKET_SEARCH)
91   execute_process(COMMAND mysql_config --socket OUTPUT_VARIABLE MYSQL_SOCK OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
92   if (NOT MYSQL_SOCK)
93     foreach (i
94       /var/run/mysqld/mysqld.sock
95       /var/tmp/mysql.sock
96       /var/run/mysql/mysql.sock
97       /var/lib/mysql/mysql.sock
98       /var/mysql/mysql.sock
99       /usr/local/mysql/var/mysql.sock
100       /Private/tmp/mysql.sock
101       /private/tmp/mysql.sock
102       /tmp/mysql.sock
103       )
104       if (EXISTS ${i})
105         set(MYSQL_SOCK ${i})
106         break()
107       endif()
108     endforeach()
109   endif()
110   if (MYSQL_SOCK)
111     set(MYSQL_UNIX_SOCK_ADDR ${MYSQL_SOCK} CACHE STRING "Path to MySQL Socket")
112   endif()
113 endmacro()
115 function(append_systemlib TARGET SOURCE SECTNAME)
116   if(MSVC)
117     list(APPEND ${TARGET}_SLIBS_NAMES "${SECTNAME}")
118     set(${TARGET}_SLIBS_NAMES ${${TARGET}_SLIBS_NAMES} PARENT_SCOPE)
119     list(APPEND ${TARGET}_SLIBS_SOURCES "${SOURCE}")
120     set(${TARGET}_SLIBS_SOURCES ${${TARGET}_SLIBS_SOURCES} PARENT_SCOPE)
121   else()
122     if (APPLE)
123       set(${TARGET}_SLIBS ${${TARGET}_SLIBS} -Wl,-sectcreate,__text,${SECTNAME},${SOURCE} PARENT_SCOPE)
124     else()
125       set(${TARGET}_SLIBS ${${TARGET}_SLIBS} "--add-section" "${SECTNAME}=${SOURCE}" PARENT_SCOPE)
126     endif()
127     # Add the systemlib file to the "LINK_DEPENDS" for the systemlib, this will cause it
128     # to be relinked and the systemlib re-embedded
129     set_property(TARGET ${TARGET} APPEND PROPERTY LINK_DEPENDS ${SOURCE})
130   endif()
131 endfunction(append_systemlib)
133 function(embed_sections TARGET DEST)
134   add_custom_command(TARGET ${TARGET} PRE_BUILD
135     # OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/generated-compiler-id.txt"
136     #        "${CMAKE_CURRENT_SOURCE_DIR}/generated-repo-schema-id.txt"
137     #        "${CMAKE_CURRENT_SOURCE_DIR}/generated-build-id.txt"
138     COMMAND
139       "INSTALL_DIR=${CMAKE_BINARY_DIR}/hphp/util"
140       "${HPHP_HOME}/hphp/hhvm/generate-buildinfo.sh"
141     WORKING_DIRECTORY "${HPHP_HOME}/hphp/util"
142     COMMENT "Generating Repo Schema ID and Compiler ID"
143     VERBATIM)
145   if (APPLE)
146     set(COMPILER_ID -Wl,-sectcreate,__text,"compiler_id","${CMAKE_BINARY_DIR}/hphp/util/generated-compiler-id.txt")
147     set(REPO_SCHEMA -Wl,-sectcreate,__text,"repo_schema_id","${CMAKE_BINARY_DIR}/hphp/util/generated-repo-schema-id.txt")
148     set(BUILD_ID -Wl,-sectcreate,__text,"build_id","${CMAKE_BINARY_DIR}/hphp/util/generated-build-id.txt")
149     target_link_libraries(${TARGET} ${${TARGET}_SLIBS} ${COMPILER_ID} ${REPO_SCHEMA} ${BUILD_ID})
150   elseif(MSVC)
151     set(RESOURCE_FILE "#pragma code_page(1252)\n")
152     set(RESOURCE_FILE "${RESOURCE_FILE}LANGUAGE 0, 0\n")
153     set(RESOURCE_FILE "${RESOURCE_FILE}\n")
154     set(RESOURCE_FILE "${RESOURCE_FILE}#include \"${CMAKE_BINARY_DIR}/hphp/runtime/version.h\"\n")
155     file(READ "${CMAKE_BINARY_DIR}/hphp/hhvm/hhvm.rc" VERSION_INFO)
156     set(RESOURCE_FILE "${RESOURCE_FILE}compiler_id RCDATA \"${CMAKE_BINARY_DIR}/hphp/util/generated-compiler-id.txt\"\n")
157     set(RESOURCE_FILE "${RESOURCE_FILE}repo_schema_id RCDATA \"${CMAKE_BINARY_DIR}/hphp/util/generated-repo-schema-id.txt\"\n")
158     set(RESOURCE_FILE "${RESOURCE_FILE}build_id RCDATA \"${CMAKE_BINARY_DIR}/hphp/util/generated-build-id.txt\"\n")
159     set(RESOURCE_FILE "${RESOURCE_FILE}${VERSION_INFO}\n")
160     set(i 0)
161     foreach (nm ${${TARGET}_SLIBS_NAMES})
162       list(GET ${TARGET}_SLIBS_SOURCES ${i} source)
163       set(RESOURCE_FILE "${RESOURCE_FILE}${nm} RCDATA \"${source}\"\n")
164       math(EXPR i "${i} + 1")
165     endforeach()
166     file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/embed.rc "${RESOURCE_FILE}")
167   else()
168     add_custom_command(TARGET ${TARGET} POST_BUILD
169       COMMAND "objcopy"
170       ARGS "--add-section" "compiler_id=${CMAKE_BINARY_DIR}/hphp/util/generated-compiler-id.txt"
171            "--add-section" "repo_schema_id=${CMAKE_BINARY_DIR}/hphp/util/generated-repo-schema-id.txt"
172            "--add-section" "build_id=${CMAKE_BINARY_DIR}/hphp/util/generated-build-id.txt"
173            ${${TARGET}_SLIBS}
174            ${DEST}
175       DEPENDS "${CMAKE_BINARY_DIR}/hphp/util/generated-compiler-id.txt"
176               "${CMAKE_BINARY_DIR}/hphp/util/generated-repo-schema-id.txt"
177               "${CMAKE_BINARY_DIR}/hphp/util/generated-build-id.txt"
178       COMMENT "Embedding php in ${TARGET}")
179   endif()
180 endfunction(embed_sections)
182 macro(embed_systemlib_byname TARGET SLIB)
183   get_filename_component(SLIB_BN ${SLIB} "NAME_WE")
184   string(LENGTH ${SLIB_BN} SLIB_BN_LEN)
185   math(EXPR SLIB_BN_REL_LEN "${SLIB_BN_LEN} - 4")
186   string(SUBSTRING ${SLIB_BN} 4 ${SLIB_BN_REL_LEN} SLIB_EXTNAME)
187   string(MD5 SLIB_HASH_NAME ${SLIB_EXTNAME})
188   # Some platforms limit section names to 16 characters :(
189   string(SUBSTRING ${SLIB_HASH_NAME} 0 12 SLIB_HASH_NAME_SHORT)
190   if (MSVC)
191     # The dot would be causing the RC lexer to begin a number in the
192     # middle of our resource name, so use an underscore instead.
193     append_systemlib(${TARGET} ${SLIB} "ext_${SLIB_HASH_NAME_SHORT}")
194   else()
195     append_systemlib(${TARGET} ${SLIB} "ext.${SLIB_HASH_NAME_SHORT}")
196   endif()
197 endmacro()
199 function(embed_all_systemlibs TARGET ROOT DEST)
200   append_systemlib(${TARGET} ${ROOT}/system/systemlib.php systemlib)
201   foreach(SLIB ${EXTENSION_SYSTEMLIB_SOURCES} ${EZC_SYSTEMLIB_SOURCES})
202     embed_systemlib_byname(${TARGET} ${SLIB})
203   endforeach()
204   embed_sections(${TARGET} ${DEST})
205 endfunction(embed_all_systemlibs)
207 # Custom install function that doesn't relink, instead it uses chrpath to change it, if
208 # it's available, otherwise, it leaves the chrpath alone
209 function(HHVM_INSTALL TARGET DEST)
210   get_target_property(LOC ${TARGET} LOCATION)
211   get_target_property(TY ${TARGET} TYPE)
212   if (FOUND_CHRPATH)
213     get_target_property(RPATH ${TARGET} INSTALL_RPATH)
214     if (NOT RPATH STREQUAL "RPATH-NOTFOUND")
215       if (RPATH STREQUAL "")
216         install(CODE "execute_process(COMMAND \"${CHRPATH}\" \"-d\" \"${LOC}\" ERROR_QUIET)")
217       else()
218         install(CODE "execute_process(COMMAND \"${CHRPATH}\" \"-r\" \"${RPATH}\" \"${LOC}\" ERROR_QUIET)")
219       endif()
220     endif()
221   endif()
222   string(TOUPPER ${DEST} DEST_UPPER)
223   install(CODE "FILE(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${DEST_UPPER}DIR}\" TYPE ${TY} FILES \"${LOC}\")")
224 endfunction(HHVM_INSTALL)
226 function(HHVM_PUBLIC_HEADERS TARGET)
227   install(
228     CODE "INCLUDE(\"${HPHP_HOME}/CMake/HPHPFunctions.cmake\")
229       HHVM_INSTALL_HEADERS(${TARGET} ${HPHP_HOME}
230       \"\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}\" ${ARGN})"
231     COMPONENT dev)
232 endfunction()
234 function(HHVM_INSTALL_HEADERS TARGET SRCROOT DEST)
235   message(STATUS "Installing header files for ${TARGET}")
236   foreach(src_rel ${ARGN})
237     # Determine the relative directory name so that we can mirror the
238     # directory structure in the output
239     file(RELATIVE_PATH dest_rel ${SRCROOT} ${src_rel})
240     if (IS_ABSOLUTE ${dest_rel})
241       message(WARNING "${TARGET}: Header file ${dest_rel} is not inside ${SRCROOT}")
242     else()
243       string(FIND ${dest_rel} / slash_pos REVERSE)
244       if(slash_pos EQUAL -1)
245         set(dest_rel)
246       else()
247         string(SUBSTRING ${dest_rel} 0 ${slash_pos} dest_rel)
248       endif()
249       file(COPY ${src_rel}
250         DESTINATION "$ENV{DESTDIR}${DEST}/${dest_rel}"
251         NO_SOURCE_PERMISSIONS)
252     endif()
253   endforeach()
254 endfunction()
256 macro(HHVM_EXT_OPTION EXTNAME PACKAGENAME)
257   if (NOT DEFINED EXT_${EXTNAME})
258     # Implicit check
259     find_package(${PACKAGENAME})
260   elseif (EXT_${EXTNAME} STREQUAL "ON")
261     # Explicit check
262     find_package(${PACKAGENAME} REQUIRED)
263   endif()
264 endmacro()
266 # Remove all files matching a set of patterns, and,
267 # optionally, not matching a second set of patterns,
268 # from a set of lists.
270 # Example:
271 # This will remove all files in the CPP_SOURCES list
272 # matching "/test/" or "Test.cpp$", but not matching
273 # "BobTest.cpp$".
274 # HHVM_REMOVE_MATCHES_FROM_LISTS(CPP_SOURCES MATCHES "/test/" "Test.cpp$" IGNORE_MATCHES "BobTest.cpp$")
276 # Parameters:
278 # [...]:
279 # The names of the lists to remove matches from.
281 # [MATCHES ...]:
282 # The matches to remove from the lists.
284 # [IGNORE_MATCHES ...]:
285 # The matches not to remove, even if they match
286 # the main set of matches to remove.
287 function(HHVM_REMOVE_MATCHES_FROM_LISTS)
288   set(LISTS_TO_SEARCH)
289   set(MATCHES_TO_REMOVE)
290   set(MATCHES_TO_IGNORE)
291   set(argumentState 0)
292   foreach (arg ${ARGN})
293     if ("x${arg}" STREQUAL "xMATCHES")
294       set(argumentState 1)
295     elseif ("x${arg}" STREQUAL "xIGNORE_MATCHES")
296       set(argumentState 2)
297     elseif (argumentState EQUAL 0)
298       list(APPEND LISTS_TO_SEARCH ${arg})
299     elseif (argumentState EQUAL 1)
300       list(APPEND MATCHES_TO_REMOVE ${arg})
301     elseif (argumentState EQUAL 2)
302       list(APPEND MATCHES_TO_IGNORE ${arg})
303     else()
304       message(FATAL_ERROR "Unknown argument state!")
305     endif()
306   endforeach()
308   foreach (theList ${LISTS_TO_SEARCH})
309     foreach (entry ${${theList}})
310       foreach (match ${MATCHES_TO_REMOVE})
311         if (${entry} MATCHES ${match})
312           set(SHOULD_IGNORE OFF)
313           foreach (ign ${MATCHES_TO_IGNORE})
314             if (${entry} MATCHES ${ign})
315               set(SHOULD_IGNORE ON)
316               break()
317             endif()
318           endforeach()
320           if (NOT SHOULD_IGNORE)
321             list(REMOVE_ITEM ${theList} ${entry})
322           endif()
323         endif()
324       endforeach()
325     endforeach()
326     set(${theList} ${${theList}} PARENT_SCOPE)
327   endforeach()
328 endfunction()
330 # Automatically create source_group directives for the sources passed in.
331 function(auto_source_group rootName rootDir)
332   file(TO_CMAKE_PATH "${rootDir}" rootDir)
333   string(LENGTH "${rootDir}" rootDirLength)
334   set(sourceGroups)
335   foreach (fil ${ARGN})
336     file(TO_CMAKE_PATH "${fil}" filePath)
337     string(FIND "${filePath}" "/" rIdx REVERSE)
338     if (rIdx EQUAL -1)
339       message(FATAL_ERROR "Unable to locate the final forward slash in '${filePath}'!")
340     endif()
341     string(SUBSTRING "${filePath}" 0 ${rIdx} filePath)
343     string(LENGTH "${filePath}" filePathLength)
344     string(FIND "${filePath}" "${rootDir}" rIdx)
345     if (rIdx EQUAL 0)
346       math(EXPR filePathLength "${filePathLength} - ${rootDirLength}")
347       string(SUBSTRING "${filePath}" ${rootDirLength} ${filePathLength} fileGroup)
349       string(REPLACE "/" "\\" fileGroup "${fileGroup}")
350       set(fileGroup "\\${rootName}${fileGroup}")
352       list(FIND sourceGroups "${fileGroup}" rIdx)
353       if (rIdx EQUAL -1)
354         list(APPEND sourceGroups "${fileGroup}")
355         source_group("${fileGroup}" REGULAR_EXPRESSION "${filePath}/[^/.]+(.(tab|yy))?.(c|cc|cpp|h|hpp|ll|php|tcc|y)$")
356       endif()
357     endif()
358   endforeach()
359 endfunction()
361 function(parse_version PREFIX VERSION)
362   if (NOT ${VERSION} MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+)?(-.+)?$")
363     message(FATAL_ERROR "VERSION must conform to X.Y(.Z)?(-.+)?")
364   endif()
366   string(FIND ${VERSION} "-" SUFFIX_POS)
367   set(SUFFIX "")
368   if (SUFFIX_POS)
369     string(SUBSTRING ${VERSION} ${SUFFIX_POS} -1 SUFFIX)
370     string(SUBSTRING ${VERSION} 0 ${SUFFIX_POS} NUMERIC_VERSION)
371   else()
372     set(NUMERIC_VERSION ${VERSION})
373   endif()
375   string(REPLACE "." ";" VERSION_LIST "${NUMERIC_VERSION}")
376   list(GET VERSION_LIST 0 MAJOR)
377   list(GET VERSION_LIST 1 MINOR)
378   list(LENGTH VERSION_LIST VERSION_LIST_LENGTH)
379   if (VERSION_LIST_LENGTH GREATER 2)
380     list(GET VERSION_LIST 2 PATCH)
381   else()
382     set(PATCH 0)
383   endif()
385   set(${PREFIX}MAJOR ${MAJOR} PARENT_SCOPE)
386   set(${PREFIX}MINOR ${MINOR} PARENT_SCOPE)
387   set(${PREFIX}PATCH ${PATCH} PARENT_SCOPE)
388   set(${PREFIX}SUFFIX ${SUFFIX} PARENT_SCOPE)
389 endfunction()
391 # MSVC doesn't support a --whole-archive flag, but newer versions
392 # of CMake do support object libraries, which give the same result.
393 # As we can't easily upgrade the normal builds to CMake 3.0, we
394 # will just require CMake 3.0+ for MSVC builds only.
395 function(add_object_library libraryName)
396   if (MSVC)
397     add_library(${libraryName} OBJECT ${ARGN})
398   else()
399     add_library(${libraryName} STATIC ${ARGN})
400   endif()
401 endfunction()
403 # Get what might be the objects of the object libraries, if needed.
404 function(get_object_libraries_objects targetVariable)
405   set(OBJECTS)
406   if (MSVC)
407     foreach (fil ${ARGN})
408       list(APPEND OBJECTS $<TARGET_OBJECTS:${fil}>)
409     endforeach()
410   endif()
412   set(${targetVariable} ${OBJECTS} PARENT_SCOPE)
413 endfunction()
415 # Add the additional link targets for a set of object libraries,
416 # if needed.
417 function(link_object_libraries target)
418   if (MSVC)
419     return()
420   endif()
422   set(WHOLE_ARCHIVE_LIBS)
423   foreach (fil ${ARGN})
424     list(APPEND WHOLE_ARCHIVE_LIBS ${fil})
425   endforeach()
427   set(ANCHOR_SYMS)
428   if (APPLE)
429     set(ANCHOR_SYMS
430       -Wl,-pagezero_size,0x00001000
431       # Set the .text.keep section to be executable.
432       -Wl,-segprot,.text,rx,rx)
433     foreach(lib ${WHOLE_ARCHIVE_LIBS})
434       # It's important to use -Xlinker and not -Wl here: ${lib} needs to be its
435       # own option on the command line, since target_link_libraries will expand it
436       # from its logical name here into the full .a path. (Eww.)
437       list(APPEND ANCHOR_SYMS -Xlinker -force_load -Xlinker ${lib})
438     endforeach()
439   else()
440     set(ANCHOR_SYMS -Wl,--whole-archive ${WHOLE_ARCHIVE_LIBS} -Wl,--no-whole-archive)
441   endif()
443   target_link_libraries(${target} ${ANCHOR_SYMS})
444 endfunction()
446 # This should be called for object libraries, rather than calling
447 # hphp_link directly.
448 function(object_library_hphp_link target)
449   # MSVC can't have it. (see below)
450   if (NOT MSVC)
451     hphp_link(${target})
452   endif()
453 endfunction()
455 # If a library needs to be linked in to make GNU ld happy,
456 # it should be done by calling this.
457 function(object_library_ld_link_libraries target)
458   if (${ARGC})
459     # CMake doesn't allow calls to target_link_libraries if the target
460     # is an OBJECT library, so MSVC can't have this.
461     if (NOT MSVC)
462       target_link_libraries(${target} ${ARGN})
463     endif()
464   endif()
465 endfunction()
467 set(
468   HHVM_THIRD_PARTY_SOURCE_CACHE_PREFIX
469   ""
470   CACHE
471   STRING
472   "URL prefix containing cache of third-party dependencies"
474 set(
475   HHVM_THIRD_PARTY_SOURCE_CACHE_SUFFIX
476   ""
477   CACHE
478   STRING
479   "URL suffix for third-party dependency cache"
481 set(
482   HHVM_THIRD_PARTY_SOURCE_ONLY_USE_CACHE
483   OFF
484   CACHE
485   BOOL
486   "Do not download sources that are not in cache; may cause build to fail."
488 set(
489   HHVM_THIRD_PARTY_SOURCE_URL_LIST_OUTPUT
490   ""
491   CACHE
492   STRING
493   "Path to a text file to put a list of sources that should be in the cache"
496 # Usage:
497 #  SET_HHVM_THIRD_PARTY_SOURCE_ARGS(
498 #    MY_VAR_NAME
499 #    SOURCE_URL https://example.com/
500 #    SOURCE_HASH SHA256=deadbeef
501 #  )
502 #  ... or ...
503 #  SET_HHVM_THIRD_PARTY_SOURCE_ARGS(
504 #    MY_VAR_NAME
505 #    Linux_URL https://example.com/linux.tar.bz2
506 #    Linux_HASH SHA256=deadbeef
507 #    Darwin_URL https://example.com/macos.tar.bz2
508 #    Darwin_HASH SHA256=deadbeef
509 #  )
511 macro(SET_HHVM_THIRD_PARTY_SOURCE_ARGS VAR_NAME)
512   cmake_parse_arguments(
513     # Prefix (FOO becomes _arg_FOO - trailing _ implied)
514     _arg
515     # No-arg parameter (none):
516     ""
517     # Single-argument parameters
518     "SOURCE_URL;SOURCE_HASH;Linux_URL;Linux_HASH;Darwin_URL;Darwin_HASH"
519     # Multi-argument parameters (none)
520     ""
521     ${ARGN}
522   )
524   # Try source, but fall back to platform-specific
525   if (NOT "${_arg_SOURCE_URL}" STREQUAL "")
526     set(_URL "${_arg_SOURCE_URL}")
527     set("${VAR_NAME}" URL_HASH "${_arg_SOURCE_HASH}")
528     if (NOT "${HHVM_THIRD_PARTY_SOURCE_URL_LIST_OUTPUT}" STREQUAL "")
529       FILE(
530         APPEND
531         "${HHVM_THIRD_PARTY_SOURCE_URL_LIST_OUTPUT}"
532         "${_arg_SOURCE_URL}\n"
533       )
534     endif()
535   else()
536     set(_URL "${_arg_${CMAKE_HOST_SYSTEM_NAME}_URL}")
537     set("${VAR_NAME}" URL_HASH "${_arg_${CMAKE_HOST_SYSTEM_NAME}_HASH}")
538     if (NOT "${HHVM_THIRD_PARTY_SOURCE_URL_LIST_OUTPUT}" STREQUAL "")
539       FILE(
540         APPEND
541         "${HHVM_THIRD_PARTY_SOURCE_URL_LIST_OUTPUT}"
542         "${_arg_Linux_URL}\n"
543         "${_arg_Darwin_URL}\n"
544       )
545     endif()
546   endif()
548   if ("${HHVM_THIRD_PARTY_SOURCE_CACHE_PREFIX}" STREQUAL "")
549     list(APPEND ${VAR_NAME} URL "${_URL}")
550     if (${HHVM_THIRD_PARTY_SOURCE_ONLY_USE_CACHE})
551       message(
552         FATAL_ERROR
553         "HHVM_THIRD_PARTY_ONLY_USE_CACHE is set, but cache is not configured"
554       )
555     endif()
556   else()
558     get_filename_component("_URL_NAME" "${_URL}" NAME)
559     list(
560       APPEND "${VAR_NAME}"
561       URL
562       "${HHVM_THIRD_PARTY_SOURCE_CACHE_PREFIX}${_URL_NAME}${HHVM_THIRD_PARTY_SOURCE_CACHE_SUFFIX}"
563     )
564     if (NOT ${HHVM_THIRD_PARTY_SOURCE_ONLY_USE_CACHE})
565       list(APPEND "${VAR_NAME}" "${_URL}")
566     endif()
567     list(APPEND "${VAR_NAME}" DOWNLOAD_NAME "${_URL_NAME}")
568   endif()
569 endmacro()