From 8842a0272b541c0e641c8132070828c3d579d1ea Mon Sep 17 00:00:00 2001
From: Craig Scott <craig.scott@crascit.com>
Date: Sun, 9 Jul 2017 20:40:34 +1000
Subject: ExternalProject: Improve documentation

- Added clearer structure by grouping the options into logical sections.
- Expanded the details for many of the options.
- Added Examples section to show how to use the various commands.
- Specifically highlighted that the contents of SOURCE_DIR may be lost
  if a download method is also provided.
- Updated argument-matching regex to be more robust and account for the
  varying leading spaces before keywords in the docs.
- Updated tests to account for slightly changed error messages.
---
 Modules/ExternalProject.cmake                      | 1195 ++++++++++++++------
 .../RunCMake/ExternalProject/NoOptions-stderr.txt  |    4 +-
 .../ExternalProject/SourceEmpty-stderr.txt         |    4 +-
 .../ExternalProject/SourceMissing-stderr.txt       |    4 +-
 4 files changed, 827 insertions(+), 380 deletions(-)

diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 2495736..d92eb5f 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -5,413 +5,860 @@
 ExternalProject
 ---------------
 
-Create custom targets to build projects in external trees
+.. only:: html
+
+   .. contents::
+
+External Project Definition
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 .. command:: ExternalProject_Add
 
-  The ``ExternalProject_Add`` function creates a custom target to drive
+  The ``ExternalProject_Add()`` function creates a custom target to drive
   download, update/patch, configure, build, install and test steps of an
   external project::
 
