1 if (${CMAKE_MAJOR_VERSION} GREATER 2)
2 cmake_policy(SET CMP0026 OLD)
5 include(GNUInstallDirs)
7 function(auto_sources RETURN_VALUE PATTERN SOURCE_SUBDIRS)
9 if ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")
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})
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})
41 list(REMOVE_ITEM ${RETURN_VALUE} ${FILTER_OUT})
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}")
50 if (NOT (${f} MATCHES "(ext_hhvm|/(old-)?tests?/)"))
51 list(APPEND CXX_SOURCES ${f})
54 auto_sources(files "*.c" "RECURSE" "${DIR}")
56 if (NOT (${f} MATCHES "(ext_hhvm|/(old-)?tests?/)"))
57 list(APPEND C_SOURCES ${f})
61 auto_sources(files "*.asm" "RECURSE" "${DIR}")
63 if (NOT (${f} MATCHES "(ext_hhvm|/(old-)?tests?/)"))
64 list(APPEND ASM_SOURCES ${f})
68 auto_sources(files "*.S" "RECURSE" "${DIR}")
70 if (NOT (${f} MATCHES "(ext_hhvm|/(old-)?tests?/)"))
71 list(APPEND ASM_SOURCES ${f})
75 auto_sources(files "*.h" "RECURSE" "${DIR}")
77 if (NOT (${f} MATCHES "(/(old-)?tests?/)"))
78 list(APPEND HEADER_SOURCES ${f})
81 endmacro(HHVM_SELECT_SOURCES)
83 function(CONTAINS_STRING FILE SEARCH RETURN_VALUE)
84 file(STRINGS ${FILE} FILE_CONTENTS REGEX ".*${SEARCH}.*")
86 set(${RETURN_VALUE} True PARENT_SCOPE)
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)
94 /var/run/mysqld/mysqld.sock
96 /var/run/mysql/mysql.sock
97 /var/lib/mysql/mysql.sock
99 /usr/local/mysql/var/mysql.sock
100 /Private/tmp/mysql.sock
101 /private/tmp/mysql.sock
111 set(MYSQL_UNIX_SOCK_ADDR ${MYSQL_SOCK} CACHE STRING "Path to MySQL Socket")
115 function(append_systemlib TARGET SOURCE SECTNAME)
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)
123 set(${TARGET}_SLIBS ${${TARGET}_SLIBS} -Wl,-sectcreate,__text,${SECTNAME},${SOURCE} PARENT_SCOPE)
125 set(${TARGET}_SLIBS ${${TARGET}_SLIBS} "--add-section" "${SECTNAME}=${SOURCE}" PARENT_SCOPE)
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})
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"
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"
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})
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")
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")
166 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/embed.rc "${RESOURCE_FILE}")
168 add_custom_command(TARGET ${TARGET} POST_BUILD
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"
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}")
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)
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}")
195 append_systemlib(${TARGET} ${SLIB} "ext.${SLIB_HASH_NAME_SHORT}")
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})
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)
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)")
218 install(CODE "execute_process(COMMAND \"${CHRPATH}\" \"-r\" \"${RPATH}\" \"${LOC}\" ERROR_QUIET)")
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)
228 CODE "INCLUDE(\"${HPHP_HOME}/CMake/HPHPFunctions.cmake\")
229 HHVM_INSTALL_HEADERS(${TARGET} ${HPHP_HOME}
230 \"\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}\" ${ARGN})"
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}")
243 string(FIND ${dest_rel} / slash_pos REVERSE)
244 if(slash_pos EQUAL -1)
247 string(SUBSTRING ${dest_rel} 0 ${slash_pos} dest_rel)
250 DESTINATION "$ENV{DESTDIR}${DEST}/${dest_rel}"
251 NO_SOURCE_PERMISSIONS)
256 macro(HHVM_EXT_OPTION EXTNAME PACKAGENAME)
257 if (NOT DEFINED EXT_${EXTNAME})
259 find_package(${PACKAGENAME})
260 elseif (EXT_${EXTNAME} STREQUAL "ON")
262 find_package(${PACKAGENAME} REQUIRED)
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.
271 # This will remove all files in the CPP_SOURCES list
272 # matching "/test/" or "Test.cpp$", but not matching
274 # HHVM_REMOVE_MATCHES_FROM_LISTS(CPP_SOURCES MATCHES "/test/" "Test.cpp$" IGNORE_MATCHES "BobTest.cpp$")
279 # The names of the lists to remove matches from.
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)
289 set(MATCHES_TO_REMOVE)
290 set(MATCHES_TO_IGNORE)
292 foreach (arg ${ARGN})
293 if ("x${arg}" STREQUAL "xMATCHES")
295 elseif ("x${arg}" STREQUAL "xIGNORE_MATCHES")
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})
304 message(FATAL_ERROR "Unknown argument state!")
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)
320 if (NOT SHOULD_IGNORE)
321 list(REMOVE_ITEM ${theList} ${entry})
326 set(${theList} ${${theList}} PARENT_SCOPE)
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)
335 foreach (fil ${ARGN})
336 file(TO_CMAKE_PATH "${fil}" filePath)
337 string(FIND "${filePath}" "/" rIdx REVERSE)
339 message(FATAL_ERROR "Unable to locate the final forward slash in '${filePath}'!")
341 string(SUBSTRING "${filePath}" 0 ${rIdx} filePath)
343 string(LENGTH "${filePath}" filePathLength)
344 string(FIND "${filePath}" "${rootDir}" rIdx)
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)
354 list(APPEND sourceGroups "${fileGroup}")
355 source_group("${fileGroup}" REGULAR_EXPRESSION "${filePath}/[^/.]+(.(tab|yy))?.(c|cc|cpp|h|hpp|ll|php|tcc|y)$")
361 macro(add_precompiled_header PrecompiledHead PrecompiledSrc SourcesVar)
362 if (MSVC AND MSVC_ENABLE_PCH)
363 get_filename_component(PrecompiledHeader "${PrecompiledHead}" ABSOLUTE)
364 get_filename_component(PrecompiledSource "${PrecompiledSrc}" ABSOLUTE)
365 get_filename_component(PrecompiledBasename "${PrecompiledHeader}" NAME_WE)
366 get_filename_component(PrecompiledHeaderFilename "${PrecompiledHeader}" NAME)
367 set(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${PrecompiledBasename}.pch")
368 set(Sources ${${SourcesVar}})
370 set_source_files_properties(${PrecompiledSource} PROPERTIES
371 COMPILE_FLAGS "/Yc\"${PrecompiledHeaderFilename}\" /Fp\"${PrecompiledBinary}\""
372 OBJECT_OUTPUTS "${PrecompiledBinary}")
373 set_source_files_properties(${Sources} PROPERTIES
374 COMPILE_FLAGS "/Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
375 OBJECT_DEPENDS "${PrecompiledBinary}")
377 list(APPEND ${SourcesVar} ${PrecompiledSource} ${PrecompiledHeader})
381 function(parse_version PREFIX VERSION)
382 if (NOT ${VERSION} MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+)?(-.+)?$")
383 message(FATAL_ERROR "VERSION must conform to X.Y(.Z)?(-.+)?")
386 string(FIND ${VERSION} "-" SUFFIX_POS)
389 string(SUBSTRING ${VERSION} ${SUFFIX_POS} -1 SUFFIX)
390 string(SUBSTRING ${VERSION} 0 ${SUFFIX_POS} NUMERIC_VERSION)
392 set(NUMERIC_VERSION ${VERSION})
395 string(REPLACE "." ";" VERSION_LIST "${NUMERIC_VERSION}")
396 list(GET VERSION_LIST 0 MAJOR)
397 list(GET VERSION_LIST 1 MINOR)
398 list(LENGTH VERSION_LIST VERSION_LIST_LENGTH)
399 if (VERSION_LIST_LENGTH GREATER 2)
400 list(GET VERSION_LIST 2 PATCH)
405 set(${PREFIX}MAJOR ${MAJOR} PARENT_SCOPE)
406 set(${PREFIX}MINOR ${MINOR} PARENT_SCOPE)
407 set(${PREFIX}PATCH ${PATCH} PARENT_SCOPE)
408 set(${PREFIX}SUFFIX ${SUFFIX} PARENT_SCOPE)
411 # MSVC doesn't support a --whole-archive flag, but newer versions
412 # of CMake do support object libraries, which give the same result.
413 # As we can't easily upgrade the normal builds to CMake 3.0, we
414 # will just require CMake 3.0+ for MSVC builds only.
415 function(add_object_library libraryName)
417 add_library(${libraryName} OBJECT ${ARGN})
419 add_library(${libraryName} STATIC ${ARGN})
423 # Get what might be the objects of the object libraries, if needed.
424 function(get_object_libraries_objects targetVariable)
427 foreach (fil ${ARGN})
428 list(APPEND OBJECTS $<TARGET_OBJECTS:${fil}>)
432 set(${targetVariable} ${OBJECTS} PARENT_SCOPE)
435 # Add the additional link targets for a set of object libraries,
437 function(link_object_libraries target)
442 set(WHOLE_ARCHIVE_LIBS)
443 foreach (fil ${ARGN})
444 list(APPEND WHOLE_ARCHIVE_LIBS ${fil})
450 -Wl,-pagezero_size,0x00001000
451 # Set the .text.keep section to be executable.
452 -Wl,-segprot,.text,rx,rx)
453 foreach(lib ${WHOLE_ARCHIVE_LIBS})
454 # It's important to use -Xlinker and not -Wl here: ${lib} needs to be its
455 # own option on the command line, since target_link_libraries will expand it
456 # from its logical name here into the full .a path. (Eww.)
457 list(APPEND ANCHOR_SYMS -Xlinker -force_load -Xlinker ${lib})
460 set(ANCHOR_SYMS -Wl,--whole-archive ${WHOLE_ARCHIVE_LIBS} -Wl,--no-whole-archive)
463 target_link_libraries(${target} ${ANCHOR_SYMS})
466 # This should be called for object libraries, rather than calling
467 # hphp_link directly.
468 function(object_library_hphp_link target)
469 # Gold doesn't need this, and MSVC can't have it. (see below)
470 if (NOT ENABLE_LD_GOLD AND NOT MSVC)
475 # If a library needs to be linked in to make GNU ld happy,
476 # it should be done by calling this.
477 function(object_library_ld_link_libraries target)
479 # CMake doesn't allow calls to target_link_libraries if the target
480 # is an OBJECT library, so MSVC can't have this.
482 target_link_libraries(${target} ${ARGN})