-function(auto_sources RETURN_VALUE PATTERN SOURCE_SUBDIRS)\r
- if ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")\r
- SET(PATH ".")\r
- if (${ARGC} EQUAL 4)\r
- list(GET ARGV 3 PATH)\r
- endif ()\r
- endif()\r
-\r
- if ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")\r
- unset(${RETURN_VALUE})\r
- file(GLOB SUBDIR_FILES "${PATH}/${PATTERN}")\r
- list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})\r
-\r
- file(GLOB subdirs RELATIVE ${PATH} ${PATH}/*)\r
-\r
- foreach(DIR ${subdirs})\r
- if (IS_DIRECTORY ${PATH}/${DIR})\r
- if (NOT "${DIR}" STREQUAL "CMakeFiles")\r
- file(GLOB_RECURSE SUBDIR_FILES "${PATH}/${DIR}/${PATTERN}")\r
- list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})\r
- endif()\r
- endif()\r
- endforeach()\r
- else()\r
- file(GLOB ${RETURN_VALUE} "${PATTERN}")\r
-\r
- foreach (PATH ${SOURCE_SUBDIRS})\r
- file(GLOB SUBDIR_FILES "${PATH}/${PATTERN}")\r
- list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})\r
- endforeach()\r
- endif ()\r
-\r
- set(${RETURN_VALUE} ${${RETURN_VALUE}} PARENT_SCOPE)\r
-endfunction(auto_sources)\r
-\r
-# Remove all files matching a set of patterns, and,\r
-# optionally, not matching a second set of patterns,\r
-# from a set of lists.\r
-#\r
-# Example:\r
-# This will remove all files in the CPP_SOURCES list\r
-# matching "/test/" or "Test.cpp$", but not matching\r
-# "BobTest.cpp$".\r
-# REMOVE_MATCHES_FROM_LISTS(CPP_SOURCES MATCHES "/test/" "Test.cpp$" IGNORE_MATCHES "BobTest.cpp$")\r
-#\r
-# Parameters:\r
-#\r
-# [...]:\r
-# The names of the lists to remove matches from.\r
-#\r
-# [MATCHES ...]:\r
-# The matches to remove from the lists.\r
-#\r
-# [IGNORE_MATCHES ...]:\r
-# The matches not to remove, even if they match\r
-# the main set of matches to remove.\r
-function(REMOVE_MATCHES_FROM_LISTS)\r
- set(LISTS_TO_SEARCH)\r
- set(MATCHES_TO_REMOVE)\r
- set(MATCHES_TO_IGNORE)\r
- set(argumentState 0)\r
- foreach (arg ${ARGN})\r
- if ("x${arg}" STREQUAL "xMATCHES")\r
- set(argumentState 1)\r
- elseif ("x${arg}" STREQUAL "xIGNORE_MATCHES")\r
- set(argumentState 2)\r
- elseif (argumentState EQUAL 0)\r
- list(APPEND LISTS_TO_SEARCH ${arg})\r
- elseif (argumentState EQUAL 1)\r
- list(APPEND MATCHES_TO_REMOVE ${arg})\r
- elseif (argumentState EQUAL 2)\r
- list(APPEND MATCHES_TO_IGNORE ${arg})\r
- else()\r
- message(FATAL_ERROR "Unknown argument state!")\r
- endif()\r
- endforeach()\r
-\r
- foreach (theList ${LISTS_TO_SEARCH})\r
- foreach (entry ${${theList}})\r
- foreach (match ${MATCHES_TO_REMOVE})\r
- if (${entry} MATCHES ${match})\r
- set(SHOULD_IGNORE OFF)\r
- foreach (ign ${MATCHES_TO_IGNORE})\r
- if (${entry} MATCHES ${ign})\r
- set(SHOULD_IGNORE ON)\r
- break()\r
- endif()\r
- endforeach()\r
-\r
- if (NOT SHOULD_IGNORE)\r
- list(REMOVE_ITEM ${theList} ${entry})\r
- endif()\r
- endif()\r
- endforeach()\r
- endforeach()\r
- set(${theList} ${${theList}} PARENT_SCOPE)\r
- endforeach()\r
-endfunction()\r
-\r
-# Automatically create source_group directives for the sources passed in.\r
-function(auto_source_group rootName rootDir)\r
- file(TO_CMAKE_PATH "${rootDir}" rootDir)\r
- string(LENGTH "${rootDir}" rootDirLength)\r
- set(sourceGroups)\r
- foreach (fil ${ARGN})\r
- file(TO_CMAKE_PATH "${fil}" filePath)\r
- string(FIND "${filePath}" "/" rIdx REVERSE)\r
- if (rIdx EQUAL -1)\r
- message(FATAL_ERROR "Unable to locate the final forward slash in '${filePath}'!")\r
- endif()\r
- string(SUBSTRING "${filePath}" 0 ${rIdx} filePath)\r
-\r
- string(LENGTH "${filePath}" filePathLength)\r
- string(FIND "${filePath}" "${rootDir}" rIdx)\r
- if (rIdx EQUAL 0)\r
- math(EXPR filePathLength "${filePathLength} - ${rootDirLength}")\r
- string(SUBSTRING "${filePath}" ${rootDirLength} ${filePathLength} fileGroup)\r
-\r
- string(REPLACE "/" "\\" fileGroup "${fileGroup}")\r
- set(fileGroup "\\${rootName}${fileGroup}")\r
-\r
- list(FIND sourceGroups "${fileGroup}" rIdx)\r
- if (rIdx EQUAL -1)\r
- list(APPEND sourceGroups "${fileGroup}")\r
- source_group("${fileGroup}" REGULAR_EXPRESSION "${filePath}/[^/.]+.(cpp|h)$")\r
- endif()\r
- endif()\r
- endforeach()\r
-endfunction()\r
-\r
-# CMake is a pain and doesn't have an easy way to install only the files\r
-# we actually included in our build :(\r
-function(auto_install_files rootName rootDir)\r
- file(TO_CMAKE_PATH "${rootDir}" rootDir)\r
- string(LENGTH "${rootDir}" rootDirLength)\r
- set(sourceGroups)\r
- foreach (fil ${ARGN})\r
- file(TO_CMAKE_PATH "${fil}" filePath)\r
- string(FIND "${filePath}" "/" rIdx REVERSE)\r
- if (rIdx EQUAL -1)\r
- message(FATAL_ERROR "Unable to locate the final forward slash in '${filePath}'!")\r
- endif()\r
- string(SUBSTRING "${filePath}" 0 ${rIdx} filePath)\r
-\r
- string(LENGTH "${filePath}" filePathLength)\r
- string(FIND "${filePath}" "${rootDir}" rIdx)\r
- if (rIdx EQUAL 0)\r
- math(EXPR filePathLength "${filePathLength} - ${rootDirLength}")\r
- string(SUBSTRING "${filePath}" ${rootDirLength} ${filePathLength} fileGroup)\r
- install(FILES ${fil} DESTINATION include/${rootName}${fileGroup})\r
- endif()\r
- endforeach()\r
-endfunction()\r
-\r
-function(folly_define_tests)\r
- set(directory_count 0)\r
- set(test_count 0)\r
- set(currentArg 0)\r
- while (currentArg LESS ${ARGC})\r
- if ("x${ARGV${currentArg}}" STREQUAL "xDIRECTORY")\r
- math(EXPR currentArg "${currentArg} + 1")\r
- if (NOT currentArg LESS ${ARGC})\r
- message(FATAL_ERROR "Expected base directory!")\r
- endif()\r
-\r
- set(cur_dir ${directory_count})\r
- math(EXPR directory_count "${directory_count} + 1")\r
- set(directory_${cur_dir}_name "${ARGV${currentArg}}")\r
- # We need a single list of sources to get source_group to work nicely.\r
- set(directory_${cur_dir}_source_list)\r
-\r
- math(EXPR currentArg "${currentArg} + 1")\r
- while (currentArg LESS ${ARGC})\r
- if ("x${ARGV${currentArg}}" STREQUAL "xDIRECTORY")\r
- break()\r
- elseif ("x${ARGV${currentArg}}" STREQUAL "xTEST")\r
- math(EXPR currentArg "${currentArg} + 1")\r
- if (NOT currentArg LESS ${ARGC})\r
- message(FATAL_ERROR "Expected test name!")\r
- endif()\r
-\r
- set(cur_test ${test_count})\r
- math(EXPR test_count "${test_count} + 1")\r
- set(test_${cur_test}_name "${ARGV${currentArg}}")\r
- math(EXPR currentArg "${currentArg} + 1")\r
- set(test_${cur_test}_directory ${cur_dir})\r
- set(test_${cur_test}_content_dir)\r
- set(test_${cur_test}_headers)\r
- set(test_${cur_test}_sources)\r
- set(test_${cur_test}_tag "NONE")\r
-\r
- set(argumentState 0)\r
- while (currentArg LESS ${ARGC})\r
- if ("x${ARGV${currentArg}}" STREQUAL "xHEADERS")\r
- set(argumentState 1)\r
- elseif ("x${ARGV${currentArg}}" STREQUAL "xSOURCES")\r
- set(argumentState 2)\r
- elseif ("x${ARGV${currentArg}}" STREQUAL "xCONTENT_DIR")\r
- math(EXPR currentArg "${currentArg} + 1")\r
- if (NOT currentArg LESS ${ARGC})\r
- message(FATAL_ERROR "Expected content directory name!")\r
- endif()\r
- set(test_${cur_test}_content_dir "${ARGV${currentArg}}")\r
- elseif ("x${ARGV${currentArg}}" STREQUAL "xTEST" OR\r
- "x${ARGV${currentArg}}" STREQUAL "xDIRECTORY")\r
- break()\r
- elseif (argumentState EQUAL 0)\r
- if ("x${ARGV${currentArg}}" STREQUAL "xBROKEN")\r
- set(test_${cur_test}_tag "BROKEN")\r
- elseif ("x${ARGV${currentArg}}" STREQUAL "xHANGING")\r
- set(test_${cur_test}_tag "HANGING")\r
- elseif ("x${ARGV${currentArg}}" STREQUAL "xSLOW")\r
- set(test_${cur_test}_tag "SLOW")\r
- else()\r
- message(FATAL_ERROR "Unknown test tag '${ARGV${currentArg}}'!")\r
- endif()\r
- elseif (argumentState EQUAL 1)\r
- list(APPEND test_${cur_test}_headers\r
- "${FOLLY_DIR}/${directory_${cur_dir}_name}${ARGV${currentArg}}"\r
- )\r
- elseif (argumentState EQUAL 2)\r
- list(APPEND test_${cur_test}_sources\r
- "${FOLLY_DIR}/${directory_${cur_dir}_name}${ARGV${currentArg}}"\r
- )\r
- else()\r
- message(FATAL_ERROR "Unknown argument state!")\r
- endif()\r
- math(EXPR currentArg "${currentArg} + 1")\r
- endwhile()\r
-\r
- list(APPEND directory_${cur_dir}_source_list\r
- ${test_${cur_test}_sources} ${test_${cur_test}_headers})\r
- else()\r
- message(FATAL_ERROR "Unknown argument inside directory '${ARGV${currentArg}}'!")\r
- endif()\r
- endwhile()\r
- else()\r
- message(FATAL_ERROR "Unknown argument '${ARGV${currentArg}}'!")\r
- endif()\r
- endwhile()\r
-\r
- set(cur_dir 0)\r
- while (cur_dir LESS directory_count)\r
- source_group("" FILES ${directory_${cur_dir}_source_list})\r
- math(EXPR cur_dir "${cur_dir} + 1")\r
- endwhile()\r
-\r
- set(cur_test 0)\r
- while (cur_test LESS test_count)\r
- if ("x${test_${cur_test}_tag}" STREQUAL "xNONE" OR\r
- ("x${test_${cur_test}_tag}" STREQUAL "xBROKEN" AND BUILD_BROKEN_TESTS) OR\r
- ("x${test_${cur_test}_tag}" STREQUAL "xSLOW" AND BUILD_SLOW_TESTS) OR\r
- ("x${test_${cur_test}_tag}" STREQUAL "xHANGING" AND BUILD_HANGING_TESTS)\r
- )\r
- set(cur_test_name ${test_${cur_test}_name})\r
- set(cur_dir_name ${directory_${test_${cur_test}_directory}_name})\r
- add_executable(${cur_test_name}\r
- ${test_${cur_test}_headers}\r
- ${test_${cur_test}_sources}\r
- )\r
- if (NOT "x${test_${cur_test}_content_dir}" STREQUAL "x")\r
- # Copy the content directory to the output directory tree so that\r
- # tests can be run easily from Visual Studio without having to change\r
- # the working directory for each test individually.\r
- file(\r
- COPY "${FOLLY_DIR}/${cur_dir_name}${test_${cur_test}_content_dir}"\r
- DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/folly/${cur_dir_name}${test_${cur_test}_content_dir}"\r
- )\r
- add_custom_command(TARGET ${cur_test_name} POST_BUILD COMMAND\r
- ${CMAKE_COMMAND} ARGS -E copy_directory\r
- "${FOLLY_DIR}/${cur_dir_name}${test_${cur_test}_content_dir}"\r
- "$<TARGET_FILE_DIR:${cur_test_name}>/folly/${cur_dir_name}${test_${cur_test}_content_dir}"\r
- COMMENT "Copying test content for ${cur_test_name}" VERBATIM\r
- )\r
- endif()\r
- # Strip the tailing test directory name for the folder name.\r
- string(REPLACE "test/" "" test_dir_name "${cur_dir_name}")\r
- set_property(TARGET ${cur_test_name} PROPERTY FOLDER "Tests/${test_dir_name}")\r
- target_link_libraries(${cur_test_name} PRIVATE folly_test_support)\r
- apply_folly_compile_options_to_target(${cur_test_name})\r
- endif()\r
- math(EXPR cur_test "${cur_test} + 1")\r
- endwhile()\r
-endfunction()\r
+function(auto_sources RETURN_VALUE PATTERN SOURCE_SUBDIRS)
+ if ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")
+ SET(PATH ".")
+ if (${ARGC} EQUAL 4)
+ list(GET ARGV 3 PATH)
+ endif ()
+ endif()
+
+ if ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")
+ unset(${RETURN_VALUE})
+ file(GLOB SUBDIR_FILES "${PATH}/${PATTERN}")
+ list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})
+
+ file(GLOB subdirs RELATIVE ${PATH} ${PATH}/*)
+
+ foreach(DIR ${subdirs})
+ if (IS_DIRECTORY ${PATH}/${DIR})
+ if (NOT "${DIR}" STREQUAL "CMakeFiles")
+ file(GLOB_RECURSE SUBDIR_FILES "${PATH}/${DIR}/${PATTERN}")
+ list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})
+ endif()
+ endif()
+ endforeach()
+ else()
+ file(GLOB ${RETURN_VALUE} "${PATTERN}")
+
+ foreach (PATH ${SOURCE_SUBDIRS})
+ file(GLOB SUBDIR_FILES "${PATH}/${PATTERN}")
+ list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})
+ endforeach()
+ endif ()
+
+ set(${RETURN_VALUE} ${${RETURN_VALUE}} PARENT_SCOPE)
+endfunction(auto_sources)
+
+# Remove all files matching a set of patterns, and,
+# optionally, not matching a second set of patterns,
+# from a set of lists.
+#
+# Example:
+# This will remove all files in the CPP_SOURCES list
+# matching "/test/" or "Test.cpp$", but not matching
+# "BobTest.cpp$".
+# REMOVE_MATCHES_FROM_LISTS(CPP_SOURCES MATCHES "/test/" "Test.cpp$" IGNORE_MATCHES "BobTest.cpp$")
+#
+# Parameters:
+#
+# [...]:
+# The names of the lists to remove matches from.
+#
+# [MATCHES ...]:
+# The matches to remove from the lists.
+#
+# [IGNORE_MATCHES ...]:
+# The matches not to remove, even if they match
+# the main set of matches to remove.
+function(REMOVE_MATCHES_FROM_LISTS)
+ set(LISTS_TO_SEARCH)
+ set(MATCHES_TO_REMOVE)
+ set(MATCHES_TO_IGNORE)
+ set(argumentState 0)
+ foreach (arg ${ARGN})
+ if ("x${arg}" STREQUAL "xMATCHES")
+ set(argumentState 1)
+ elseif ("x${arg}" STREQUAL "xIGNORE_MATCHES")
+ set(argumentState 2)
+ elseif (argumentState EQUAL 0)
+ list(APPEND LISTS_TO_SEARCH ${arg})
+ elseif (argumentState EQUAL 1)
+ list(APPEND MATCHES_TO_REMOVE ${arg})
+ elseif (argumentState EQUAL 2)
+ list(APPEND MATCHES_TO_IGNORE ${arg})
+ else()
+ message(FATAL_ERROR "Unknown argument state!")
+ endif()
+ endforeach()
+
+ foreach (theList ${LISTS_TO_SEARCH})
+ foreach (entry ${${theList}})
+ foreach (match ${MATCHES_TO_REMOVE})
+ if (${entry} MATCHES ${match})
+ set(SHOULD_IGNORE OFF)
+ foreach (ign ${MATCHES_TO_IGNORE})
+ if (${entry} MATCHES ${ign})
+ set(SHOULD_IGNORE ON)
+ break()
+ endif()
+ endforeach()
+
+ if (NOT SHOULD_IGNORE)
+ list(REMOVE_ITEM ${theList} ${entry})
+ endif()
+ endif()
+ endforeach()
+ endforeach()
+ set(${theList} ${${theList}} PARENT_SCOPE)
+ endforeach()
+endfunction()
+
+# Automatically create source_group directives for the sources passed in.
+function(auto_source_group rootName rootDir)
+ file(TO_CMAKE_PATH "${rootDir}" rootDir)
+ string(LENGTH "${rootDir}" rootDirLength)
+ set(sourceGroups)
+ foreach (fil ${ARGN})
+ file(TO_CMAKE_PATH "${fil}" filePath)
+ string(FIND "${filePath}" "/" rIdx REVERSE)
+ if (rIdx EQUAL -1)
+ message(FATAL_ERROR "Unable to locate the final forward slash in '${filePath}'!")
+ endif()
+ string(SUBSTRING "${filePath}" 0 ${rIdx} filePath)
+
+ string(LENGTH "${filePath}" filePathLength)
+ string(FIND "${filePath}" "${rootDir}" rIdx)
+ if (rIdx EQUAL 0)
+ math(EXPR filePathLength "${filePathLength} - ${rootDirLength}")
+ string(SUBSTRING "${filePath}" ${rootDirLength} ${filePathLength} fileGroup)
+
+ string(REPLACE "/" "\\" fileGroup "${fileGroup}")
+ set(fileGroup "\\${rootName}${fileGroup}")
+
+ list(FIND sourceGroups "${fileGroup}" rIdx)
+ if (rIdx EQUAL -1)
+ list(APPEND sourceGroups "${fileGroup}")
+ source_group("${fileGroup}" REGULAR_EXPRESSION "${filePath}/[^/.]+.(cpp|h)$")
+ endif()
+ endif()
+ endforeach()
+endfunction()
+
+# CMake is a pain and doesn't have an easy way to install only the files
+# we actually included in our build :(
+function(auto_install_files rootName rootDir)
+ file(TO_CMAKE_PATH "${rootDir}" rootDir)
+ string(LENGTH "${rootDir}" rootDirLength)
+ set(sourceGroups)
+ foreach (fil ${ARGN})
+ file(TO_CMAKE_PATH "${fil}" filePath)
+ string(FIND "${filePath}" "/" rIdx REVERSE)
+ if (rIdx EQUAL -1)
+ message(FATAL_ERROR "Unable to locate the final forward slash in '${filePath}'!")
+ endif()
+ string(SUBSTRING "${filePath}" 0 ${rIdx} filePath)
+
+ string(LENGTH "${filePath}" filePathLength)
+ string(FIND "${filePath}" "${rootDir}" rIdx)
+ if (rIdx EQUAL 0)
+ math(EXPR filePathLength "${filePathLength} - ${rootDirLength}")
+ string(SUBSTRING "${filePath}" ${rootDirLength} ${filePathLength} fileGroup)
+ install(FILES ${fil} DESTINATION include/${rootName}${fileGroup})
+ endif()
+ endforeach()
+endfunction()
+
+function(folly_define_tests)
+ set(directory_count 0)
+ set(test_count 0)
+ set(currentArg 0)
+ while (currentArg LESS ${ARGC})
+ if ("x${ARGV${currentArg}}" STREQUAL "xDIRECTORY")
+ math(EXPR currentArg "${currentArg} + 1")
+ if (NOT currentArg LESS ${ARGC})
+ message(FATAL_ERROR "Expected base directory!")
+ endif()
+
+ set(cur_dir ${directory_count})
+ math(EXPR directory_count "${directory_count} + 1")
+ set(directory_${cur_dir}_name "${ARGV${currentArg}}")
+ # We need a single list of sources to get source_group to work nicely.
+ set(directory_${cur_dir}_source_list)
+
+ math(EXPR currentArg "${currentArg} + 1")
+ while (currentArg LESS ${ARGC})
+ if ("x${ARGV${currentArg}}" STREQUAL "xDIRECTORY")
+ break()
+ elseif ("x${ARGV${currentArg}}" STREQUAL "xTEST")
+ math(EXPR currentArg "${currentArg} + 1")
+ if (NOT currentArg LESS ${ARGC})
+ message(FATAL_ERROR "Expected test name!")
+ endif()
+
+ set(cur_test ${test_count})
+ math(EXPR test_count "${test_count} + 1")
+ set(test_${cur_test}_name "${ARGV${currentArg}}")
+ math(EXPR currentArg "${currentArg} + 1")
+ set(test_${cur_test}_directory ${cur_dir})
+ set(test_${cur_test}_content_dir)
+ set(test_${cur_test}_headers)
+ set(test_${cur_test}_sources)
+ set(test_${cur_test}_tag "NONE")
+
+ set(argumentState 0)
+ while (currentArg LESS ${ARGC})
+ if ("x${ARGV${currentArg}}" STREQUAL "xHEADERS")
+ set(argumentState 1)
+ elseif ("x${ARGV${currentArg}}" STREQUAL "xSOURCES")
+ set(argumentState 2)
+ elseif ("x${ARGV${currentArg}}" STREQUAL "xCONTENT_DIR")
+ math(EXPR currentArg "${currentArg} + 1")
+ if (NOT currentArg LESS ${ARGC})
+ message(FATAL_ERROR "Expected content directory name!")
+ endif()
+ set(test_${cur_test}_content_dir "${ARGV${currentArg}}")
+ elseif ("x${ARGV${currentArg}}" STREQUAL "xTEST" OR
+ "x${ARGV${currentArg}}" STREQUAL "xDIRECTORY")
+ break()
+ elseif (argumentState EQUAL 0)
+ if ("x${ARGV${currentArg}}" STREQUAL "xBROKEN")
+ set(test_${cur_test}_tag "BROKEN")
+ elseif ("x${ARGV${currentArg}}" STREQUAL "xHANGING")
+ set(test_${cur_test}_tag "HANGING")
+ elseif ("x${ARGV${currentArg}}" STREQUAL "xSLOW")
+ set(test_${cur_test}_tag "SLOW")
+ else()
+ message(FATAL_ERROR "Unknown test tag '${ARGV${currentArg}}'!")
+ endif()
+ elseif (argumentState EQUAL 1)
+ list(APPEND test_${cur_test}_headers
+ "${FOLLY_DIR}/${directory_${cur_dir}_name}${ARGV${currentArg}}"
+ )
+ elseif (argumentState EQUAL 2)
+ list(APPEND test_${cur_test}_sources
+ "${FOLLY_DIR}/${directory_${cur_dir}_name}${ARGV${currentArg}}"
+ )
+ else()
+ message(FATAL_ERROR "Unknown argument state!")
+ endif()
+ math(EXPR currentArg "${currentArg} + 1")
+ endwhile()
+
+ list(APPEND directory_${cur_dir}_source_list
+ ${test_${cur_test}_sources} ${test_${cur_test}_headers})
+ else()
+ message(FATAL_ERROR "Unknown argument inside directory '${ARGV${currentArg}}'!")
+ endif()
+ endwhile()
+ else()
+ message(FATAL_ERROR "Unknown argument '${ARGV${currentArg}}'!")
+ endif()
+ endwhile()
+
+ set(cur_dir 0)
+ while (cur_dir LESS directory_count)
+ source_group("" FILES ${directory_${cur_dir}_source_list})
+ math(EXPR cur_dir "${cur_dir} + 1")
+ endwhile()
+
+ set(cur_test 0)
+ while (cur_test LESS test_count)
+ if ("x${test_${cur_test}_tag}" STREQUAL "xNONE" OR
+ ("x${test_${cur_test}_tag}" STREQUAL "xBROKEN" AND BUILD_BROKEN_TESTS) OR
+ ("x${test_${cur_test}_tag}" STREQUAL "xSLOW" AND BUILD_SLOW_TESTS) OR
+ ("x${test_${cur_test}_tag}" STREQUAL "xHANGING" AND BUILD_HANGING_TESTS)
+ )
+ set(cur_test_name ${test_${cur_test}_name})
+ set(cur_dir_name ${directory_${test_${cur_test}_directory}_name})
+ add_executable(${cur_test_name}
+ ${test_${cur_test}_headers}
+ ${test_${cur_test}_sources}
+ )
+ if (HAVE_CMAKE_GTEST)
+ gtest_add_tests(TARGET ${cur_test_name}
+ TEST_PREFIX "${cur_test_name}."
+ TEST_LIST test_cases)
+ set_tests_properties(${test_cases} PROPERTIES TIMEOUT 120)
+ endif()
+ if (NOT "x${test_${cur_test}_content_dir}" STREQUAL "x")
+ # Copy the content directory to the output directory tree so that
+ # tests can be run easily from Visual Studio without having to change
+ # the working directory for each test individually.
+ file(
+ COPY "${FOLLY_DIR}/${cur_dir_name}${test_${cur_test}_content_dir}"
+ DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/folly/${cur_dir_name}${test_${cur_test}_content_dir}"
+ )
+ add_custom_command(TARGET ${cur_test_name} POST_BUILD COMMAND
+ ${CMAKE_COMMAND} ARGS -E copy_directory
+ "${FOLLY_DIR}/${cur_dir_name}${test_${cur_test}_content_dir}"
+ "$<TARGET_FILE_DIR:${cur_test_name}>/folly/${cur_dir_name}${test_${cur_test}_content_dir}"
+ COMMENT "Copying test content for ${cur_test_name}" VERBATIM
+ )
+ endif()
+ # Strip the tailing test directory name for the folder name.
+ string(REPLACE "test/" "" test_dir_name "${cur_dir_name}")
+ set_property(TARGET ${cur_test_name} PROPERTY FOLDER "Tests/${test_dir_name}")
+ target_link_libraries(${cur_test_name} PRIVATE folly_test_support)
+ apply_folly_compile_options_to_target(${cur_test_name})
+ endif()
+ math(EXPR cur_test "${cur_test} + 1")
+ endwhile()
+endfunction()