-   ExternalProject_Add(<name> [<option>...])
-
-  General options are:
-
-  ``DEPENDS <projects>...``
-    Targets on which the project depends
-  ``PREFIX <dir>``
-    Root dir for entire project
-  ``LIST_SEPARATOR <sep>``
-    Sep to be replaced by ; in cmd lines
-  ``TMP_DIR <dir>``
-    Directory to store temporary files
-  ``STAMP_DIR <dir>``
-    Directory to store step timestamps
-  ``EXCLUDE_FROM_ALL 1``
-    The "all" target does not depend on this
-
-  Download step options are:
-
-  ``DOWNLOAD_NAME <fname>``
-    File name to store (if not end of URL)
-  ``DOWNLOAD_DIR <dir>``
-    Directory to store downloaded files
-  ``DOWNLOAD_COMMAND <cmd>...``
-    Command to download source tree
-  ``DOWNLOAD_NO_PROGRESS 1``
-    Disable download progress reports
-  ``CVS_REPOSITORY <cvsroot>``
-    CVSROOT of CVS repository
-  ``CVS_MODULE <mod>``
-    Module to checkout from CVS repo
-  ``CVS_TAG <tag>``
-    Tag to checkout from CVS repo
-  ``SVN_REPOSITORY <url>``
-    URL of Subversion repo
-  ``SVN_REVISION -r<rev>``
-    Revision to checkout from Subversion repo
-  ``SVN_USERNAME <username>``
-    Username for Subversion checkout and update
-  ``SVN_PASSWORD <password>``
-    Password for Subversion checkout and update
-  ``SVN_TRUST_CERT 1``
-    Trust the Subversion server site certificate
-  ``GIT_REPOSITORY <url>``
-    URL of git repo
-  ``GIT_TAG <tag>``
-    Git branch name, commit id or tag
-  ``GIT_REMOTE_NAME <name>``
-    The optional name of the remote, default to ``origin``
-  ``GIT_SUBMODULES <module>...``
-    Git submodules that shall be updated, all if empty
-  ``GIT_SHALLOW 1``
-    Tell Git to clone with ``--depth 1``.  Use when ``GIT_TAG`` is not
-    specified or when it names a branch in order to download only the
-    tip of the branch without the rest of its history.
-  ``GIT_PROGRESS 1``
-    Tell Git to clone with ``--progress``.  For large projects, the clone step
-    does not output anything which can make the build appear to have stalled.
-    This option forces Git to output progress information during the clone step
-    so that forward progress is indicated.
-  ``GIT_CONFIG <option>...``
-    Tell Git to clone with ``--config <option>``.  Use additional configuration
-    parameters when cloning the project (``key=value`` as expected by ``git
-    config``).
-  ``HG_REPOSITORY <url>``
-    URL of mercurial repo
-  ``HG_TAG <tag>``
-    Mercurial branch name, commit id or tag
-  ``URL /.../src.tgz [/.../src.tgz]...``
-    Full path or URL(s) of source.  Multiple URLs are allowed as mirrors.
-  ``URL_HASH ALGO=value``
-    Hash of file at URL
-  ``URL_MD5 md5``
-    Equivalent to URL_HASH MD5=md5
-  ``HTTP_USERNAME <username>``
-    Username for download operation
-  ``HTTP_PASSWORD <username>``
-    Password for download operation
-  ``HTTP_HEADER <header>``
-    HTTP header for download operation. Suboption can be repeated several times.
-  ``TLS_VERIFY <bool>``
-    Should certificate for https be checked
-  ``TLS_CAINFO <file>``
-    Path to a certificate authority file
-  ``TIMEOUT <seconds>``
-    Time allowed for file download operations
-  ``DOWNLOAD_NO_EXTRACT 1``
-    Just download the file and do not extract it; the full path to the
-    downloaded file is available as ``<DOWNLOADED_FILE>``.
-
-  Update/Patch step options are:
-
-  ``UPDATE_COMMAND <cmd>...``
-    Source work-tree update command
-  ``UPDATE_DISCONNECTED 1``
-    Never update automatically from the remote repository
-  ``PATCH_COMMAND <cmd>...``
-    Command to patch downloaded source
-
-  Configure step options are:
-
-  ``SOURCE_DIR <dir>``
-    Source dir to be used for build
-  ``SOURCE_SUBDIR <dir>``
-    Path to source CMakeLists.txt relative to ``SOURCE_DIR``
-  ``CONFIGURE_COMMAND <cmd>...``
-    Build tree configuration command
-  ``CMAKE_COMMAND /.../cmake``
-    Specify alternative cmake executable
-  ``CMAKE_GENERATOR <gen>``
-    Specify generator for native build
-  ``CMAKE_GENERATOR_PLATFORM <platform>``
-    Generator-specific platform name
-  ``CMAKE_GENERATOR_TOOLSET <toolset>``
-    Generator-specific toolset name
-  ``CMAKE_ARGS <arg>...``
-    Arguments to CMake command line.
-    These arguments are passed to CMake command line, and can contain
-    arguments other than cache values, see also
-    :manual:`CMake Options <cmake(1)>`. Arguments in the form
-    ``-Dvar:string=on`` are always passed to the command line, and
-    therefore cannot be changed by the user.
-    Arguments may use
-    :manual:`generator expressions <cmake-generator-expressions(7)>`.
-  ``CMAKE_CACHE_ARGS <arg>...``
-    Initial cache arguments, of the form ``-Dvar:string=on``.
-    These arguments are written in a pre-load a script that populates
-    CMake cache, see also :manual:`cmake -C <cmake(1)>`. This allows one to
-    overcome command line length limits.
-    These arguments are :command:`set` using the ``FORCE`` argument,
-    and therefore cannot be changed by the user.
-    Arguments may use
-    :manual:`generator expressions <cmake-generator-expressions(7)>`.
-  ``CMAKE_CACHE_DEFAULT_ARGS <arg>...``
-    Initial default cache arguments, of the form ``-Dvar:string=on``.
-    These arguments are written in a pre-load a script that populates
-    CMake cache, see also :manual:`cmake -C <cmake(1)>`. This allows one to
-    overcome command line length limits.
-    These arguments can be used as default value that will be set if no
-    previous value is found in the cache, and that the user can change
-    later.
-    Arguments may use
-    :manual:`generator expressions <cmake-generator-expressions(7)>`.
-
-  Build step options are:
-
-  ``BINARY_DIR <dir>``
-    Specify build dir location
-  ``BUILD_COMMAND <cmd>...``
-    Command to drive the native build
-  ``BUILD_IN_SOURCE 1``
-    Use source dir for build dir
-  ``BUILD_ALWAYS 1``
-    No stamp file, build step always runs
-  ``BUILD_BYPRODUCTS <file>...``
-    Files that will be generated by the build command but may or may
-    not have their modification time updated by subsequent builds.
-
-  Install step options are:
-
-  ``INSTALL_DIR <dir>``
-    Installation prefix to be placed in the ``<INSTALL_DIR>`` placeholder.
-    This does not actually configure the external project to install to
-    the given prefix.  That must be done by passing appropriate arguments
-    to the external project configuration step, e.g. using ``<INSTALL_DIR>``.
-  ``INSTALL_COMMAND <cmd>...``
-    Command to drive installation of the external project after it has been
-    built.  This only happens at the *build* time of the calling project.
-    In order to install files from the external project alongside the
-    locally-built files, a separate local :command:`install` call must be
-    added to pick the files up from one of the external project trees.
-
-  Test step options are:
-
-  ``TEST_BEFORE_INSTALL 1``
-    Add test step executed before install step
-  ``TEST_AFTER_INSTALL 1``
-    Add test step executed after install step
-  ``TEST_EXCLUDE_FROM_MAIN 1``
-    Main target does not depend on the test step
-  ``TEST_COMMAND <cmd>...``
-    Command to drive test
-
-  Output logging options are:
-
-  ``LOG_DOWNLOAD 1``
-    Wrap download in script to log output
-  ``LOG_UPDATE 1``
-    Wrap update in script to log output
-  ``LOG_CONFIGURE 1``
-    Wrap configure in script to log output
-  ``LOG_BUILD 1``
-    Wrap build in script to log output
-  ``LOG_TEST 1``
-    Wrap test in script to log output
-  ``LOG_INSTALL 1``
-    Wrap install in script to log output
-
-  Steps can be given direct access to the terminal if possible.  With
-  the :generator:`Ninja` generator, this places the steps in the
-  ``console`` :prop_gbl:`pool <JOB_POOLS>`.  Options are:
-
-  ``USES_TERMINAL_DOWNLOAD 1``
-    Give download terminal access.
-  ``USES_TERMINAL_UPDATE 1``
-    Give update terminal access.
-  ``USES_TERMINAL_CONFIGURE 1``
-    Give configure terminal access.
-  ``USES_TERMINAL_BUILD 1``
-    Give build terminal access.
-  ``USES_TERMINAL_TEST 1``
-    Give test terminal access.
-  ``USES_TERMINAL_INSTALL 1``
-    Give install terminal access.
-
-  Other options are:
-
-  ``STEP_TARGETS <step-target>...``
-    Generate custom targets for these steps
-  ``INDEPENDENT_STEP_TARGETS <step-target>...``
-    Generate custom targets for these steps that do not depend on other
-    external projects even if a dependency is set
-
-  The ``*_DIR`` options specify directories for the project, with default
-  directories computed as follows.  If the ``PREFIX`` option is given to
-  ``ExternalProject_Add()`` or the ``EP_PREFIX`` directory property is set,
-  then an external project is built and installed under the specified prefix::
-
-   TMP_DIR      = <prefix>/tmp
-   STAMP_DIR    = <prefix>/src/<name>-stamp
-   DOWNLOAD_DIR = <prefix>/src
-   SOURCE_DIR   = <prefix>/src/<name>
-   BINARY_DIR   = <prefix>/src/<name>-build
-   INSTALL_DIR  = <prefix>
-
-  Otherwise, if the ``EP_BASE`` directory property is set then components
-  of an external project are stored under the specified base::
-
-   TMP_DIR      = <base>/tmp/<name>
-   STAMP_DIR    = <base>/Stamp/<name>
-   DOWNLOAD_DIR = <base>/Download/<name>
-   SOURCE_DIR   = <base>/Source/<name>
-   BINARY_DIR   = <base>/Build/<name>
-   INSTALL_DIR  = <base>/Install/<name>
-
-  If no ``PREFIX``, ``EP_PREFIX``, or ``EP_BASE`` is specified then the
-  default is to set ``PREFIX`` to ``<name>-prefix``.  Relative paths are
-  interpreted with respect to the build directory corresponding to the
-  source directory in which ``ExternalProject_Add`` is invoked.
-
-  If ``SOURCE_SUBDIR`` is set and no ``CONFIGURE_COMMAND`` is specified, the
-  configure command will run CMake using the ``CMakeLists.txt`` located in the
-  relative path specified by ``SOURCE_SUBDIR``, relative to the ``SOURCE_DIR``.
-  If no ``SOURCE_SUBDIR`` is given, ``SOURCE_DIR`` is used.
-
-  If ``SOURCE_DIR`` is explicitly set to an existing directory the project
-  will be built from it.  Otherwise a download step must be specified
-  using one of the ``DOWNLOAD_COMMAND``, ``CVS_*``, ``SVN_*``, or ``URL``
-  options.  The ``URL`` option may refer locally to a directory or source
-  tarball, or refer to a remote tarball (e.g. ``http://.../src.tgz``).
-
-  If ``UPDATE_DISCONNECTED`` is set, the update step is not executed
-  automatically when building the main target. The update step can still
-  be added as a step target and called manually. This is useful if you
-  want to allow one to build the project when you are disconnected from the
-  network (you might still need the network for the download step).
-  This is disabled by default.
-  The directory property ``EP_UPDATE_DISCONNECTED`` can be used to change
-  the default value for all the external projects in the current
-  directory and its subdirectories.
+    ExternalProject_Add(<name> [<option>...])
+
+  The individual steps within the process can be driven independently if
+  required (e.g. for CDash submission) and extra custom steps can be defined,
+  along with the ability to control the step dependencies. The directory
+  structure used for the management of the external project can also be
+  customized. The function supports a large number of options which can be used
+  to tailor the external project behavior.
+
+  **Directory Options:**
+    Most of the time, the default directory layout is sufficient. It is largely
+    an implementation detail that the main project usually doesn't need to
+    change. In some circumstances, however, control over the directory layout
+    can be useful or necessary. The directory options are potentially more
+    useful from the point of view that the main build can use the
+    :command:`ExternalProject_Get_Property` command to retrieve their values,
+    thereby allowing the main project to refer to build artifacts of the
+    external project.
+
+    ``PREFIX <dir>``
+      Root directory for the external project. Unless otherwise noted below,
+      all other directories associated with the external project will be
+      created under here.
+
+    ``TMP_DIR <dir>``
+      Directory in which to store temporary files.
+
+    ``STAMP_DIR <dir>``
+      Directory in which to store the timestamps of each step. Log files from
+      individual steps are also created in here (see *Logging Options* below).
+
+    ``DOWNLOAD_DIR <dir>``
+      Directory in which to store downloaded files before unpacking them. This
+      directory is only used by the URL download method, all other download
+      methods use ``SOURCE_DIR`` directly instead.
+
+    ``SOURCE_DIR <dir>``
+      Source directory into which downloaded contents will be unpacked, or for
+      non-URL download methods, the directory in which the repository should be
+      checked out, cloned, etc. If no download method is specified, this must
+      point to an existing directory where the external project has already
+      been unpacked or cloned/checked out.
+
+      .. note::
+         If a download method is specified, any existing contents of the source
+         directory may be deleted. Only the URL download method checks whether
+         this directory is either missing or empty before initiating the
+         download, stopping with an error if it is not empty. All other
+         download methods silently discard any previous contents of the source
+         directory.
+
+    ``BINARY_DIR <dir>``
+      Specify the build directory location. This option is ignored if
+      ``BUILD_IN_SOURCE`` is enabled.
+
+    ``INSTALL_DIR <dir>``
+      Installation prefix to be placed in the ``<INSTALL_DIR>`` placeholder.
+      This does not actually configure the external project to install to
+      the given prefix. That must be done by passing appropriate arguments
+      to the external project configuration step, e.g. using ``<INSTALL_DIR>``.
+
+    If any of the above ``..._DIR`` options are not specified, their defaults
+    are computed as follows. If the ``PREFIX`` option is given or the
+    ``EP_PREFIX`` directory property is set, then an external project is built
+    and installed under the specified prefix::
+
+      TMP_DIR      = <prefix>/tmp
+      STAMP_DIR    = <prefix>/src/<name>-stamp
+      DOWNLOAD_DIR = <prefix>/src
+      SOURCE_DIR   = <prefix>/src/<name>
+      BINARY_DIR   = <prefix>/src/<name>-build
+      INSTALL_DIR  = <prefix>
+
+    Otherwise, if the ``EP_BASE`` directory property is set then components
+    of an external project are stored under the specified base::
+
+      TMP_DIR      = <base>/tmp/<name>
+      STAMP_DIR    = <base>/Stamp/<name>
+      DOWNLOAD_DIR = <base>/Download/<name>
+      SOURCE_DIR   = <base>/Source/<name>
+      BINARY_DIR   = <base>/Build/<name>
+      INSTALL_DIR  = <base>/Install/<name>
+
+    If no ``PREFIX``, ``EP_PREFIX``, or ``EP_BASE`` is specified, then the
+    default is to set ``PREFIX`` to ``<name>-prefix``. Relative paths are
+    interpreted with respect to :variable:`CMAKE_CURRENT_BINARY_DIR` at the
+    point where ``ExternalProject_Add()`` is called.
+
+  **Download Step Options:**
+    A download method can be omitted if the ``SOURCE_DIR`` option is used to
+    point to an existing non-empty directory. Otherwise, one of the download
+    methods below must be specified (multiple download methods should not be
+    given) or a custom ``DOWNLOAD_COMMAND`` provided.
+
+    ``DOWNLOAD_COMMAND <cmd>...``
+      Overrides the command used for the download step
+      (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+      supported). If this option is specified, all other download options will
+      be ignored. Providing an empty string for ``<cmd>`` effectively disables
+      the download step.
+
+    *URL Download*
+      ``URL <url1> [<url2>...]``
+        List of paths and/or URL(s) of the external project's source. When more
+        than one URL is given, they are tried in turn until one succeeds. A URL
+        may be an ordinary path in the local file system (in which case it
+        must be the only URL provided) or any downloadable URL supported by the
+        :command:`file(DOWNLOAD)` command. A local filesystem path may refer to
+        either an existing directory or to an archive file, whereas a URL is
+        expected to point to a file which can be treated as an archive. When an
+        archive is used, it will be unpacked automatically unless the
+        ``DOWNLOAD_NO_EXTRACT`` option is set to prevent it. The archive type
+        is determined by inspecting the actual content rather than using logic
+        based on the file extension.
+
+      ``URL_HASH ALGO=<value>``
+        Hash of the archive file to be downloaded. The ``<value>`` should be of
+        the form ``algo=hashValue`` where ``algo`` can be any of the hashing
+        algorithms supported by the :command:`file()` command. Specifying this
+        option is strongly recommended for URL downloads, as it ensures the
+        integrity of the downloaded content. It is also used as a check for a
+        previously downloaded file, allowing connection to the remote location
+        to be avoided altogether if the local directory already has a file from
+        an earlier download that matches the specified hash.
+
+      ``URL_MD5 <md5>``
+        Equivalent to ``URL_HASH MD5=<md5>``.
+
+      ``DOWNLOAD_NAME <fname>``
+        File name to use for the downloaded file. If not given, the end of the
+        URL is used to determine the file name. This option is rarely needed,
+        the default name is generally suitable and is not normally used outside
+        of code internal to the ``ExternalProject`` module.
+
+      ``DOWNLOAD_NO_EXTRACT <bool>``
+        Allows the extraction part of the download step to be disabled by
+        passing a boolean true value for this option. If this option is not
+        given, the downloaded contents will be unpacked automatically if
+        required. If extraction has been disabled, the full path to the
+        downloaded file is available as ``<DOWNLOADED_FILE>`` in subsequent
+        steps or as the property ``DOWNLOADED_FILE`` with the
+        :command:`ExternalProject_Get_Property` command.
+
+      ``DOWNLOAD_NO_PROGRESS <bool>``
+        Can be used to disable logging the download progress. If this option is
+        not given, download progress messages will be logged.
+
+      ``TIMEOUT <seconds>``
+        Maximum time allowed for file download operations.
+
+      ``HTTP_USERNAME <username>``
+        Username for the download operation if authentication is required.
+
+      ``HTTP_PASSWORD <password>``
+        Password for the download operation if authentication is required.
+
+      ``HTTP_HEADER <header1> [<header2>...]``
+        Provides an arbitrary list of HTTP headers for the download operation.
+        This can be useful for accessing content in systems like AWS, etc.
+
+      ``TLS_VERIFY <bool>``
+        Specifies whether certificate verification should be performed for
+        https URLs. If this option is not provided, the default behavior is
+        determined by the ``CMAKE_TLS_VERIFY`` variable (see
+        :command:`file(DOWNLOAD)`). If that is also not set, certificate
+        verification will not be performed. In situations where ``URL_HASH``
+        cannot be provided, this option can be an alternative verification
+        measure.
+
+      ``TLS_CAINFO <file>``
+        Specify a custom certificate authority file to use if ``TLS_VERIFY``
+        is enabled. If this option is not specified, the value of the
+        ``CMAKE_TLS_CAINFO`` variable will be used instead (see
+        :command:`file(DOWNLOAD)`)
+
+    *Git*
+      NOTE: A git version of 1.6.5 or later is required if this download method
+      is used.
+
+      ``GIT_REPOSITORY <url>``
+        URL of the git repository. Any URL understood by the ``git`` command
+        may be used.
+
+      ``GIT_TAG <tag>``
+        Git branch name, tag or commit hash. Note that branch names and tags
+        should generally be specified as remote names (i.e. ``origin/myBranch``
+        rather than simply ``myBranch``). This ensures that if the remote end
+        has its tag moved or branch rebased or history rewritten, the local
+        clone will still be updated correctly. In general, however, specifying
+        a commit hash should be preferred for a number of reasons:
+
+        - If the local clone already has the commit corresponding to the hash,
+          no ``git fetch`` needs to be performed to check for changes each time
+          CMake is re-run. This can result in a significant speed up if many
+          external projects are being used.
+        - Using a specific git hash ensures that the main project's own history
+          is fully traceable to a specific point in the external project's
+          evolution. If a branch or tag name is used instead, then checking out
+          a specific commit of the main project doesn't necessarily pin the
+          whole build to a specific point in the life of the external project.
+          The lack of such deterministic behavior makes the main project lose
+          traceability and repeatability.
+
+      ``GIT_REMOTE_NAME <name>``
+        The optional name of the remote. If this option is not specified, it
+        defaults to ``origin``.
+
+      ``GIT_SUBMODULES <module>...``
+        Specific git submodules that should also be updated. If this option is
+        not provided, all git submodules will be updated.
+
+      ``GIT_SHALLOW <bool>``
+        When this option is enabled, the ``git clone`` operation will be given
+        the ``--depth 1`` option. This performs a shallow clone, which avoids
+        downloading the whole history and instead retrieves just the commit
+        denoted by the ``GIT_TAG`` option.
+
+      ``GIT_PROGRESS <bool>``
+        When enabled, this option instructs the ``git clone`` operation to
+        report its progress by passing it the ``--progress`` option. Without
+        this option, the clone step for large projects may appear to make the
+        build stall, since nothing will be logged until the clone operation
+        finishes. While this option can be used to provide progress to prevent
+        the appearance of the build having stalled, it may also make the build
+        overly noisy if lots of external projects are used.
+
+      ``GIT_CONFIG <option1> [<option2>...]``
+        Specify a list of config options to pass to ``git clone``. Each option
+        listed will be transformed into its own ``--config <option>`` on the
+        ``git clone`` command line, with each option required to be in the
+        form ``key=value``.
+
+    *Subversion*
+      ``SVN_REPOSITORY <url>``
+        URL of the Subversion repository.
+
+      ``SVN_REVISION -r<rev>``
+        Revision to checkout from the Subversion repository.
+
+      ``SVN_USERNAME <username>``
+        Username for the Subversion checkout and update.
+
+      ``SVN_PASSWORD <password>``
+        Password for the Subversion checkout and update.
+
+      ``SVN_TRUST_CERT <bool>``
+        Specifies whether to trust the Subversion server site certificate. If
+        enabled, the ``--trust-server-cert`` option is passed to the ``svn``
+        checkout and update commands.
+
+    *Mercurial*
+      ``HG_REPOSITORY <url>``
+        URL of the mercurial repository.
+
+      ``HG_TAG <tag>``
+        Mercurial branch name, tag or commit id.
+
+    *CVS*
+      ``CVS_REPOSITORY <cvsroot>``
+        CVSROOT of the CVS repository.
+
+      ``CVS_MODULE <mod>``
+        Module to checkout from the CVS repository.
+
+      ``CVS_TAG <tag>``
+        Tag to checkout from the CVS repository.
+
+  **Update/Patch Step Options:**
+    Whenever CMake is re-run, by default the external project's sources will be
+    updated if the download method supports updates (e.g. a git repository
+    would be checked if the ``GIT_TAG`` does not refer to a specific commit).
+
+    ``UPDATE_COMMAND <cmd>...``
+      Overrides the download method's update step with a custom command.
+      The command may use
+      :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+    ``UPDATE_DISCONNECTED <bool>``
+      When enabled, this option causes the update step to be skipped. It does
+      not, however, prevent the download step. The update step can still be
+      added as a step target (see :command:`ExternalProject_Add_StepTargets`)
+      and called manually. This is useful if you want to allow developers to
+      build the project when disconnected from the network (the network may
+      still be needed for the download step though).
+
+      When this option is present, it is generally advisable to make the value
+      a cache variable under the developer's control rather than hard-coding
+      it. If this option is not present, the default value is taken from the
+      ``EP_UPDATE_DISCONNECTED`` directory property. If that is also not
+      defined, updates are performed as normal. The ``EP_UPDATE_DISCONNECTED``
+      directory property is intended as a convenience for controlling the
+      ``UPDATE_DISCONNECTED`` behavior for an entire section of a project's
+      directory hierarchy and may be a more convenient method of giving
+      developers control over whether or not to perform updates (assuming the
+      project also provides a cache variable or some other convenient method
+      for setting the directory property).
+
+    ``PATCH_COMMAND <cmd>...``
+      Specifies a custom command to patch the sources after an update. By
+      default, no patch command is defined. Note that it can be quite difficult
+      to define an appropriate patch command that performs robustly, especially
+      for download methods such as git where changing the ``GIT_TAG`` will not
+      discard changes from a previous patch, but the patch command will be
+      called again after updating to the new tag.
+
+  **Configure Step Options:**
+    The configure step is run after the download and update steps. By default,
+    the external project is assumed to be a CMake project, but this can be
+    overridden if required.
+
+    ``CONFIGURE_COMMAND <cmd>...``
+      The default configure command runs CMake with options based on the main
+      project. For non-CMake external projects, the ``CONFIGURE_COMMAND``
+      option must be used to override this behavior
+      (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+      supported). For projects that require no configure step, specify this
+      option with an empty string as the command to execute.
+
+    ``CMAKE_COMMAND /.../cmake``
+      Specify an alternative cmake executable for the configure step (use an
+      absolute path). This is generally not recommended, since it is
+      usually desirable to use the same CMake version throughout the whole
+      build. This option is ignored if a custom configure command has been
+      specified with ``CONFIGURE_COMMAND``.
+
+    ``CMAKE_GENERATOR <gen>``
+      Override the CMake generator used for the configure step. Without this
+      option, the same generator as the main build will be used. This option is
+      ignored if a custom configure command has been specified with the
+      ``CONFIGURE_COMMAND`` option.
+
+    ``CMAKE_GENERATOR_PLATFORM <platform>``
+      Pass a generator-specific platform name to the CMake command (see
+      :variable:`CMAKE_GENERATOR_PLATFORM`). It is an error to provide this
+      option without the ``CMAKE_GENERATOR`` option.
+
+    ``CMAKE_GENERATOR_TOOLSET <toolset>``
+      Pass a generator-specific toolset name to the CMake command (see
+      :variable:`CMAKE_GENERATOR_TOOLSET`). It is an error to provide this
+      option without the ``CMAKE_GENERATOR`` option.
+
+    ``CMAKE_ARGS <arg>...``
+      The specified arguments are passed to the ``cmake`` command line. They
+      can be any argument the ``cmake`` command understands, not just cache
+      values defined by ``-D...`` arguments (see also
+      :manual:`CMake Options <cmake(1)>`). In addition, arguments may use
+      :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+    ``CMAKE_CACHE_ARGS <arg>...``
+      This is an alternate way of specifying cache variables where command line
+      length issues may become a problem. The arguments are expected to be in
+      the form ``-Dvar:STRING=value``, which are then transformed into
+      CMake :command:`set` commands with the ``FORCE`` option used. These
+      ``set()`` commands are written to a pre-load script which is then applied
+      using the :manual:`cmake -C <cmake(1)>` command line option. Arguments
+      may use :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+    ``CMAKE_CACHE_DEFAULT_ARGS <arg>...``
+      This is the same as the ``CMAKE_CACHE_ARGS`` option except the ``set()``
+      commands do not include the ``FORCE`` keyword. This means the values act
+      as initial defaults only and will not override any variables already set
+      from a previous run. Use this option with care, as it can lead to
+      different behavior depending on whether the build starts from a fresh
+      build directory or re-uses previous build contents.
+
+    ``SOURCE_SUBDIR <dir>``
+      When no ``CONFIGURE_COMMAND`` option is specified, the configure step
+      assumes the external project has a ``CMakeLists.txt`` file at the top of
+      its source tree (i.e. in ``SOURCE_DIR``). The ``SOURCE_SUBDIR`` option
+      can be used to point to an alternative directory within the source tree
+      to use as the top of the CMake source tree instead. This must be a
+      relative path and it will be interpreted as being relative to
+      ``SOURCE_DIR``.
+
+  **Build Step Options:**
+    If the configure step assumed the external project uses CMake as its build
+    system, the build step will also. Otherwise, the build step will assume a
+    Makefile-based build and simply run ``make`` with no arguments as the
+    default build step. This can be overridden with custom build commands if
+    required.
+
+    ``BUILD_COMMAND <cmd>...``
+      Overrides the default build command
+      (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+      supported). If this option is not given, the default build command will
+      be chosen to integrate with the main build in the most appropriate way
+      (e.g. using recursive ``make`` for Makefile generators or
+      ``cmake --build`` if the project uses a CMake build). This option can be
+      specified with an empty string as the command to make the build step do
+      nothing.
+
+    ``BUILD_IN_SOURCE <bool>``
+      When this option is enabled, the build will be done directly within the
+      external project's source tree. This should generally be avoided, the use
+      of a separate build directory is usually preferred, but it can be useful
+      when the external project assumes an in-source build. The ``BINARY_DIR``
+      option should not be specified if building in-source.
+
+    ``BUILD_ALWAYS <bool>``
+      Enabling this option forces the build step to always be run. This can be
+      the easiest way to robustly ensure that the external project's own build
+      dependencies are evaluated rather than relying on the default
+      success timestamp-based method. This option is not normally needed unless
+      developers are expected to modify something the external project's build
+      depends on in a way that is not detectable via the step target
+      dependencies (e.g. ``SOURCE_DIR`` is used without a download method and
+      developers might modify the sources in ``SOURCE_DIR``).
+
+    ``BUILD_BYPRODUCTS <file>...``
+      Specifies files that will be generated by the build command but which
+      might or might not have their modification time updated by subsequent
+      builds. These ultimately get passed through as ``BYPRODUCTS`` to the
+      build step's own underlying call to :command:`add_custom_command`.
+
+  **Install Step Options:**
+    If the configure step assumed the external project uses CMake as its build
+    system, the install step will also. Otherwise, the install step will assume
+    a Makefile-based build and simply run ``make install`` as the default build
+    step. This can be overridden with custom install commands if required.
+
+    ``INSTALL_COMMAND <cmd>...``
+      The external project's own install step is invoked as part of the main
+      project's *build*. It is done after the external project's build step
+      and may be before or after the external project's test step (see the
+      ``TEST_BEFORE_INSTALL`` option below). The external project's install
+      rules are not part of the main project's install rules, so if anything
+      from the external project should be installed as part of the main build,
+      these need to be specified in the main build as additional
+      :command:`install` commands. The default install step builds the
+      ``install`` target of the external project, but this can be overridden
+      with a custom command using this option
+      (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+      supported). Passing an empty string as the ``<cmd>`` makes the install
+      step do nothing.
+
+  **Test Step Options:**
+    The test step is only defined if at least one of the following ``TEST_...``
+    options are provided.
+
+    ``TEST_COMMAND <cmd>...``
+      Overrides the default test command
+      (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+      supported). If this option is not given, the default behavior of the test
+      step is to build the external project's own ``test`` target. This option
+      can be specified with ``<cmd>`` as an empty string, which allows the test
+      step to still be defined, but it will do nothing. Do not specify any of
+      the other ``TEST_...`` options if providing an empty string as the test
+      command, but prefer to omit all ``TEST_...`` options altogether if the
+      test step target is not needed.
+
+    ``TEST_BEFORE_INSTALL <bool>``
+      When this option is enabled, the test step will be executed before the
+      install step. The default behavior is for the test step to run after the
+      install step.
+
+    ``TEST_AFTER_INSTALL <bool>``
+      This option is mainly useful as a way to indicate that the test step is
+      desired but all default behavior is sufficient. Specifying this option
+      with a boolean true value ensures the test step is defined and that it
+      comes after the install step. If both ``TEST_BEFORE_INSTALL`` and
+      ``TEST_AFTER_INSTALL`` are enabled, the latter is silently ignored.
+
+    ``TEST_EXCLUDE_FROM_MAIN <bool>``
+      If enabled, the main build's default ALL target will not depend on the
+      test step. This can be a useful way of ensuring the test step is defined
+      but only gets invoked when manually requested.
+
+  **Output Logging Options:**
+    Each of the following ``LOG_...`` options can be used to wrap the relevant
+    step in a script to capture its output to files. The log files will be
+    created in the ``STAMP_DIR`` directory with step-specific file names.
+
+    ``LOG_DOWNLOAD <bool>``
+      When enabled, the output of the download step is logged to files.
+
+    ``LOG_UPDATE <bool>``
+      When enabled, the output of the update step is logged to files.
+
+    ``LOG_CONFIGURE <bool>``
+      When enabled, the output of the configure step is logged to files.
+
+    ``LOG_BUILD <bool>``
+      When enabled, the output of the build step is logged to files.
+
+    ``LOG_INSTALL <bool>``
+      When enabled, the output of the install step is logged to files.
+
+    ``LOG_TEST <bool>``
+      When enabled, the output of the test step is logged to files.
+
+  **Terminal Access Options:**
+    Steps can be given direct access to the terminal in some cases. Giving a
+    step access to the terminal may allow it to receive terminal input if
+    required, such as for authentication details not provided by other options.
+    With the :generator:`Ninja` generator, these options place the steps in the
+    ``console`` :prop_gbl:`job pool <JOB_POOLS>`. Each step can be given access
+    to the terminal individually via the following options:
+
+    ``USES_TERMINAL_DOWNLOAD <bool>``
+      Give the download step access to the terminal.
+
+    ``USES_TERMINAL_UPDATE <bool>``
+      Give the update step access to the terminal.
+
+    ``USES_TERMINAL_CONFIGURE <bool>``
+      Give the configure step access to the terminal.
+
+    ``USES_TERMINAL_BUILD <bool>``
+      Give the build step access to the terminal.
+
+    ``USES_TERMINAL_INSTALL <bool>``
+      Give the install step access to the terminal.
+
+    ``USES_TERMINAL_TEST <bool>``
+      Give the test step access to the terminal.
+
+  **Target Options:**
+    ``DEPENDS <targets>...``
+      Specify other targets on which the external project depends. The other
+      targets will be brought up to date before any of the external project's
+      steps are executed. Because the external project uses additional custom
+      targets internally for each step, the ``DEPENDS`` option is the most
+      convenient way to ensure all of those steps depend on the other targets.
+      Simply doing
+      :command:`add_dependencies(\<name\> \<targets\>) <add_dependencies>` will
+      not make any of the steps dependent on ``<targets>``.
+
+    ``EXCLUDE_FROM_ALL <bool>``
+      When enabled, this option excludes the external project from the default
+      ALL target of the main build.
+
+    ``STEP_TARGETS <step-target>...``
+      Generate custom targets for the specified steps. This is required if the
+      steps need to be triggered manually or if they need to be used as
+      dependencies of other targets. If this option is not specified, the
+      default value is taken from the ``EP_STEP_TARGETS`` directory property.
+      See :command:`ExternalProject_Add_Step` below for further discussion of
+      the effects of this option.
+
+    ``INDEPENDENT_STEP_TARGETS <step-target>...``
+      Generate custom targets for the specified steps and prevent these targets
+      from having the usual dependencies applied to them. If this option is not
+      specified, the default value is taken from the
+      ``EP_INDEPENDENT_STEP_TARGETS`` directory property. This option is mostly
+      useful for allowing individual steps to be driven independently, such as
+      for a CDash setup where each step should be initiated and reported
+      individually rather than as one whole build. See
+      :command:`ExternalProject_Add_Step` below for further discussion of the
+      effects of this option.
+
+  **Miscellaneous Options:**
+    ``LIST_SEPARATOR <sep>``
+      For any of the various ``..._COMMAND`` options, replace ``;`` with
+      ``<sep>`` in the specified command lines. This can be useful where list
+      variables may be given in commands where they should end up as
+      space-separated arguments (``<sep>`` would be a single space character
+      string in this case).
+
+    ``COMMAND <cmd>...``
+      Any of the other ``..._COMMAND`` options can have additional commands
+      appended to them by following them with as many ``COMMAND ...`` options
+      as needed
+      (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+      supported). For example::
+
+        ExternalProject_Add(example
+          ... # Download options, etc.
+          BUILD_COMMAND ${CMAKE_COMMAND} -E echo "Starting $<CONFIG> build"
+          COMMAND       ${CMAKE_COMMAND} --build <BINARY_DIR> --config $<CONFIG>
+          COMMAND       ${CMAKE_COMMAND} -E echo "$<CONFIG> build complete"
+        )
+
+  It should also be noted that each build step is created via a call to
+  :command:`ExternalProject_Add_Step`. See that command's documentation for the
+  automatic substitutions that are supported for some options.
+
+Obtaining Project Properties
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. command:: ExternalProject_Get_Property
+
+  The ``ExternalProject_Get_Property()`` function retrieves external project
+  target properties::
+
+    ExternalProject_Get_Property(<name> <prop1> [<prop2>...])
+
+  The function stores property values in variables of the same name. Property
+  names correspond to the keyword argument names of ``ExternalProject_Add()``.
+  For example, the source directory might be retrieved like so:
+
+  .. code-block:: cmake
+
+    ExternalProject_Get_property(myExtProj SOURCE_DIR)
+    message("Source dir of myExtProj = ${SOURCE_DIR}")
+
+Explicit Step Management
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``ExternalProject_Add()`` function on its own is often sufficient for
+incorporating an external project into the main build. Certain scenarios
+require additional work to implement desired behavior, such as adding in a
+custom step or making steps available as manually triggerable targets. The
+``ExternalProject_Add_Step()``, ``ExternalProject_Add_StepTargets()`` and
+``ExternalProject_Add_StepDependencies`` functions provide the lower level
+control needed to implement such step-level capabilities.
 
 .. command:: ExternalProject_Add_Step
 
