1 function(auto_sources RETURN_VALUE PATTERN SOURCE_SUBDIRS)
\r
2 if ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")
\r
5 list(GET ARGV 3 PATH)
\r
9 if ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")
\r
10 unset(${RETURN_VALUE})
\r
11 file(GLOB SUBDIR_FILES "${PATH}/${PATTERN}")
\r
12 list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})
\r
14 file(GLOB subdirs RELATIVE ${PATH} ${PATH}/*)
\r
16 foreach(DIR ${subdirs})
\r
17 if (IS_DIRECTORY ${PATH}/${DIR})
\r
18 if (NOT "${DIR}" STREQUAL "CMakeFiles")
\r
19 file(GLOB_RECURSE SUBDIR_FILES "${PATH}/${DIR}/${PATTERN}")
\r
20 list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})
\r
25 file(GLOB ${RETURN_VALUE} "${PATTERN}")
\r
27 foreach (PATH ${SOURCE_SUBDIRS})
\r
28 file(GLOB SUBDIR_FILES "${PATH}/${PATTERN}")
\r
29 list(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})
\r
33 set(${RETURN_VALUE} ${${RETURN_VALUE}} PARENT_SCOPE)
\r
34 endfunction(auto_sources)
\r
36 # Remove all files matching a set of patterns, and,
\r
37 # optionally, not matching a second set of patterns,
\r
38 # from a set of lists.
\r
41 # This will remove all files in the CPP_SOURCES list
\r
42 # matching "/test/" or "Test.cpp$", but not matching
\r
44 # REMOVE_MATCHES_FROM_LISTS(CPP_SOURCES MATCHES "/test/" "Test.cpp$" IGNORE_MATCHES "BobTest.cpp$")
\r
49 # The names of the lists to remove matches from.
\r
52 # The matches to remove from the lists.
\r
54 # [IGNORE_MATCHES ...]:
\r
55 # The matches not to remove, even if they match
\r
56 # the main set of matches to remove.
\r
57 function(REMOVE_MATCHES_FROM_LISTS)
\r
58 set(LISTS_TO_SEARCH)
\r
59 set(MATCHES_TO_REMOVE)
\r
60 set(MATCHES_TO_IGNORE)
\r
61 set(argumentState 0)
\r
62 foreach (arg ${ARGN})
\r
63 if ("x${arg}" STREQUAL "xMATCHES")
\r
64 set(argumentState 1)
\r
65 elseif ("x${arg}" STREQUAL "xIGNORE_MATCHES")
\r
66 set(argumentState 2)
\r
67 elseif (argumentState EQUAL 0)
\r
68 list(APPEND LISTS_TO_SEARCH ${arg})
\r
69 elseif (argumentState EQUAL 1)
\r
70 list(APPEND MATCHES_TO_REMOVE ${arg})
\r
71 elseif (argumentState EQUAL 2)
\r
72 list(APPEND MATCHES_TO_IGNORE ${arg})
\r
74 message(FATAL_ERROR "Unknown argument state!")
\r
78 foreach (theList ${LISTS_TO_SEARCH})
\r
79 foreach (entry ${${theList}})
\r
80 foreach (match ${MATCHES_TO_REMOVE})
\r
81 if (${entry} MATCHES ${match})
\r
82 set(SHOULD_IGNORE OFF)
\r
83 foreach (ign ${MATCHES_TO_IGNORE})
\r
84 if (${entry} MATCHES ${ign})
\r
85 set(SHOULD_IGNORE ON)
\r
90 if (NOT SHOULD_IGNORE)
\r
91 list(REMOVE_ITEM ${theList} ${entry})
\r
96 set(${theList} ${${theList}} PARENT_SCOPE)
\r
100 # Automatically create source_group directives for the sources passed in.
\r
101 function(auto_source_group rootName rootDir)
\r
102 file(TO_CMAKE_PATH "${rootDir}" rootDir)
\r
103 string(LENGTH "${rootDir}" rootDirLength)
\r
105 foreach (fil ${ARGN})
\r
106 file(TO_CMAKE_PATH "${fil}" filePath)
\r
107 string(FIND "${filePath}" "/" rIdx REVERSE)
\r
109 message(FATAL_ERROR "Unable to locate the final forward slash in '${filePath}'!")
\r
111 string(SUBSTRING "${filePath}" 0 ${rIdx} filePath)
\r
113 string(LENGTH "${filePath}" filePathLength)
\r
114 string(FIND "${filePath}" "${rootDir}" rIdx)
\r
116 math(EXPR filePathLength "${filePathLength} - ${rootDirLength}")
\r
117 string(SUBSTRING "${filePath}" ${rootDirLength} ${filePathLength} fileGroup)
\r
119 string(REPLACE "/" "\\" fileGroup "${fileGroup}")
\r
120 set(fileGroup "\\${rootName}${fileGroup}")
\r
122 list(FIND sourceGroups "${fileGroup}" rIdx)
\r
124 list(APPEND sourceGroups "${fileGroup}")
\r
125 source_group("${fileGroup}" REGULAR_EXPRESSION "${filePath}/[^/.]+.(cpp|h)$")
\r
131 # CMake is a pain and doesn't have an easy way to install only the files
\r
132 # we actually included in our build :(
\r
133 function(auto_install_files rootName rootDir)
\r
134 file(TO_CMAKE_PATH "${rootDir}" rootDir)
\r
135 string(LENGTH "${rootDir}" rootDirLength)
\r
137 foreach (fil ${ARGN})
\r
138 file(TO_CMAKE_PATH "${fil}" filePath)
\r
139 string(FIND "${filePath}" "/" rIdx REVERSE)
\r
141 message(FATAL_ERROR "Unable to locate the final forward slash in '${filePath}'!")
\r
143 string(SUBSTRING "${filePath}" 0 ${rIdx} filePath)
\r
145 string(LENGTH "${filePath}" filePathLength)
\r
146 string(FIND "${filePath}" "${rootDir}" rIdx)
\r
148 math(EXPR filePathLength "${filePathLength} - ${rootDirLength}")
\r
149 string(SUBSTRING "${filePath}" ${rootDirLength} ${filePathLength} fileGroup)
\r
150 install(FILES ${fil} DESTINATION include/${rootName}${fileGroup})
\r
155 function(folly_define_tests)
\r
156 set(directory_count 0)
\r
159 while (currentArg LESS ${ARGC})
\r
160 if ("x${ARGV${currentArg}}" STREQUAL "xDIRECTORY")
\r
161 math(EXPR currentArg "${currentArg} + 1")
\r
162 if (NOT currentArg LESS ${ARGC})
\r
163 message(FATAL_ERROR "Expected base directory!")
\r
166 set(cur_dir ${directory_count})
\r
167 math(EXPR directory_count "${directory_count} + 1")
\r
168 set(directory_${cur_dir}_name "${ARGV${currentArg}}")
\r
169 # We need a single list of sources to get source_group to work nicely.
\r
170 set(directory_${cur_dir}_source_list)
\r
172 math(EXPR currentArg "${currentArg} + 1")
\r
173 while (currentArg LESS ${ARGC})
\r
174 if ("x${ARGV${currentArg}}" STREQUAL "xDIRECTORY")
\r
176 elseif ("x${ARGV${currentArg}}" STREQUAL "xTEST")
\r
177 math(EXPR currentArg "${currentArg} + 1")
\r
178 if (NOT currentArg LESS ${ARGC})
\r
179 message(FATAL_ERROR "Expected test name!")
\r
182 set(cur_test ${test_count})
\r
183 math(EXPR test_count "${test_count} + 1")
\r
184 set(test_${cur_test}_name "${ARGV${currentArg}}")
\r
185 math(EXPR currentArg "${currentArg} + 1")
\r
186 set(test_${cur_test}_directory ${cur_dir})
\r
187 set(test_${cur_test}_content_dir)
\r
188 set(test_${cur_test}_headers)
\r
189 set(test_${cur_test}_sources)
\r
190 set(test_${cur_test}_tag "NONE")
\r
192 set(argumentState 0)
\r
193 while (currentArg LESS ${ARGC})
\r
194 if ("x${ARGV${currentArg}}" STREQUAL "xHEADERS")
\r
195 set(argumentState 1)
\r
196 elseif ("x${ARGV${currentArg}}" STREQUAL "xSOURCES")
\r
197 set(argumentState 2)
\r
198 elseif ("x${ARGV${currentArg}}" STREQUAL "xCONTENT_DIR")
\r
199 math(EXPR currentArg "${currentArg} + 1")
\r
200 if (NOT currentArg LESS ${ARGC})
\r
201 message(FATAL_ERROR "Expected content directory name!")
\r
203 set(test_${cur_test}_content_dir "${ARGV${currentArg}}")
\r
204 elseif ("x${ARGV${currentArg}}" STREQUAL "xTEST" OR
\r
205 "x${ARGV${currentArg}}" STREQUAL "xDIRECTORY")
\r
207 elseif (argumentState EQUAL 0)
\r
208 if ("x${ARGV${currentArg}}" STREQUAL "xBROKEN")
\r
209 set(test_${cur_test}_tag "BROKEN")
\r
210 elseif ("x${ARGV${currentArg}}" STREQUAL "xHANGING")
\r
211 set(test_${cur_test}_tag "HANGING")
\r
212 elseif ("x${ARGV${currentArg}}" STREQUAL "xSLOW")
\r
213 set(test_${cur_test}_tag "SLOW")
\r
215 message(FATAL_ERROR "Unknown test tag '${ARGV${currentArg}}'!")
\r
217 elseif (argumentState EQUAL 1)
\r
218 list(APPEND test_${cur_test}_headers
\r
219 "${FOLLY_DIR}/${directory_${cur_dir}_name}${ARGV${currentArg}}"
\r
221 elseif (argumentState EQUAL 2)
\r
222 list(APPEND test_${cur_test}_sources
\r
223 "${FOLLY_DIR}/${directory_${cur_dir}_name}${ARGV${currentArg}}"
\r
226 message(FATAL_ERROR "Unknown argument state!")
\r
228 math(EXPR currentArg "${currentArg} + 1")
\r
231 list(APPEND directory_${cur_dir}_source_list
\r
232 ${test_${cur_test}_sources} ${test_${cur_test}_headers})
\r
234 message(FATAL_ERROR "Unknown argument inside directory '${ARGV${currentArg}}'!")
\r
238 message(FATAL_ERROR "Unknown argument '${ARGV${currentArg}}'!")
\r
243 while (cur_dir LESS directory_count)
\r
244 source_group("" FILES ${directory_${cur_dir}_source_list})
\r
245 math(EXPR cur_dir "${cur_dir} + 1")
\r
249 while (cur_test LESS test_count)
\r
250 if ("x${test_${cur_test}_tag}" STREQUAL "xNONE" OR
\r
251 ("x${test_${cur_test}_tag}" STREQUAL "xBROKEN" AND BUILD_BROKEN_TESTS) OR
\r
252 ("x${test_${cur_test}_tag}" STREQUAL "xSLOW" AND BUILD_SLOW_TESTS) OR
\r
253 ("x${test_${cur_test}_tag}" STREQUAL "xHANGING" AND BUILD_HANGING_TESTS)
\r
255 set(cur_test_name ${test_${cur_test}_name})
\r
256 set(cur_dir_name ${directory_${test_${cur_test}_directory}_name})
\r
257 add_executable(${cur_test_name}
\r
258 ${test_${cur_test}_headers}
\r
259 ${test_${cur_test}_sources}
\r
261 if (NOT "x${test_${cur_test}_content_dir}" STREQUAL "x")
\r
262 # Copy the content directory to the output directory tree so that
\r
263 # tests can be run easily from Visual Studio without having to change
\r
264 # the working directory for each test individually.
\r
266 COPY "${FOLLY_DIR}/${cur_dir_name}${test_${cur_test}_content_dir}"
\r
267 DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/folly/${cur_dir_name}${test_${cur_test}_content_dir}"
\r
269 add_custom_command(TARGET ${cur_test_name} POST_BUILD COMMAND
\r
270 ${CMAKE_COMMAND} ARGS -E copy_directory
\r
271 "${FOLLY_DIR}/${cur_dir_name}${test_${cur_test}_content_dir}"
\r
272 "$<TARGET_FILE_DIR:${cur_test_name}>/folly/${cur_dir_name}${test_${cur_test}_content_dir}"
\r
273 COMMENT "Copying test content for ${cur_test_name}" VERBATIM
\r
276 # Strip the tailing test directory name for the folder name.
\r
277 string(REPLACE "test/" "" test_dir_name "${cur_dir_name}")
\r
278 set_property(TARGET ${cur_test_name} PROPERTY FOLDER "Tests/${test_dir_name}")
\r
279 target_link_libraries(${cur_test_name} PRIVATE folly_test_support)
\r
280 apply_folly_compile_options_to_target(${cur_test_name})
\r
282 math(EXPR cur_test "${cur_test} + 1")
\r