blob: 165ae718c69c1c18163fc41888e9b86f995fffc7 [file] [edit]
# 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}")