-  The ``ExternalProject_Add_Step`` function adds a custom step to an
-  external project::
+  The ``ExternalProject_Add_Step()`` function specifies an additional custom
+  step for an external project defined by an earlier call to
+  :command:`ExternalProject_Add`::
 
-   ExternalProject_Add_Step(<name> <step> [<option>...])
+    ExternalProject_Add_Step(<name> <step> [<option>...])
 
-  Options are:
+  ``<name>`` is the same as the name passed to the original call to
+  :command:`ExternalProject_Add`. The specified ``<step>`` must not be one of
+  the pre-defined steps (``mkdir``, ``download``, ``update``, ``skip-update``,
+  ``patch``, ``configure``, ``build``, ``install`` or ``test``). The supported
+  options are:
 
   ``COMMAND <cmd>...``
-    Command line invoked by this step
+    The command line to be executed by this custom step
+    (:manual:`generator expressions <cmake-generator-expressions(7)>` are
+    supported). This option can be repeated multiple times to specify multiple
+    commands to be executed in order.
+
   ``COMMENT "<text>..."``
-    Text printed when step executes
+    Text to be printed when the custom step executes.
+
   ``DEPENDEES <step>...``
-    Steps on which this step depends
+    Other steps (custom or pre-defined) on which this step depends.
+
   ``DEPENDERS <step>...``
