| # Synchronize a documentation source tree into an intermediate Sphinx source | |
| # tree. | |
| # | |
| # Usage: | |
| # | |
| # cmake -DSOURCE_DIR=/path/to/project/docs \ | |
| # -DDESTINATION_DIR=/path/to/build/project/docs \ | |
| # -DFILE_LIST=/path/to/build/file-list.txt \ | |
| # -DPRESERVE_FILE=/path/to/build/preserve.txt \ | |
| # -DMANIFEST_FILE=/path/to/build/manifest.txt \ | |
| # -DDEPFILE=/path/to/build/sync.d \ | |
| # -DSTAMP_FILE=/path/to/build/sync.stamp \ | |
| # -P /path/to/SphinxSourceSync.cmake | |
| # | |
| # The sync copies all source files into DESTINATION_DIR, avoids rewriting files | |
| # whose contents are unchanged, and removes stale .rst and .md files that no | |
| # longer exist under SOURCE_DIR unless they are listed in PRESERVE_FILE. This | |
| # is intended for Sphinx builds that merge checked-in docs with generated docs | |
| # in a build-tree source directory. | |
| include("${CMAKE_CURRENT_LIST_DIR}/SphinxSourceUtils.cmake") | |
| if (NOT DEFINED SOURCE_DIR) | |
| message(FATAL_ERROR "SOURCE_DIR must be set") | |
| endif() | |
| if (NOT DEFINED DESTINATION_DIR) | |
| message(FATAL_ERROR "DESTINATION_DIR must be set") | |
| endif() | |
| if (NOT DEFINED FILE_LIST) | |
| message(FATAL_ERROR "FILE_LIST must be set") | |
| endif() | |
| if (NOT DEFINED PRESERVE_FILE) | |
| message(FATAL_ERROR "PRESERVE_FILE must be set") | |
| endif() | |
| if (NOT DEFINED MANIFEST_FILE) | |
| message(FATAL_ERROR "MANIFEST_FILE must be set") | |
| endif() | |
| if (NOT DEFINED DEPFILE) | |
| message(FATAL_ERROR "DEPFILE must be set") | |
| endif() | |
| if (NOT DEFINED STAMP_FILE) | |
| message(FATAL_ERROR "STAMP_FILE must be set") | |
| endif() | |
| file(MAKE_DIRECTORY "${DESTINATION_DIR}") | |
| file(STRINGS "${FILE_LIST}" source_files) | |
| file(STRINGS "${PRESERVE_FILE}" preserve_docs) | |
| set(depfile_dependencies) | |
| set(source_docs) | |
| foreach(relative_path IN LISTS source_files) | |
| set(source_path "${SOURCE_DIR}/${relative_path}") | |
| set(destination_path "${DESTINATION_DIR}/${relative_path}") | |
| get_filename_component(destination_parent "${destination_path}" DIRECTORY) | |
| file(MAKE_DIRECTORY "${destination_parent}") | |
| # configure_file(COPYONLY) preserves mtimes for unchanged files and avoids | |
| # the subprocess overhead of cmake -E copy_if_different. | |
| configure_file("${source_path}" "${destination_path}" COPYONLY) | |
| list(APPEND depfile_dependencies "${source_path}") | |
| string(TOLOWER "${relative_path}" lower_relative_path) | |
| if (lower_relative_path MATCHES "\\.(rst|md)$") | |
| list(APPEND source_docs "${relative_path}") | |
| endif() | |
| endforeach() | |
| file(GLOB_RECURSE destination_docs | |
| LIST_DIRECTORIES false | |
| RELATIVE "${DESTINATION_DIR}" | |
| "${DESTINATION_DIR}/*.rst" | |
| "${DESTINATION_DIR}/*.md") | |
| foreach(relative_path IN LISTS destination_docs) | |
| list(FIND source_docs "${relative_path}" source_index) | |
| list(FIND preserve_docs "${relative_path}" preserve_index) | |
| # Generated docs are absent from SOURCE_DIR, but callers list them in | |
| # PRESERVE_FILE so stale-source cleanup does not remove build outputs. | |
| if (source_index EQUAL -1 AND preserve_index EQUAL -1) | |
| file(REMOVE "${DESTINATION_DIR}/${relative_path}") | |
| endif() | |
| endforeach() | |
| set(manifest_contents) | |
| foreach(relative_path IN LISTS source_docs) | |
| string(APPEND manifest_contents "${relative_path}\n") | |
| endforeach() | |
| write_if_changed("${MANIFEST_FILE}" "${manifest_contents}") | |
| escape_depfile_path("${STAMP_FILE}" escaped_stamp) | |
| set(depfile_contents "${escaped_stamp}:") | |
| foreach(source_path IN LISTS depfile_dependencies) | |
| escape_depfile_path("${source_path}" escaped_source_path) | |
| string(APPEND depfile_contents " ${escaped_source_path}") | |
| endforeach() | |
| string(APPEND depfile_contents "\n") | |
| file(WRITE "${DEPFILE}" "${depfile_contents}") | |
| get_filename_component(stamp_dir "${STAMP_FILE}" DIRECTORY) | |
| file(MAKE_DIRECTORY "${stamp_dir}") | |
| file(TOUCH "${STAMP_FILE}") |