1#------------------------------------------------------------------------------ 2# Function used to copy arbitrary files matching certain patterns. 3# Usage: 4# copy_files_recursive(<source-dir> 5# DESTINATION <destination-dir> 6# [LABEL "<label to use>"] 7# [OUTPUT "<file generated to mark end of copying>"] 8# [REGEX <regex> [EXCLUDE]] 9# [DEPENDS [depends ...]] 10# ) 11# 12# One can specify multiple REGEX or REGEX <regex> EXCLUDE arguments. 13#------------------------------------------------------------------------------ 14function(copy_files_recursive source-dir) 15 set (dest-dir) 16 set (patterns) 17 set (exclude-patterns) 18 set (output-file) 19 set (extra_depends) 20 set (label "Copying files") 21 22 set (doing "") 23 foreach (arg IN LISTS ARGN) 24 if (arg MATCHES "^(DESTINATION|REGEX|OUTPUT|LABEL|DEPENDS)$") 25 set (doing "${arg}") 26 elseif ("x${doing}" STREQUAL "xDESTINATION") 27 set (doing "") 28 set (dest-dir "${arg}") 29 elseif ("x${doing}" STREQUAL "xREGEX") 30 set (doing "SET") 31 list (APPEND patterns "${arg}") 32 elseif (("x${arg}" STREQUAL "xEXCLUDE") AND ("x${doing}" STREQUAL "xSET")) 33 set (doing "") 34 list (GET patterns -1 cur-pattern) 35 list (REMOVE_AT patterns -1) 36 list (APPEND exclude-patterns "${cur-pattern}") 37 elseif ("x${doing}" STREQUAL "xOUTPUT") 38 set (doing "") 39 set (output-file "${arg}") 40 elseif ("x${doing}" STREQUAL "xLABEL") 41 set (doing "") 42 set (label "${arg}") 43 elseif ("x${doing}" STREQUAL "xDEPENDS") 44 list(APPEND extra_depends "${arg}") 45 else() 46 message(AUTHOR_WARNING "Unknown argument [${arg}]") 47 endif() 48 endforeach() 49 50 file(GLOB_RECURSE _all_files RELATIVE "${source-dir}" "${source-dir}/*") 51 set(extra_args) 52 foreach(_item IN LISTS patterns) 53 # need to escape "\" since we're writing these out to a cmake file. 54 string(REPLACE "\\" "\\\\" _item "${_item}") 55 set(extra_args "${extra_args} REGEX \"${_item}\"") 56 endforeach() 57 foreach(_item IN LISTS exclude-patterns) 58 string(REPLACE "\\" "\\\\" _item "${_item}") 59 set(extra_args "${extra_args} REGEX \"${_item}\" EXCLUDE") 60 endforeach() 61 if(extra_args) 62 set(extra_args "FILES_MATCHING ${extra_args}") 63 endif() 64 set (copy-commands "file(COPY \${SRCDIR} DESTINATION \${OUTDIR} ${extra_args})") 65 66 # Let's now build a list of files matching the selection criteria 67 # so we can add dependencies on those. 68 set(all_files) 69 string(REPLACE ";" "|" match-regex "${patterns}") 70 string(REPLACE ";" "|" exclude-regex "${exclude-patterns}") 71 foreach (_file ${_all_files}) 72 if (exclude-regex AND ("${_file}" MATCHES "${exclude-regex}")) 73 # skip 74 elseif ("${_file}" MATCHES "${match-regex}") 75 set (in-file "${source-dir}/${_file}") 76 list (APPEND all_files ${in-file}) 77 endif() 78 endforeach() 79 80 get_filename_component(_name ${output-file} NAME) 81 set(CMAKE_CONFIGURABLE_FILE_CONTENT ${copy-commands}) 82 configure_file(${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in 83 "${CMAKE_CURRENT_BINARY_DIR}/${_name}.cfr.cmake" @ONLY) 84 unset(CMAKE_CONFIGURABLE_FILE_CONTENT) 85 86 add_custom_command(OUTPUT ${output-file} 87 COMMAND ${CMAKE_COMMAND} -DOUTDIR=${dest-dir} 88 -DSRCDIR=${source-dir}/ 89 -P ${CMAKE_CURRENT_BINARY_DIR}/${_name}.cfr.cmake 90 COMMAND ${CMAKE_COMMAND} -E touch ${output-file} 91 DEPENDS ${all_files} 92 "${CMAKE_CURRENT_BINARY_DIR}/${_name}.cfr.cmake" 93 ${extra_depends} 94 COMMENT ${label} 95 VERBATIM) 96endfunction() 97