-    Steps that depend on this step
+    Other steps (custom or pre-defined) that depend on this new custom step.
+
   ``DEPENDS <file>...``
-    Files on which this step depends
+    Files on which this custom step depends.
+
   ``BYPRODUCTS <file>...``
-    Files that will be generated by this step but may or may not
-    have their modification time updated by subsequent builds.
-  ``ALWAYS 1``
-    No stamp file, step always runs
-  ``EXCLUDE_FROM_MAIN 1``
-    Main target does not depend on this step
+    Files that will be generated by this custom step but which might or might
+    not have their modification time updated by subsequent builds. This list of
+    files will ultimately be passed through as the ``BYPRODUCTS`` option to the
+    :command:`add_custom_command` used to implement the custom step internally.
+
+  ``ALWAYS <bool>``
+    When enabled, this option specifies that the custom step should always be
+    run (i.e. that it is always considered out of date).
+
+  ``EXCLUDE_FROM_MAIN <bool>``
+    When enabled, this option specifies that the external project's main target
+    does not depend on the custom step.
+
   ``WORKING_DIRECTORY <dir>``
-    Working directory for command
-  ``LOG 1``
-    Wrap step in script to log output
-  ``USES_TERMINAL 1``
-    Give the step direct access to the terminal if possible.
+    Specifies the working directory to set before running the custom step's
+    command. If this option is not specified, the directory will be the value
+    of the :variable:`CMAKE_CURRENT_BINARY_DIR` at the point where
+    ``ExternalProject_Add_Step()`` was called.
 
-  The command line, comment, working directory, and byproducts of every
-  standard and custom step are processed to replace tokens ``<SOURCE_DIR>``,
-  ``<SOURCE_SUBDIR>``,  ``<BINARY_DIR>``, ``<INSTALL_DIR>``, and ``<TMP_DIR>``
-  with corresponding property values.
+  ``LOG <bool>``
+    If set, this causes the output from the custom step to be captured to files
+    in the external project's ``STAMP_DIR``.
 
-Any builtin step that specifies a ``<step>_COMMAND cmd...`` or custom
-step that specifies a ``COMMAND cmd...`` may specify additional command
-lines using the form ``COMMAND cmd...``.  At build time the commands
-will be executed in order and aborted if any one fails.  For example::
+  ``USES_TERMINAL <bool>``
+    If enabled, this gives the custom step direct access to the terminal if
+    possible.
 
- ... BUILD_COMMAND make COMMAND echo done ...
+  The command line, comment, working directory and byproducts of every
+  standard and custom step are processed to replace the tokens
+  ``<SOURCE_DIR>``, ``<SOURCE_SUBDIR>``, ``<BINARY_DIR>``, ``<INSTALL_DIR>``
+  and ``<TMP_DIR>`` with their corresponding property values defined in the
+  original call to :command:`ExternalProject_Add`.
 
-specifies to run ``make`` and then ``echo done`` during the build step.
-Whether the current working directory is preserved between commands is
-not defined.  Behavior of shell operators like ``&&`` is not defined.
+.. command:: ExternalProject_Add_StepTargets
 
-Arguments to ``<step>_COMMAND`` or ``COMMAND`` options may use
-:manual:`generator expressions <cmake-generator-expressions(7)>`.
+  The ``ExternalProject_Add_StepTargets()`` function generates targets for the
+  steps listed. The name of each created target will be of the form
+  ``<name>-<step>``::
+
+    ExternalProject_Add_StepTargets(<name> [NO_DEPENDS] <step1> [<step2>...])
+
+  Creating a target for a step allows it to be used as a dependency of another
+  target or to be triggered manually. Having targets for specific steps also
+  allows them to be driven independently of each other by specifying targets on
+  build command lines. For example, you may be submitting to a sub-project
+  based dashboard where you want to drive the configure portion of the build,
+  then submit to the dashboard, followed by the build portion, followed
+  by tests. If you invoke a custom target that depends on a step halfway
+  through the step dependency chain, then all the previous steps will also run
+  to ensure everything is up to date.
+
+  If the ``NO_DEPENDS`` option is specified, the step target will not depend on
+  the dependencies of the external project (i.e. on any dependencies of the
+  ``<name>`` custom target created by :command:`ExternalProject_Add`). This is
+  usually safe for the ``download``, ``update`` and ``patch`` steps, since they
+  do not typically require that the dependencies are updated and built. Using
+  ``NO_DEPENDS`` for any of the other pre-defined steps, however, may break
+  parallel builds. Only use ``NO_DEPENDS`` where it is certain that the named
+  steps genuinely do not have dependencies. For custom steps, consider whether
+  or not the custom commands require the dependencies to be configured, built
+  and installed.
+
+  Internally, :command:`ExternalProject_Add` calls
+  :command:`ExternalProject_Add_Step` to create each step. If any
+  ``STEP_TARGETS`` or ``INDEPENDENT_STEP_TARGETS`` were specified, then
+  ``ExternalProject_Add_StepTargets()`` will also be called after
+  :command:`ExternalProject_Add_Step`. ``INDEPENDENT_STEP_TARGETS`` have the
+  ``NO_DEPENDS`` option set, whereas ``STEP_TARGETS`` do not. Other than that,
+  the two options result in ``ExternalProject_Add_StepTargets()`` being called
+  in the same way. Even if a step is not mentioned in either of those two
+  options, ``ExternalProject_Add_StepTargets()`` can still be called later to
+  manually define a target for the step.
+
+  The ``STEP_TARGETS`` and ``INDEPENDENT_STEP_TARGETS`` options for
+  :command:`ExternalProject_Add` are generally the easiest way to ensure
+  targets are created for specific steps of interest. For custom steps,
+  ``ExternalProject_Add_StepTargets()`` must be called explicitly if a target
+  should also be created for that custom step. An alternative to these two
+  options is to populate the ``EP_STEP_TARGETS`` and
+  ``EP_INDEPENDENT_STEP_TARGETS`` directory properties. These act as defaults
+  for the step target options and can save having to repeatedly specify the
+  same set of step targets when multiple external projects are being defined.
 
-.. command:: ExternalProject_Get_Property
+.. command:: ExternalProject_Add_StepDependencies
 
-  The ``ExternalProject_Get_Property`` function retrieves external project
-  target properties::
+  The ``ExternalProject_Add_StepDependencies()`` function can be used to add
+  dependencies to a step. The dependencies added must be targets CMake already
+  knows about (these can be ordinary executable or library targets, custom
+  targets or even step targets of another external project)::
 
-    ExternalProject_Get_Property(<name> [prop1 [prop2 [...]]])
+    ExternalProject_Add_StepDependencies(<name> <step> <target1> [<target2>...])
 
-  It stores property values in variables of the same name.  Property
-  names correspond to the keyword argument names of
-  ``ExternalProject_Add``.
+  This function takes care to set both target and file level dependencies and
+  will ensure that parallel builds will not break. It should be used instead of
+  :command:`add_dependencies` whenever adding a dependency for some of the step
+  targets generated by the ``ExternalProject`` module.
 
-.. command:: ExternalProject_Add_StepTargets
+Examples
+^^^^^^^^
 
-  The ``ExternalProject_Add_StepTargets`` function generates custom
-  targets for the steps listed::
-
-    ExternalProject_Add_StepTargets(<name> [NO_DEPENDS] [step1 [step2 [...]]])
-
-If ``NO_DEPENDS`` is set, the target will not depend on the
-dependencies of the complete project. This is usually safe to use for
-the download, update, and patch steps that do not require that all the
-dependencies are updated and built.  Using ``NO_DEPENDS`` for other
-of the default steps might break parallel builds, so you should avoid,
-it.  For custom steps, you should consider whether or not the custom
-commands requires that the dependencies are configured, built and
-installed.
-
-If ``STEP_TARGETS`` or ``INDEPENDENT_STEP_TARGETS`` is set then
-``ExternalProject_Add_StepTargets`` is automatically called at the end
-of matching calls to ``ExternalProject_Add_Step``.  Pass
-``STEP_TARGETS`` or ``INDEPENDENT_STEP_TARGETS`` explicitly to
-individual ``ExternalProject_Add`` calls, or implicitly to all
-``ExternalProject_Add`` calls by setting the directory properties
-``EP_STEP_TARGETS`` and ``EP_INDEPENDENT_STEP_TARGETS``.  The
-``INDEPENDENT`` version of the argument and of the property will call
-``ExternalProject_Add_StepTargets`` with the ``NO_DEPENDS`` argument.
-
-If ``STEP_TARGETS`` and ``INDEPENDENT_STEP_TARGETS`` are not set,
-clients may still manually call ``ExternalProject_Add_StepTargets``
-after calling ``ExternalProject_Add`` or ``ExternalProject_Add_Step``.
-
-This functionality is provided to make it easy to drive the steps
-independently of each other by specifying targets on build command
-lines.  For example, you may be submitting to a sub-project based
-dashboard, where you want to drive the configure portion of the build,
-then submit to the dashboard, followed by the build portion, followed
-by tests.  If you invoke a custom target that depends on a step
-halfway through the step dependency chain, then all the previous steps
-will also run to ensure everything is up to date.
-
-For example, to drive configure, build and test steps independently
-for each ``ExternalProject_Add`` call in your project, write the following
-line prior to any ``ExternalProject_Add`` calls in your ``CMakeLists.txt``
-file::
-
- set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test)
+The following example shows how to download and build a hypothetical project
+called *FooBar* from github:
 
-.. command:: ExternalProject_Add_StepDependencies
+.. code-block:: cmake
+
+  include(ExternalProject)
+  ExternalProject_Add(foobar
+    GIT_REPOSITORY    git@github.com:FooCo/FooBar.git
+    GIT_TAG           origin/release/1.2.3
+  )
+
+For the sake of the example, also define a second hypothetical external project
+called *SecretSauce*, which is downloaded from a web server. Two URLs are given
+to take advantage of a faster internal network if available, with a fallback to
+a slower external server. The project is a typical ``Makefile`` project with no
+configure step, so some of the default commands are overridden. The build is
+only required to build the *sauce* target:
+
+.. code-block:: cmake
+
+  find_program(MAKE_EXE NAMES gmake nmake make)
+  ExternalProject_Add(secretsauce
+    URL               http://intranet.somecompany.com/artifacts/sauce-2.7.tgz
+                      https://www.somecompany.com/downloads/sauce-2.7.zip
+    URL_HASH          MD5=d41d8cd98f00b204e9800998ecf8427e
+    CONFIGURE_COMMAND ""
+    BUILD_COMMAND     ${MAKE_EXE} sauce
+  )
+
+Suppose the build step of ``secretsauce`` requires that ``foobar`` must already
+be built. This could be enforced like so:
+
+.. code-block:: cmake
+
+  ExternalProject_Add_StepDependencies(secretsauce build foobar)
+
+Another alternative would be to create a custom target for ``foobar``'s build
+step and make ``secretsauce`` depend on that rather than the whole ``foobar``
+project. This would mean ``foobar`` only needs to be built, it doesn't need to
+run its install or test steps before ``secretsauce`` can be built. The
+dependency can also be defined along with the ``secretsauce`` project:
+
+.. code-block:: cmake
+
+  ExternalProject_Add_StepTargets(foobar build)
+  ExternalProject_Add(secretsauce
+    URL               http://intranet.somecompany.com/artifacts/sauce-2.7.tgz
+                      https://www.somecompany.com/downloads/sauce-2.7.zip
+    URL_HASH          MD5=d41d8cd98f00b204e9800998ecf8427e
+    CONFIGURE_COMMAND ""
+    BUILD_COMMAND     ${MAKE_EXE} sauce
+    DEPENDS           foobar-build
+  )
+
+Instead of calling :command:`ExternalProject_Add_StepTargets`, the target could
+be defined along with the ``foobar`` project itself:
+
+.. code-block:: cmake
+
+  ExternalProject_Add(foobar
+    GIT_REPOSITORY git@github.com:FooCo/FooBar.git
+    GIT_TAG        origin/release/1.2.3
+    STEP_TARGETS   build
+  )
+
+If many external projects should have the same set of step targets, setting a
+directory property may be more convenient. The ``build`` step target could be
+created automatically by setting the ``EP_STEP_TARGETS`` directory property
+before creating the external projects with :command:`ExternalProject_Add`:
+
+.. code-block:: cmake
+
+  set_property(DIRECTORY PROPERTY EP_STEP_TARGETS build)
+
+Lastly, suppose that ``secretsauce`` provides a script called ``makedoc`` which
+can be used to generate its own documentation. Further suppose that the script
+expects the output directory to be provided as the only parameter and that it
+should be run from the ``secretsauce`` source directory. A custom step and a
+custom target to trigger the script can be defined like so:
+
+.. code-block:: cmake
+
+  ExternalProject_Add_Step(secretsauce docs
+    COMMAND           <SOURCE_DIR>/makedoc <BINARY_DIR>
+    WORKING_DIRECTORY <SOURCE_DIR>
+    COMMENT           "Building secretsauce docs"
+    ALWAYS            TRUE
+    EXCLUDE_FROM_MAIN TRUE
+  )
+  ExternalProject_Add_StepTargets(secretsauce docs)
 
-  The ``ExternalProject_Add_StepDependencies`` function add some
-  dependencies for some external project step::
+The custom step could then be triggered from the main build like so::
 
-    ExternalProject_Add_StepDependencies(<name> <step> [target1 [target2 [...]]])
+  cmake --build . --target secretsauce-docs
 
-  This function takes care to set both target and file level
-  dependencies, and will ensure that parallel builds will not break.
-  It should be used instead of :command:`add_dependencies()` when adding
-  a dependency for some of the step targets generated by
-  ``ExternalProject``.
 #]=======================================================================]
 
 # Pre-compute a regex to match documented keywords for each command.
-math(EXPR _ep_documentation_line_count "${CMAKE_CURRENT_LIST_LINE} - 16")
+math(EXPR _ep_documentation_line_count "${CMAKE_CURRENT_LIST_LINE} - 4")
 file(STRINGS "${CMAKE_CURRENT_LIST_FILE}" lines
      LIMIT_COUNT ${_ep_documentation_line_count}
-     REGEX "^\\.\\. command:: [A-Za-z0-9_]+|^  ``[A-Z0-9_]+ .*``$")
+     REGEX "^\\.\\. command:: [A-Za-z0-9_]+|^ +``[A-Z0-9_]+ [^`]*``$")
 foreach(line IN LISTS lines)
   if("${line}" MATCHES "^\\.\\. command:: ([A-Za-z0-9_]+)")
     if(_ep_func)
@@ -421,7 +868,7 @@ foreach(line IN LISTS lines)
     #message("function [${_ep_func}]")
     set(_ep_keywords_${_ep_func} "^(")
     set(_ep_keyword_sep)
-  elseif("${line}" MATCHES "^  ``([A-Z0-9_]+) .*``$")
+  elseif("${line}" MATCHES "^ +``([A-Z0-9_]+) [^`]*``$")
     set(_ep_key "${CMAKE_MATCH_1}")
     #message("  keyword [${_ep_key}]")
     string(APPEND _ep_keywords_${_ep_func}
@@ -504,7 +951,7 @@ define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED
   BRIEF_DOCS
   "List of ExternalProject steps that automatically get corresponding targets"
   FULL_DOCS
-  "These targets will be dependent on the main target dependencies"
+  "These targets will be dependent on the main target dependencies. "
   "See documentation of the ExternalProject_Add_StepTargets() function in the "
   "ExternalProject module."
   )
@@ -513,7 +960,7 @@ define_property(DIRECTORY PROPERTY "EP_INDEPENDENT_STEP_TARGETS" INHERITED
   BRIEF_DOCS
   "List of ExternalProject steps that automatically get corresponding targets"
   FULL_DOCS
-  "These targets will not be dependent on the main target dependencies"
+  "These targets will not be dependent on the main target dependencies. "
   "See documentation of the ExternalProject_Add_StepTargets() function in the "
   "ExternalProject module."
   )
@@ -2012,12 +2459,12 @@ function(_ep_add_download_command name)
         " ${source_dir}\n"
         "is not an existing non-empty directory.  Please specify one of:\n"
         " * SOURCE_DIR with an existing non-empty directory\n"
+        " * DOWNLOAD_COMMAND\n"
         " * URL\n"
         " * GIT_REPOSITORY\n"
+        " * SVN_REPOSITORY\n"
         " * HG_REPOSITORY\n"
-        " * CVS_REPOSITORY and CVS_MODULE\n"
-        " * SVN_REVISION\n"
-        " * DOWNLOAD_COMMAND"
+        " * CVS_REPOSITORY and CVS_MODULE"
         )
     endif()
   endif()
diff --git a/Tests/RunCMake/ExternalProject/NoOptions-stderr.txt b/Tests/RunCMake/ExternalProject/NoOptions-stderr.txt
index 12a76c5..2fc7d29 100644
--- a/Tests/RunCMake/ExternalProject/NoOptions-stderr.txt
+++ b/Tests/RunCMake/ExternalProject/NoOptions-stderr.txt
@@ -6,12 +6,12 @@
   is not an existing non-empty directory.  Please specify one of:
 
    \* SOURCE_DIR with an existing non-empty directory
+   \* DOWNLOAD_COMMAND
    \* URL
    \* GIT_REPOSITORY
+   \* SVN_REPOSITORY
    \* HG_REPOSITORY
    \* CVS_REPOSITORY and CVS_MODULE
-   \* SVN_REVISION
-   \* DOWNLOAD_COMMAND
 Call Stack \(most recent call first\):
   .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_download_command\)
   NoOptions.cmake:[0-9]+ \(ExternalProject_Add\)
diff --git a/Tests/RunCMake/ExternalProject/SourceEmpty-stderr.txt b/Tests/RunCMake/ExternalProject/SourceEmpty-stderr.txt
index 58a343c..07c6e87 100644
--- a/Tests/RunCMake/ExternalProject/SourceEmpty-stderr.txt
+++ b/Tests/RunCMake/ExternalProject/SourceEmpty-stderr.txt
@@ -6,12 +6,12 @@
   is not an existing non-empty directory.  Please specify one of:
 
    \* SOURCE_DIR with an existing non-empty directory
+   \* DOWNLOAD_COMMAND
    \* URL
    \* GIT_REPOSITORY
+   \* SVN_REPOSITORY
    \* HG_REPOSITORY
    \* CVS_REPOSITORY and CVS_MODULE
-   \* SVN_REVISION
-   \* DOWNLOAD_COMMAND
 Call Stack \(most recent call first\):
   .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_download_command\)
   SourceEmpty.cmake:[0-9]+ \(ExternalProject_Add\)
diff --git a/Tests/RunCMake/ExternalProject/SourceMissing-stderr.txt b/Tests/RunCMake/ExternalProject/SourceMissing-stderr.txt
index e62f7cf..373f6e3 100644
--- a/Tests/RunCMake/ExternalProject/SourceMissing-stderr.txt
+++ b/Tests/RunCMake/ExternalProject/SourceMissing-stderr.txt
@@ -6,12 +6,12 @@
   is not an existing non-empty directory.  Please specify one of:
 
    \* SOURCE_DIR with an existing non-empty directory
+   \* DOWNLOAD_COMMAND
    \* URL
    \* GIT_REPOSITORY
+   \* SVN_REPOSITORY
    \* HG_REPOSITORY
    \* CVS_REPOSITORY and CVS_MODULE
-   \* SVN_REVISION
-   \* DOWNLOAD_COMMAND
 Call Stack \(most recent call first\):
   .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_download_command\)
   SourceMissing.cmake:[0-9]+ \(ExternalProject_Add\)
-- 
cgit v0.12