Merge branch 'release-4.0'
[kiteware-cmake.git] / Modules / ExternalProject.cmake
blobe2d26ca91d1303ccfc5476ec407cdde15685e09d
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
4 include_guard(GLOBAL)
6 #[=======================================================================[.rst:
7 ExternalProject
8 ---------------
10 .. only:: html
12    .. contents::
14 External Project Definition
15 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
17 .. command:: ExternalProject_Add
19   The ``ExternalProject_Add()`` function creates a custom target to drive
20   download, update/patch, configure, build, install and test steps of an
21   external project:
23   .. code-block:: cmake
25     ExternalProject_Add(<name> [<option>...])
27   The individual steps within the process can be driven independently if
28   required (e.g. for CDash submission) and extra custom steps can be defined,
29   along with the ability to control the step dependencies. The directory
30   structure used for the management of the external project can also be
31   customized. The function supports a large number of options which can be used
32   to tailor the external project behavior.
34 Directory Options
35 """""""""""""""""
37 Most of the time, the default directory layout is sufficient. It is largely
38 an implementation detail that the main project usually doesn't need to
39 change. In some circumstances, however, control over the directory layout
40 can be useful or necessary. The directory options are potentially more
41 useful from the point of view that the main build can use the
42 :command:`ExternalProject_Get_Property` command to retrieve their values,
43 thereby allowing the main project to refer to build artifacts of the
44 external project.
46 ``PREFIX <dir>``
47   Root directory for the external project. Unless otherwise noted below,
48   all other directories associated with the external project will be
49   created under here.
51 ``TMP_DIR <dir>``
52   Directory in which to store temporary files.
54 ``STAMP_DIR <dir>``
55   Directory in which to store the timestamps of each step. Log files from
56   individual steps are also created in here unless overridden by LOG_DIR
57   (see *Logging Options* below).
59 ``LOG_DIR <dir>``
60   .. versionadded:: 3.14
62   Directory in which to store the logs of each step.
64 ``DOWNLOAD_DIR <dir>``
65   Directory in which to store downloaded files before unpacking them. This
66   directory is only used by the URL download method, all other download
67   methods use ``SOURCE_DIR`` directly instead.
69 ``SOURCE_DIR <dir>``
70   Source directory into which downloaded contents will be unpacked, or for
71   non-URL download methods, the directory in which the repository should be
72   checked out, cloned, etc. If no download method is specified, this must
73   point to an existing directory where the external project has already
74   been unpacked or cloned/checked out.
76   .. note::
77       If a download method is specified, any existing contents of the source
78       directory may be deleted. Only the URL download method checks whether
79       this directory is either missing or empty before initiating the
80       download, stopping with an error if it is not empty. All other
81       download methods silently discard any previous contents of the source
82       directory.
84 ``BINARY_DIR <dir>``
85   Specify the build directory location. This option is ignored if
86   ``BUILD_IN_SOURCE`` is enabled.
88 ``INSTALL_DIR <dir>``
89   Installation prefix to be placed in the ``<INSTALL_DIR>`` placeholder.
90   This does not actually configure the external project to install to
91   the given prefix. That must be done by passing appropriate arguments
92   to the external project configuration step, e.g. using ``<INSTALL_DIR>``.
94 If any of the above ``..._DIR`` options are not specified, their defaults
95 are computed as follows. If the ``PREFIX`` option is given or the
96 ``EP_PREFIX`` directory property is set, then an external project is built
97 and installed under the specified prefix::
99   TMP_DIR      = <prefix>/tmp
100   STAMP_DIR    = <prefix>/src/<name>-stamp
101   DOWNLOAD_DIR = <prefix>/src
102   SOURCE_DIR   = <prefix>/src/<name>
103   BINARY_DIR   = <prefix>/src/<name>-build
104   INSTALL_DIR  = <prefix>
105   LOG_DIR      = <STAMP_DIR>
107 Otherwise, if the ``EP_BASE`` directory property is set then components
108 of an external project are stored under the specified base::
110   TMP_DIR      = <base>/tmp/<name>
111   STAMP_DIR    = <base>/Stamp/<name>
112   DOWNLOAD_DIR = <base>/Download/<name>
113   SOURCE_DIR   = <base>/Source/<name>
114   BINARY_DIR   = <base>/Build/<name>
115   INSTALL_DIR  = <base>/Install/<name>
116   LOG_DIR      = <STAMP_DIR>
118 If no ``PREFIX``, ``EP_PREFIX``, or ``EP_BASE`` is specified, then the
119 default is to set ``PREFIX`` to ``<name>-prefix``. Relative paths are
120 interpreted with respect to :variable:`CMAKE_CURRENT_BINARY_DIR` at the
121 point where ``ExternalProject_Add()`` is called.
123 Download Step Options
124 """""""""""""""""""""
126 A download method can be omitted if the ``SOURCE_DIR`` option is used to
127 point to an existing non-empty directory. Otherwise, one of the download
128 methods below must be specified (multiple download methods should not be
129 given) or a custom ``DOWNLOAD_COMMAND`` provided.
131 ``DOWNLOAD_COMMAND <cmd>...``
132   Overrides the command used for the download step
133   (:manual:`generator expressions <cmake-generator-expressions(7)>` are
134   supported). If this option is specified, all other download options will
135   be ignored. Providing an empty string for ``<cmd>`` effectively disables
136   the download step.
141 ``URL <url1> [<url2>...]``
142   List of paths and/or URL(s) of the external project's source. When more
143   than one URL is given, they are tried in turn until one succeeds. A URL
144   may be an ordinary path in the local file system (in which case it
145   must be the only URL provided) or any downloadable URL supported by the
146   :command:`file(DOWNLOAD)` command. A local filesystem path may refer to
147   either an existing directory or to an archive file, whereas a URL is
148   expected to point to a file which can be treated as an archive. When an
149   archive is used, it will be unpacked automatically unless the
150   ``DOWNLOAD_NO_EXTRACT`` option is set to prevent it. The archive type
151   is determined by inspecting the actual content rather than using logic
152   based on the file extension.
154   .. versionchanged:: 3.7
155     Multiple URLs are allowed.
157 ``URL_HASH <algo>=<hashValue>``
158   Hash of the archive file to be downloaded. The argument should be of
159   the form ``<algo>=<hashValue>`` where ``algo`` can be any of the hashing
160   algorithms supported by the :command:`file()` command. Specifying this
161   option is strongly recommended for URL downloads, as it ensures the
162   integrity of the downloaded content. It is also used as a check for a
163   previously downloaded file, allowing connection to the remote location
164   to be avoided altogether if the local directory already has a file from
165   an earlier download that matches the specified hash.
167 ``URL_MD5 <md5>``
168   Equivalent to ``URL_HASH MD5=<md5>``.
170 ``DOWNLOAD_NAME <fname>``
171   File name to use for the downloaded file. If not given, the end of the
172   URL is used to determine the file name. This option is rarely needed,
173   the default name is generally suitable and is not normally used outside
174   of code internal to the ``ExternalProject`` module.
176 ``DOWNLOAD_EXTRACT_TIMESTAMP <bool>``
177   .. versionadded:: 3.24
179   When specified with a true value, the timestamps of the extracted
180   files will match those in the archive. When false, the timestamps of
181   the extracted files will reflect the time at which the extraction
182   was performed. If the download URL changes, timestamps based off
183   those in the archive can result in dependent targets not being rebuilt
184   when they potentially should have been. Therefore, unless the file
185   timestamps are significant to the project in some way, use a false
186   value for this option. If ``DOWNLOAD_EXTRACT_TIMESTAMP`` is not given,
187   the default is false. See policy :policy:`CMP0135`.
189 ``DOWNLOAD_NO_EXTRACT <bool>``
190   .. versionadded:: 3.6
192   Allows the extraction part of the download step to be disabled by
193   passing a boolean true value for this option. If this option is not
194   given, the downloaded contents will be unpacked automatically if
195   required. If extraction has been disabled, the full path to the
196   downloaded file is available as ``<DOWNLOADED_FILE>`` in subsequent
197   steps or as the property ``DOWNLOADED_FILE`` with the
198   :command:`ExternalProject_Get_Property` command.
200 ``DOWNLOAD_NO_PROGRESS <bool>``
201   Can be used to disable logging the download progress. If this option is
202   not given, download progress messages will be logged.
204 ``TIMEOUT <seconds>``
205   Maximum time allowed for file download operations.
207 ``INACTIVITY_TIMEOUT <seconds>``
208   .. versionadded:: 3.19
210   Terminate the operation after a period of inactivity.
212 ``HTTP_USERNAME <username>``
213   .. versionadded:: 3.7
215   Username for the download operation if authentication is required.
217 ``HTTP_PASSWORD <password>``
218   .. versionadded:: 3.7
220   Password for the download operation if authentication is required.
222 ``HTTP_HEADER <header1> [<header2>...]``
223   .. versionadded:: 3.7
225   Provides an arbitrary list of HTTP headers for the download operation.
226   This can be useful for accessing content in systems like AWS, etc.
228 ``TLS_VERSION <min>``
229   .. versionadded:: 3.30
231   Specify minimum TLS version for ``https://`` URLs.  If this option is
232   not provided, the value of the :variable:`CMAKE_TLS_VERSION` variable
233   or the :envvar:`CMAKE_TLS_VERSION` environment variable will be used
234   instead (see :command:`file(DOWNLOAD)`).
236   This option also applies to ``git clone`` invocations, although the
237   default behavior is different.  If none of the ``TLS_VERSION`` option,
238   :variable:`CMAKE_TLS_VERSION` variable, or :envvar:`CMAKE_TLS_VERSION`
239   environment variable is specified, the behavior will be determined by
240   git's default or a ``http.sslVersion`` git config option the user may
241   have set at a global level.
243 ``TLS_VERIFY <bool>``
244   Specifies whether certificate verification should be performed for
245   ``https://`` URLs.  If this option is not provided, the value of the
246   :variable:`CMAKE_TLS_VERIFY` variable or the :envvar:`CMAKE_TLS_VERIFY`
247   environment variable will be used instead (see :command:`file(DOWNLOAD)`).
248   If neither of those is set, certificate verification will not be performed.
249   In situations where ``URL_HASH`` cannot be provided, this option can
250   be an alternative verification measure.
252   This option also applies to ``git clone`` invocations, although the
253   default behavior is different.  If none of the ``TLS_VERIFY`` option,
254   :variable:`CMAKE_TLS_VERIFY` variable, or :envvar:`CMAKE_TLS_VERIFY`
255   environment variable is specified, the behavior will be determined by
256   git's default (true) or a ``http.sslVerify`` git config option the
257   user may have set at a global level.
259   .. versionchanged:: 3.6
261     Previously this option did not apply to ``git clone`` invocations.
263   .. versionchanged:: 3.30
265     Previously the :envvar:`CMAKE_TLS_VERIFY` environment variable
266     was not checked.
268 ``TLS_CAINFO <file>``
269   Specify a custom certificate authority file to use if ``TLS_VERIFY``
270   is enabled. If this option is not specified, the value of the
271   :variable:`CMAKE_TLS_CAINFO` variable will be used instead (see
272   :command:`file(DOWNLOAD)`)
274 ``NETRC <level>``
275   .. versionadded:: 3.11
277   Specify whether the ``.netrc`` file is to be used for operation.
278   If this option is not specified, the value of the
279   :variable:`CMAKE_NETRC` variable will be used instead
280   (see :command:`file(DOWNLOAD)`).  Valid levels are:
282   ``IGNORED``
283     The ``.netrc`` file is ignored.
284     This is the default.
285   ``OPTIONAL``
286     The ``.netrc`` file is optional, and information in the URL
287     is preferred.  The file will be scanned to find which ever
288     information is not specified in the URL.
289   ``REQUIRED``
290     The ``.netrc`` file is required, and information in the URL
291     is ignored.
293 ``NETRC_FILE <file>``
294   .. versionadded:: 3.11
296   Specify an alternative ``.netrc`` file to the one in your home directory
297   if the ``NETRC`` level is ``OPTIONAL`` or ``REQUIRED``. If this option
298   is not specified, the value of the :variable:`CMAKE_NETRC_FILE` variable
299   will be used instead (see :command:`file(DOWNLOAD)`)
301 .. versionadded:: 3.1
302   Added support for `tbz2`, `.tar.xz`, `.txz`, and `.7z` extensions.
307 NOTE: A git version of 1.6.5 or later is required if this download method
308 is used.
310 ``GIT_REPOSITORY <url>``
311   URL of the git repository. Any URL understood by the ``git`` command
312   may be used.
314   .. versionchanged:: 3.27
315     A relative URL will be resolved based on the parent project's
316     remote, subject to :policy:`CMP0150`.  See the policy documentation
317     for how the remote is selected, including conditions where the
318     remote selection can fail.  Local filesystem remotes should
319     always use absolute paths.
321 ``GIT_TAG <tag>``
322   Git branch name, tag or commit hash. Note that branch names and tags
323   should generally be specified as remote names (i.e. ``origin/myBranch``
324   rather than simply ``myBranch``). This ensures that if the remote end
325   has its tag moved or branch rebased or history rewritten, the local
326   clone will still be updated correctly. In general, however, specifying
327   a commit hash should be preferred for a number of reasons:
329   - If the local clone already has the commit corresponding to the hash,
330     no ``git fetch`` needs to be performed to check for changes each time
331     CMake is re-run. This can result in a significant speed up if many
332     external projects are being used.
333   - Using a specific git hash ensures that the main project's own history
334     is fully traceable to a specific point in the external project's
335     evolution. If a branch or tag name is used instead, then checking out
336     a specific commit of the main project doesn't necessarily pin the
337     whole build to a specific point in the life of the external project.
338     The lack of such deterministic behavior makes the main project lose
339     traceability and repeatability.
341   If ``GIT_SHALLOW`` is enabled then ``GIT_TAG`` works only with
342   branch names and tags.  A commit hash is not allowed.
344   Note that if not provided, ``GIT_TAG`` defaults to ``master``, not the
345   default Git branch name.
347 ``GIT_REMOTE_NAME <name>``
348   The optional name of the remote. If this option is not specified, it
349   defaults to ``origin``.
351 ``GIT_SUBMODULES <module>...``
352   Specific git submodules that should also be updated. If this option is
353   not provided, all git submodules will be updated.
355   .. versionchanged:: 3.16
356     When :policy:`CMP0097` is set to ``NEW``, if this value is set
357     to an empty string then no submodules are initialized or updated.
359 ``GIT_SUBMODULES_RECURSE <bool>``
360   .. versionadded:: 3.17
362   Specify whether git submodules (if any) should update recursively by
363   passing the ``--recursive`` flag to ``git submodule update``.
364   If not specified, the default is on.
366 ``GIT_SHALLOW <bool>``
367   .. versionadded:: 3.6
369   When this option is enabled, the ``git clone`` operation will be given
370   the ``--depth 1`` option. This performs a shallow clone, which avoids
371   downloading the whole history and instead retrieves just the commit
372   denoted by the ``GIT_TAG`` option.
374 ``GIT_PROGRESS <bool>``
375   .. versionadded:: 3.8
377   When enabled, this option instructs the ``git clone`` operation to
378   report its progress by passing it the ``--progress`` option. Without
379   this option, the clone step for large projects may appear to make the
380   build stall, since nothing will be logged until the clone operation
381   finishes. While this option can be used to provide progress to prevent
382   the appearance of the build having stalled, it may also make the build
383   overly noisy if lots of external projects are used.
385 ``GIT_CONFIG <option1> [<option2>...]``
386   .. versionadded:: 3.8
388   Specify a list of config options to pass to ``git clone``. Each option
389   listed will be transformed into its own ``--config <option>`` on the
390   ``git clone`` command line, with each option required to be in the
391   form ``key=value``.
393 ``GIT_REMOTE_UPDATE_STRATEGY <strategy>``
394   .. versionadded:: 3.18
396   When ``GIT_TAG`` refers to a remote branch, this option can be used to
397   specify how the update step behaves.  The ``<strategy>`` must be one of
398   the following:
400   ``CHECKOUT``
401     Ignore the local branch and always checkout the branch specified by
402     ``GIT_TAG``.
404   ``REBASE``
405     Try to rebase the current branch to the one specified by ``GIT_TAG``.
406     If there are local uncommitted changes, they will be stashed first
407     and popped again after rebasing.  If rebasing or popping stashed
408     changes fail, abort the rebase and halt with an error.
409     When ``GIT_REMOTE_UPDATE_STRATEGY`` is not present, this is the
410     default strategy unless the default has been overridden with
411     ``CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY`` (see below).
412     Note that if the branch specified in ``GIT_TAG`` is different to
413     the upstream branch currently being tracked, it is not safe to
414     perform a rebase. In that situation, ``REBASE`` will silently be
415     treated as ``CHECKOUT`` instead.
417   ``REBASE_CHECKOUT``
418     Same as ``REBASE`` except if the rebase fails, an annotated tag will
419     be created at the original ``HEAD`` position from before the rebase
420     and then checkout ``GIT_TAG`` just like the ``CHECKOUT`` strategy.
421     The message stored on the annotated tag will give information about
422     what was attempted and the tag name will include a timestamp so that
423     each failed run will add a new tag.  This strategy ensures no changes
424     will be lost, but updates should always succeed if ``GIT_TAG`` refers
425     to a valid ref unless there are uncommitted changes that cannot be
426     popped successfully.
428   The variable ``CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY`` can be set to
429   override the default strategy.  This variable should not be set by a
430   project, it is intended for the user to set.  It is primarily intended
431   for use in continuous integration scripts to ensure that when history
432   is rewritten on a remote branch, the build doesn't end up with
433   unintended changes or failed builds resulting from conflicts during
434   rebase operations.
436 Subversion
437 ~~~~~~~~~~
439 ``SVN_REPOSITORY <url>``
440   URL of the Subversion repository.
442 ``SVN_REVISION -r<rev>``
443   Revision to checkout from the Subversion repository.
445 ``SVN_USERNAME <username>``
446   Username for the Subversion checkout and update.
448 ``SVN_PASSWORD <password>``
449   Password for the Subversion checkout and update.
451 ``SVN_TRUST_CERT <bool>``
452   Specifies whether to trust the Subversion server site certificate. If
453   enabled, the ``--trust-server-cert`` option is passed to the ``svn``
454   checkout and update commands.
456 Mercurial
457 ~~~~~~~~~
459 ``HG_REPOSITORY <url>``
460   URL of the mercurial repository.
462 ``HG_TAG <tag>``
463   Mercurial branch name, tag or commit id.
468 ``CVS_REPOSITORY <cvsroot>``
469   CVSROOT of the CVS repository.
471 ``CVS_MODULE <mod>``
472   Module to checkout from the CVS repository.
474 ``CVS_TAG <tag>``
475   Tag to checkout from the CVS repository.
477 Update Step Options
478 """""""""""""""""""
480 Whenever CMake is re-run, by default the external project's sources will be
481 updated if the download method supports updates (e.g. a git repository
482 would be checked if the ``GIT_TAG`` does not refer to a specific commit).
484 ``UPDATE_COMMAND <cmd>...``
485   Overrides the download method's update step with a custom command.
486   The command may use
487   :manual:`generator expressions <cmake-generator-expressions(7)>`.
489 ``UPDATE_DISCONNECTED <bool>``
490   .. versionadded:: 3.2
492   When enabled, this option causes the update step to be skipped (but see
493   below for changed behavior where this is not the case). It does not
494   prevent the download step. The update step can still be
495   added as a step target (see :command:`ExternalProject_Add_StepTargets`)
496   and called manually. This is useful if you want to allow developers to
497   build the project when disconnected from the network (the network may
498   still be needed for the download step though).
500   .. versionchanged:: 3.27
502     When ``UPDATE_DISCONNECTED`` is true, the update step will be executed
503     if any details about the update or download step are changed.
504     Furthermore, if using the git download/update method, the update
505     logic will be modified to skip attempts to contact the remote.
506     If the ``GIT_TAG`` mentions a ref that is not known locally, the
507     update step will halt with a fatal error.
509   When this option is present, it is generally advisable to make the value
510   a cache variable under the developer's control rather than hard-coding
511   it. If this option is not present, the default value is taken from the
512   ``EP_UPDATE_DISCONNECTED`` directory property. If that is also not
513   defined, updates are performed as normal. The ``EP_UPDATE_DISCONNECTED``
514   directory property is intended as a convenience for controlling the
515   ``UPDATE_DISCONNECTED`` behavior for an entire section of a project's
516   directory hierarchy and may be a more convenient method of giving
517   developers control over whether or not to perform updates (assuming the
518   project also provides a cache variable or some other convenient method
519   for setting the directory property).
521   This may cause a step target to be created automatically for the
522   ``download`` step.  See policy :policy:`CMP0114`.
524 Patch Step Options
525 """"""""""""""""""
527 ``PATCH_COMMAND <cmd>...``
528   Specifies a custom command to patch the sources after an update. By
529   default, no patch command is defined. Note that it can be quite difficult
530   to define an appropriate patch command that performs robustly, especially
531   for download methods such as git where changing the ``GIT_TAG`` will not
532   discard changes from a previous patch, but the patch command will be
533   called again after updating to the new tag.
535 Configure Step Options
536 """"""""""""""""""""""
538 The configure step is run after the download and update steps. By default,
539 the external project is assumed to be a CMake project, but this can be
540 overridden if required.
542 ``CONFIGURE_COMMAND <cmd>...``
543   The default configure command runs CMake with a few options based on
544   the main project.  The options added are typically only those needed to
545   use the same generator as the main project, but the ``CMAKE_GENERATOR``
546   option can be given to override this.  The project is responsible for
547   adding any toolchain details, flags or other settings it wants to
548   reuse from the main project or otherwise specify (see ``CMAKE_ARGS``,
549   ``CMAKE_CACHE_ARGS`` and ``CMAKE_CACHE_DEFAULT_ARGS`` below).
551   For non-CMake external projects, the ``CONFIGURE_COMMAND`` option must
552   be used to override the default configure command
553   (:manual:`generator expressions <cmake-generator-expressions(7)>` are
554   supported). For projects that require no configure step, specify this
555   option with an empty string as the command to execute.
557 ``CMAKE_COMMAND /.../cmake``
558   Specify an alternative cmake executable for the configure step (use an
559   absolute path). This is generally not recommended, since it is
560   usually desirable to use the same CMake version throughout the whole
561   build. This option is ignored if a custom configure command has been
562   specified with ``CONFIGURE_COMMAND``.
564 ``CMAKE_GENERATOR <gen>``
565   Override the CMake generator used for the configure step. Without this
566   option, the same generator as the main build will be used. This option is
567   ignored if a custom configure command has been specified with the
568   ``CONFIGURE_COMMAND`` option.
570 ``CMAKE_GENERATOR_PLATFORM <platform>``
571   .. versionadded:: 3.1
573   Pass a generator-specific platform name to the CMake command (see
574   :variable:`CMAKE_GENERATOR_PLATFORM`). It is an error to provide this
575   option without the ``CMAKE_GENERATOR`` option.
577 ``CMAKE_GENERATOR_TOOLSET <toolset>``
578   Pass a generator-specific toolset name to the CMake command (see
579   :variable:`CMAKE_GENERATOR_TOOLSET`). It is an error to provide this
580   option without the ``CMAKE_GENERATOR`` option.
582 ``CMAKE_GENERATOR_INSTANCE <instance>``
583   .. versionadded:: 3.11
585   Pass a generator-specific instance selection to the CMake command (see
586   :variable:`CMAKE_GENERATOR_INSTANCE`). It is an error to provide this
587   option without the ``CMAKE_GENERATOR`` option.
589 ``CMAKE_ARGS <arg>...``
590   The specified arguments are passed to the :program:`cmake` command line.
591   They can be any argument the :program:`cmake` command understands, not just
592   cache values defined by ``-D...`` arguments (see also
593   :manual:`CMake Options <cmake(1)>`).
595   .. versionadded:: 3.3
596     Arguments may use
597     :manual:`generator expressions <cmake-generator-expressions(7)>`.
599 ``CMAKE_CACHE_ARGS <arg>...``
600   This is an alternate way of specifying cache variables where command line
601   length issues may become a problem. The arguments are expected to be in
602   the form ``-Dvar:STRING=value``, which are then transformed into
603   CMake :command:`set` commands with the ``FORCE`` option used. These
604   ``set()`` commands are written to a pre-load script which is then applied
605   using the :manual:`cmake -C <cmake(1)>` command line option.
607   .. versionadded:: 3.3
608     Arguments may use
609     :manual:`generator expressions <cmake-generator-expressions(7)>`.
611 ``CMAKE_CACHE_DEFAULT_ARGS <arg>...``
612   .. versionadded:: 3.2
614   This is the same as the ``CMAKE_CACHE_ARGS`` option except the ``set()``
615   commands do not include the ``FORCE`` keyword. This means the values act
616   as initial defaults only and will not override any variables already set
617   from a previous run. Use this option with care, as it can lead to
618   different behavior depending on whether the build starts from a fresh
619   build directory or reuses previous build contents.
621   .. versionadded:: 3.15
622     If the CMake generator is the ``Green Hills MULTI`` and not overridden,
623     the original project's settings for the GHS toolset and target system
624     customization cache variables are propagated into the external project.
626 ``SOURCE_SUBDIR <dir>``
627   .. versionadded:: 3.7
629   When no ``CONFIGURE_COMMAND`` option is specified, the configure step
630   assumes the external project has a ``CMakeLists.txt`` file at the top of
631   its source tree (i.e. in ``SOURCE_DIR``). The ``SOURCE_SUBDIR`` option
632   can be used to point to an alternative directory within the source tree
633   to use as the top of the CMake source tree instead. This must be a
634   relative path and it will be interpreted as being relative to
635   ``SOURCE_DIR``.
637   .. versionadded:: 3.14
638     When ``BUILD_IN_SOURCE`` option is enabled, the ``BUILD_COMMAND``
639     is used to point to an alternative directory within the source tree.
641 ``CONFIGURE_HANDLED_BY_BUILD <bool>``
642   .. versionadded:: 3.20
644   Enabling this option relaxes the dependencies of the configure step on
645   other external projects to order-only. This means the configure step will
646   be executed after its external project dependencies are built but it will
647   not be marked dirty when one of its external project dependencies is
648   rebuilt. This option can be enabled when the build step is smart enough
649   to figure out if the configure step needs to be rerun. CMake and Meson are
650   examples of build systems whose build step is smart enough to know if the
651   configure step needs to be rerun.
653 Build Step Options
654 """"""""""""""""""
656 If the configure step assumed the external project uses CMake as its build
657 system, the build step will also. Otherwise, the build step will assume a
658 Makefile-based build and simply run ``make`` with no arguments as the
659 default build step. This can be overridden with custom build commands if
660 required.
662 If both the main project and the external project use make as their build
663 tool, the build step of the external project is invoked as a recursive
664 make using ``$(MAKE)``.  This will communicate some build tool settings
665 from the main project to the external project.  If either the main project
666 or external project is not using make, no build tool settings will be
667 passed to the external project other than those established by the
668 configure step (i.e. running ``ninja -v`` in the main project will not
669 pass ``-v`` to the external project's build step, even if it also uses
670 ``ninja`` as its build tool).
672 ``BUILD_COMMAND <cmd>...``
673   Overrides the default build command
674   (:manual:`generator expressions <cmake-generator-expressions(7)>` are
675   supported). If this option is not given, the default build command will
676   be chosen to integrate with the main build in the most appropriate way
677   (e.g. using recursive ``make`` for Makefile generators or
678   :option:`cmake --build` if the project uses a CMake build). This option
679   can be specified with an empty string as the command to make the build
680   step do nothing.
682 ``BUILD_IN_SOURCE <bool>``
683   When this option is enabled, the build will be done directly within the
684   external project's source tree. This should generally be avoided, the use
685   of a separate build directory is usually preferred, but it can be useful
686   when the external project assumes an in-source build. The ``BINARY_DIR``
687   option should not be specified if building in-source.
689 ``BUILD_ALWAYS <bool>``
690   Enabling this option forces the build step to always be run. This can be
691   the easiest way to robustly ensure that the external project's own build
692   dependencies are evaluated rather than relying on the default
693   success timestamp-based method. This option is not normally needed unless
694   developers are expected to modify something the external project's build
695   depends on in a way that is not detectable via the step target
696   dependencies (e.g. ``SOURCE_DIR`` is used without a download method and
697   developers might modify the sources in ``SOURCE_DIR``).
699 ``BUILD_BYPRODUCTS <file>...``
700   .. versionadded:: 3.2
702   Specifies files that will be generated by the build command but which
703   might or might not have their modification time updated by subsequent
704   builds. This may also be required to explicitly declare dependencies
705   when using the :generator:`Ninja` generator.
706   These ultimately get passed through as ``BYPRODUCTS`` to the
707   build step's own underlying call to :command:`add_custom_command`, which
708   has additional documentation.
710 ``BUILD_JOB_SERVER_AWARE <bool>``
711   .. versionadded:: 3.28
713   Specifies that the build step is aware of the GNU Make job server.
714   See the :command:`add_custom_command` documentation of its
715   ``JOB_SERVER_AWARE`` option for details.  This option is relevant
716   only when an explicit ``BUILD_COMMAND`` is specified.
718 Install Step Options
719 """"""""""""""""""""
721 If the configure step assumed the external project uses CMake as its build
722 system, the install step will also. Otherwise, the install step will assume
723 a Makefile-based build and simply run ``make install`` as the default build
724 step. This can be overridden with custom install commands if required.
726 ``INSTALL_COMMAND <cmd>...``
727   The external project's own install step is invoked as part of the main
728   project's *build*. It is done after the external project's build step
729   and may be before or after the external project's test step (see the
730   ``TEST_BEFORE_INSTALL`` option below). The external project's install
731   rules are not part of the main project's install rules, so if anything
732   from the external project should be installed as part of the main build,
733   these need to be specified in the main build as additional
734   :command:`install` commands. The default install step builds the
735   ``install`` target of the external project, but this can be overridden
736   with a custom command using this option
737   (:manual:`generator expressions <cmake-generator-expressions(7)>` are
738   supported). Passing an empty string as the ``<cmd>`` makes the install
739   step do nothing.
741 ``INSTALL_BYPRODUCTS <file>...``
742   .. versionadded:: 3.26
744   Specifies files that will be generated by the install command but which
745   might or might not have their modification time updated by subsequent
746   installs. This may also be required to explicitly declare dependencies
747   when using the :generator:`Ninja` generator.
748   These ultimately get passed through as ``BYPRODUCTS`` to the
749   install step's own underlying call to :command:`add_custom_command`, which
750   has additional documentation.
752 ``INSTALL_JOB_SERVER_AWARE <bool>``
753   .. versionadded:: 4.0
755   Specifies that the install step is aware of the GNU Make job server.
756   See the :command:`add_custom_command` documentation of its
757   ``JOB_SERVER_AWARE`` option for details.  This option is relevant
758   only when an explicit ``INSTALL_COMMAND`` is specified.
760 .. note::
761   If the :envvar:`CMAKE_INSTALL_MODE` environment variable is set when the
762   main project is built, it will only have an effect if the following
763   conditions are met:
765   * The main project's configure step assumed the external project uses
766     CMake as its build system.
767   * The external project's install command actually runs. Note that due
768     to the way ``ExternalProject`` may use timestamps internally, if
769     nothing the install step depends on needs to be re-executed, the
770     install command might also not need to run.
772   Note also that ``ExternalProject`` does not check whether the
773   :envvar:`CMAKE_INSTALL_MODE` environment variable changes from one run
774   to another.
776 Test Step Options
777 """""""""""""""""
779 The test step is only defined if at least one of the following ``TEST_...``
780 options are provided.
782 ``TEST_COMMAND <cmd>...``
783   Overrides the default test command
784   (:manual:`generator expressions <cmake-generator-expressions(7)>` are
785   supported). If this option is not given, the default behavior of the test
786   step is to build the external project's own ``test`` target. This option
787   can be specified with ``<cmd>`` as an empty string, which allows the test
788   step to still be defined, but it will do nothing. Do not specify any of
789   the other ``TEST_...`` options if providing an empty string as the test
790   command, but prefer to omit all ``TEST_...`` options altogether if the
791   test step target is not needed.
793 ``TEST_BEFORE_INSTALL <bool>``
794   When this option is enabled, the test step will be executed before the
795   install step. The default behavior is for the test step to run after the
796   install step.
798 ``TEST_AFTER_INSTALL <bool>``
799   This option is mainly useful as a way to indicate that the test step is
800   desired but all default behavior is sufficient. Specifying this option
801   with a boolean true value ensures the test step is defined and that it
802   comes after the install step. If both ``TEST_BEFORE_INSTALL`` and
803   ``TEST_AFTER_INSTALL`` are enabled, the latter is silently ignored.
805 ``TEST_EXCLUDE_FROM_MAIN <bool>``
806   .. versionadded:: 3.2
808   If enabled, the main build's default ALL target will not depend on the
809   test step. This can be a useful way of ensuring the test step is defined
810   but only gets invoked when manually requested.
811   This may cause a step target to be created automatically for either
812   the ``install`` or ``build`` step.  See policy :policy:`CMP0114`.
814 Output Logging Options
815 """"""""""""""""""""""
817 Each of the following ``LOG_...`` options can be used to wrap the relevant
818 step in a script to capture its output to files. The log files will be
819 created in ``LOG_DIR`` if supplied or otherwise the ``STAMP_DIR``
820 directory with step-specific file names.
822 ``LOG_DOWNLOAD <bool>``
823   When enabled, the output of the download step is logged to files.
825 ``LOG_UPDATE <bool>``
826   When enabled, the output of the update step is logged to files.
828 ``LOG_PATCH <bool>``
829   .. versionadded:: 3.14
831   When enabled, the output of the patch step is logged to files.
833 ``LOG_CONFIGURE <bool>``
834   When enabled, the output of the configure step is logged to files.
836 ``LOG_BUILD <bool>``
837   When enabled, the output of the build step is logged to files.
839 ``LOG_INSTALL <bool>``
840   When enabled, the output of the install step is logged to files.
842 ``LOG_TEST <bool>``
843   When enabled, the output of the test step is logged to files.
845 ``LOG_MERGED_STDOUTERR <bool>``
846   .. versionadded:: 3.14
848   When enabled, stdout and stderr will be merged for any step whose
849   output is being logged to files.
851 ``LOG_OUTPUT_ON_FAILURE <bool>``
852   .. versionadded:: 3.14
854   This option only has an effect if at least one of the other ``LOG_<step>``
855   options is enabled.  If an error occurs for a step which has logging to
856   file enabled, that step's output will be printed to the console if
857   ``LOG_OUTPUT_ON_FAILURE`` is set to true.  For cases where a large amount
858   of output is recorded, just the end of that output may be printed to the
859   console.
861 Terminal Access Options
862 """""""""""""""""""""""
864 .. versionadded:: 3.4
866 Steps can be given direct access to the terminal in some cases. Giving a
867 step access to the terminal may allow it to receive terminal input if
868 required, such as for authentication details not provided by other options.
869 With the :generator:`Ninja` generator, these options place the steps in the
870 ``console`` :prop_gbl:`job pool <JOB_POOLS>`. Each step can be given access
871 to the terminal individually via the following options:
873 ``USES_TERMINAL_DOWNLOAD <bool>``
874   Give the download step access to the terminal.
876 ``USES_TERMINAL_UPDATE <bool>``
877   Give the update step access to the terminal.
879 ``USES_TERMINAL_PATCH <bool>``
880   .. versionadded:: 3.23
882   Give the patch step access to the terminal.
884 ``USES_TERMINAL_CONFIGURE <bool>``
885   Give the configure step access to the terminal.
887 ``USES_TERMINAL_BUILD <bool>``
888   Give the build step access to the terminal.
890 ``USES_TERMINAL_INSTALL <bool>``
891   Give the install step access to the terminal.
893 ``USES_TERMINAL_TEST <bool>``
894   Give the test step access to the terminal.
896 Target Options
897 """"""""""""""
899 ``DEPENDS <targets>...``
900   Specify other targets on which the external project depends. The other
901   targets will be brought up to date before any of the external project's
902   steps are executed. Because the external project uses additional custom
903   targets internally for each step, the ``DEPENDS`` option is the most
904   convenient way to ensure all of those steps depend on the other targets.
905   Simply doing
906   :command:`add_dependencies(\<name\> \<targets\>) <add_dependencies>` will
907   not make any of the steps dependent on ``<targets>``.
909 ``EXCLUDE_FROM_ALL <bool>``
910   When enabled, this option excludes the external project from the default
911   ALL target of the main build.
913 ``STEP_TARGETS <step-target>...``
914   Generate custom targets for the specified steps. This is required if the
915   steps need to be triggered manually or if they need to be used as
916   dependencies of other targets. If this option is not specified, the
917   default value is taken from the ``EP_STEP_TARGETS`` directory property.
918   See :command:`ExternalProject_Add_StepTargets` below for further
919   discussion of the effects of this option.
921 ``INDEPENDENT_STEP_TARGETS <step-target>...``
922   .. deprecated:: 3.19
923     This is allowed only if policy :policy:`CMP0114` is not set to ``NEW``.
925   Generates custom targets for the specified steps and prevent these targets
926   from having the usual dependencies applied to them. If this option is not
927   specified, the default value is taken from the
928   ``EP_INDEPENDENT_STEP_TARGETS`` directory property. This option is mostly
929   useful for allowing individual steps to be driven independently, such as
930   for a CDash setup where each step should be initiated and reported
931   individually rather than as one whole build. See
932   :command:`ExternalProject_Add_StepTargets` below for further discussion
933   of the effects of this option.
935 Miscellaneous Options
936 """""""""""""""""""""
938 ``LIST_SEPARATOR <sep>``
939   For any of the various ``..._COMMAND`` options, and ``CMAKE_ARGS``,
940   ``ExternalProject`` will replace ``<sep>`` with ``;`` in the specified
941   command lines. This can be used to ensure a command has a literal ``;`` in it
942   where direct usage would otherwise be interpreted as argument separators to
943   CMake APIs instead. Note that the separator should be chosen to avoid being
944   confused for non-list-separator usages of the sequence. For example, using
945   ``LIST_SEPARATOR`` allows for passing list values to CMake cache variables on
946   the command line:
948   .. code-block:: cmake
950     ExternalProject_Add(example
951       ... # Download options, etc.
952       LIST_SEPARATOR ","
953       CMAKE_ARGS "-DCMAKE_PREFIX_PATH:STRING=${first_prefix},${second_prefix}"
954     )
956 ``COMMAND <cmd>...``
957   Any of the other ``..._COMMAND`` options can have additional commands
958   appended to them by following them with as many ``COMMAND ...`` options
959   as needed
960   (:manual:`generator expressions <cmake-generator-expressions(7)>` are
961   supported). For example:
963   .. code-block:: cmake
965     ExternalProject_Add(example
966       ... # Download options, etc.
967       BUILD_COMMAND ${CMAKE_COMMAND} -E echo "Starting $<CONFIG> build"
968       COMMAND       ${CMAKE_COMMAND} --build <BINARY_DIR> --config $<CONFIG>
969       COMMAND       ${CMAKE_COMMAND} -E echo "$<CONFIG> build complete"
970     )
972 It should also be noted that each build step is created via a call to
973 :command:`ExternalProject_Add_Step`. See that command's documentation for the
974 automatic substitutions that are supported for some options.
976 Obtaining Project Properties
977 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
979 .. command:: ExternalProject_Get_Property
981   The ``ExternalProject_Get_Property()`` function retrieves external project
982   target properties:
984   .. code-block:: cmake
986     ExternalProject_Get_Property(<name> <prop1> [<prop2>...])
988   The function stores property values in variables of the same name. Property
989   names correspond to the keyword argument names of ``ExternalProject_Add()``.
990   For example, the source directory might be retrieved like so:
992   .. code-block:: cmake
994     ExternalProject_Get_property(myExtProj SOURCE_DIR)
995     message("Source dir of myExtProj = ${SOURCE_DIR}")
997 Explicit Step Management
998 ^^^^^^^^^^^^^^^^^^^^^^^^
1000 The ``ExternalProject_Add()`` function on its own is often sufficient for
1001 incorporating an external project into the main build. Certain scenarios
1002 require additional work to implement desired behavior, such as adding in a
1003 custom step or making steps available as manually triggerable targets. The
1004 ``ExternalProject_Add_Step()``, ``ExternalProject_Add_StepTargets()`` and
1005 ``ExternalProject_Add_StepDependencies`` functions provide the lower level
1006 control needed to implement such step-level capabilities.
1008 .. command:: ExternalProject_Add_Step
1010   The ``ExternalProject_Add_Step()`` function specifies an additional custom
1011   step for an external project defined by an earlier call to
1012   :command:`ExternalProject_Add`:
1014   .. code-block:: cmake
1016     ExternalProject_Add_Step(<name> <step> [<option>...])
1018   ``<name>`` is the same as the name passed to the original call to
1019   :command:`ExternalProject_Add`. The specified ``<step>`` must not be one of
1020   the pre-defined steps (``mkdir``, ``download``, ``update``,
1021   ``patch``, ``configure``, ``build``, ``install`` or ``test``). The supported
1022   options are:
1024   ``COMMAND <cmd>...``
1025     The command line to be executed by this custom step
1026     (:manual:`generator expressions <cmake-generator-expressions(7)>` are
1027     supported). This option can be repeated multiple times to specify multiple
1028     commands to be executed in order.
1030   ``COMMENT "<text>..."``
1031     Text to be printed when the custom step executes.
1033   ``DEPENDEES <step>...``
1034     Other steps (custom or pre-defined) on which this step depends.
1036   ``DEPENDERS <step>...``
1037     Other steps (custom or pre-defined) that depend on this new custom step.
1039   ``DEPENDS <file>...``
1040     Files on which this custom step depends.
1042   ``INDEPENDENT <bool>``
1043     .. versionadded:: 3.19
1045     Specifies whether this step is independent of the external dependencies
1046     specified by the :command:`ExternalProject_Add`'s ``DEPENDS`` option.
1047     The default is ``FALSE``.  Steps marked as independent may depend only
1048     on other steps marked independent.  See policy :policy:`CMP0114`.
1050     Note that this use of the term "independent" refers only to independence
1051     from external targets specified by the ``DEPENDS`` option and is
1052     orthogonal to a step's dependencies on other steps.
1054     If a step target is created for an independent step by the
1055     :command:`ExternalProject_Add` ``STEP_TARGETS`` option or by the
1056     :command:`ExternalProject_Add_StepTargets` function, it will not depend
1057     on the external targets, but may depend on targets for other steps.
1059   ``BYPRODUCTS <file>...``
1060     .. versionadded:: 3.2
1062     Files that will be generated by this custom step but which might or might
1063     not have their modification time updated by subsequent builds.
1064     This may also be required to explicitly declare dependencies
1065     when using the :generator:`Ninja` generator. This list of
1066     files will ultimately be passed through as the ``BYPRODUCTS`` option to the
1067     :command:`add_custom_command` used to implement the custom step internally,
1068     which has additional documentation.
1070   ``ALWAYS <bool>``
1071     When enabled, this option specifies that the custom step should always be
1072     run (i.e. that it is always considered out of date).
1074   ``JOB_SERVER_AWARE <bool>``
1075     .. versionadded:: 3.28
1077     Specifies that the custom step is aware of the GNU Make job server.
1078     See the :command:`add_custom_command` documentation of its
1079     ``JOB_SERVER_AWARE`` option for details.
1081   ``EXCLUDE_FROM_MAIN <bool>``
1082     When enabled, this option specifies that the external project's main target
1083     does not depend on the custom step.
1084     This may cause step targets to be created automatically for the steps on
1085     which this step depends.  See policy :policy:`CMP0114`.
1087   ``WORKING_DIRECTORY <dir>``
1088     Specifies the working directory to set before running the custom step's
1089     command. If this option is not specified, the directory will be the value
1090     of the :variable:`CMAKE_CURRENT_BINARY_DIR` at the point where
1091     ``ExternalProject_Add_Step()`` was called.
1093   ``LOG <bool>``
1094     If set, this causes the output from the custom step to be captured to files
1095     in the external project's ``LOG_DIR`` if supplied or ``STAMP_DIR``.
1097   ``USES_TERMINAL <bool>``
1098     If enabled, this gives the custom step direct access to the terminal if
1099     possible.
1101   The command line, comment, working directory and byproducts of every
1102   standard and custom step are processed to replace the tokens
1103   ``<SOURCE_DIR>``, ``<SOURCE_SUBDIR>``, ``<BINARY_DIR>``, ``<INSTALL_DIR>``
1104   ``<TMP_DIR>``, ``<DOWNLOAD_DIR>`` and ``<DOWNLOADED_FILE>`` with their
1105   corresponding property values defined in the original call to
1106   :command:`ExternalProject_Add`.
1108   .. versionadded:: 3.3
1109     Token replacement is extended to byproducts.
1111   .. versionadded:: 3.11
1112     The ``<DOWNLOAD_DIR>`` substitution token.
1114 .. command:: ExternalProject_Add_StepTargets
1116   The ``ExternalProject_Add_StepTargets()`` function generates targets for the
1117   steps listed. The name of each created target will be of the form
1118   ``<name>-<step>``:
1120   .. code-block:: cmake
1122     ExternalProject_Add_StepTargets(<name> <step1> [<step2>...])
1124   Creating a target for a step allows it to be used as a dependency of another
1125   target or to be triggered manually. Having targets for specific steps also
1126   allows them to be driven independently of each other by specifying targets on
1127   build command lines. For example, you may be submitting to a sub-project
1128   based dashboard where you want to drive the configure portion of the build,
1129   then submit to the dashboard, followed by the build portion, followed
1130   by tests. If you invoke a custom target that depends on a step halfway
1131   through the step dependency chain, then all the previous steps will also run
1132   to ensure everything is up to date.
1134   Internally, :command:`ExternalProject_Add` calls
1135   :command:`ExternalProject_Add_Step` to create each step. If any
1136   ``STEP_TARGETS`` were specified, then ``ExternalProject_Add_StepTargets()``
1137   will also be called after :command:`ExternalProject_Add_Step`.  Even if a
1138   step is not mentioned in the ``STEP_TARGETS`` option,
1139   ``ExternalProject_Add_StepTargets()`` can still be called later to manually
1140   define a target for the step.
1142   The ``STEP_TARGETS`` option for :command:`ExternalProject_Add` is generally
1143   the easiest way to ensure targets are created for specific steps of interest.
1144   For custom steps, ``ExternalProject_Add_StepTargets()`` must be called
1145   explicitly if a target should also be created for that custom step.
1146   An alternative to these two options is to populate the ``EP_STEP_TARGETS``
1147   directory property.  It acts as a default for the step target options and
1148   can save having to repeatedly specify the same set of step targets when
1149   multiple external projects are being defined.
1151   .. versionadded:: 3.19
1152     If :policy:`CMP0114` is set to ``NEW``, step targets are fully responsible
1153     for holding the custom commands implementing their steps.  The primary
1154     target created by ``ExternalProject_Add`` depends on the step targets, and
1155     the step targets depend on each other.  The target-level dependencies match
1156     the file-level dependencies used by the custom commands for each step.
1157     The targets for steps created with :command:`ExternalProject_Add_Step`'s
1158     ``INDEPENDENT`` option do not depend on the external targets specified
1159     by :command:`ExternalProject_Add`'s ``DEPENDS`` option.  The predefined
1160     steps ``mkdir``, ``download``, ``update``, and ``patch`` are independent.
1162   If :policy:`CMP0114` is not ``NEW``, the following deprecated behavior
1163   is available:
1165   * A deprecated ``NO_DEPENDS`` option may be specified immediately after the
1166     ``<name>`` and before the first step.
1167     If the ``NO_DEPENDS`` option is specified, the step target will not depend
1168     on the dependencies of the external project (i.e. on any dependencies of the
1169     ``<name>`` custom target created by :command:`ExternalProject_Add`). This is
1170     usually safe for the ``download``, ``update`` and ``patch`` steps, since
1171     they do not typically require that the dependencies are updated and built.
1172     Using ``NO_DEPENDS`` for any of the other pre-defined steps, however, may
1173     break parallel builds. Only use ``NO_DEPENDS`` where it is certain that the
1174     named steps genuinely do not have dependencies. For custom steps, consider
1175     whether or not the custom commands require the dependencies to be
1176     configured, built and installed.
1178   * The ``INDEPENDENT_STEP_TARGETS`` option for :command:`ExternalProject_Add`,
1179     or the ``EP_INDEPENDENT_STEP_TARGETS`` directory property, tells the
1180     function to call ``ExternalProject_Add_StepTargets()`` internally
1181     using the ``NO_DEPENDS`` option for the specified steps.
1183 .. command:: ExternalProject_Add_StepDependencies
1185   .. versionadded:: 3.2
1187   The ``ExternalProject_Add_StepDependencies()`` function can be used to add
1188   dependencies to a step. The dependencies added must be targets CMake already
1189   knows about (these can be ordinary executable or library targets, custom
1190   targets or even step targets of another external project):
1192   .. code-block:: cmake
1194     ExternalProject_Add_StepDependencies(<name> <step> <target1> [<target2>...])
1196   This function takes care to set both target and file level dependencies and
1197   will ensure that parallel builds will not break. It should be used instead of
1198   :command:`add_dependencies` whenever adding a dependency for some of the step
1199   targets generated by the ``ExternalProject`` module.
1201 Examples
1202 ^^^^^^^^
1204 The following example shows how to download and build a hypothetical project
1205 called *FooBar* from github:
1207 .. code-block:: cmake
1209   include(ExternalProject)
1210   ExternalProject_Add(foobar
1211     GIT_REPOSITORY    git@github.com:FooCo/FooBar.git
1212     GIT_TAG           origin/release/1.2.3
1213   )
1215 For the sake of the example, also define a second hypothetical external project
1216 called *SecretSauce*, which is downloaded from a web server. Two URLs are given
1217 to take advantage of a faster internal network if available, with a fallback to
1218 a slower external server. The project is a typical ``Makefile`` project with no
1219 configure step, so some of the default commands are overridden. The build is
1220 only required to build the *sauce* target:
1222 .. code-block:: cmake
1224   find_program(MAKE_EXE NAMES gmake nmake make)
1225   ExternalProject_Add(secretsauce
1226     URL               http://intranet.somecompany.com/artifacts/sauce-2.7.tgz
1227                       https://www.somecompany.com/downloads/sauce-2.7.zip
1228     URL_HASH          MD5=d41d8cd98f00b204e9800998ecf8427e
1229     CONFIGURE_COMMAND ""
1230     BUILD_COMMAND     ${MAKE_EXE} sauce
1231   )
1233 Suppose the build step of ``secretsauce`` requires that ``foobar`` must already
1234 be built. This could be enforced like so:
1236 .. code-block:: cmake
1238   ExternalProject_Add_StepDependencies(secretsauce build foobar)
1240 Another alternative would be to create a custom target for ``foobar``'s build
1241 step and make ``secretsauce`` depend on that rather than the whole ``foobar``
1242 project. This would mean ``foobar`` only needs to be built, it doesn't need to
1243 run its install or test steps before ``secretsauce`` can be built. The
1244 dependency can also be defined along with the ``secretsauce`` project:
1246 .. code-block:: cmake
1248   ExternalProject_Add_StepTargets(foobar build)
1249   ExternalProject_Add(secretsauce
1250     URL               http://intranet.somecompany.com/artifacts/sauce-2.7.tgz
1251                       https://www.somecompany.com/downloads/sauce-2.7.zip
1252     URL_HASH          MD5=d41d8cd98f00b204e9800998ecf8427e
1253     CONFIGURE_COMMAND ""
1254     BUILD_COMMAND     ${MAKE_EXE} sauce
1255     DEPENDS           foobar-build
1256   )
1258 Instead of calling :command:`ExternalProject_Add_StepTargets`, the target could
1259 be defined along with the ``foobar`` project itself:
1261 .. code-block:: cmake
1263   ExternalProject_Add(foobar
1264     GIT_REPOSITORY git@github.com:FooCo/FooBar.git
1265     GIT_TAG        origin/release/1.2.3
1266     STEP_TARGETS   build
1267   )
1269 If many external projects should have the same set of step targets, setting a
1270 directory property may be more convenient. The ``build`` step target could be
1271 created automatically by setting the ``EP_STEP_TARGETS`` directory property
1272 before creating the external projects with :command:`ExternalProject_Add`:
1274 .. code-block:: cmake
1276   set_property(DIRECTORY PROPERTY EP_STEP_TARGETS build)
1278 Lastly, suppose that ``secretsauce`` provides a script called ``makedoc`` which
1279 can be used to generate its own documentation. Further suppose that the script
1280 expects the output directory to be provided as the only parameter and that it
1281 should be run from the ``secretsauce`` source directory. A custom step and a
1282 custom target to trigger the script can be defined like so:
1284 .. code-block:: cmake
1286   ExternalProject_Add_Step(secretsauce docs
1287     COMMAND           <SOURCE_DIR>/makedoc <BINARY_DIR>
1288     WORKING_DIRECTORY <SOURCE_DIR>
1289     COMMENT           "Building secretsauce docs"
1290     ALWAYS            TRUE
1291     EXCLUDE_FROM_MAIN TRUE
1292   )
1293   ExternalProject_Add_StepTargets(secretsauce docs)
1295 The custom step could then be triggered from the main build like so::
1297   cmake --build . --target secretsauce-docs
1299 #]=======================================================================]
1301 include(${CMAKE_CURRENT_LIST_DIR}/ExternalProject/shared_internal_commands.cmake)
1303 define_property(DIRECTORY PROPERTY "EP_BASE" INHERITED)
1304 define_property(DIRECTORY PROPERTY "EP_PREFIX" INHERITED)
1305 define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED)
1306 define_property(DIRECTORY PROPERTY "EP_INDEPENDENT_STEP_TARGETS" INHERITED)
1307 define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED)
1309 # file(TO_CMAKE_PATH) will interpret a platform-specific character as a path
1310 # separator, and if its input contains that character, it will treat the input
1311 # as a list. Sometimes we have a string that we know is always a single path,
1312 # but it may contain the separator character. To prevent it being treated as a
1313 # list of paths, this function masks the separator character while calling
1314 # file(TO_CMAKE_PATH).
1315 function(_ep_to_single_cmake_path out_var input)
1316   if(WIN32)
1317     set(unsafe_char ";")
1318   else()
1319     set(unsafe_char ":")
1320   endif()
1322   string(REPLACE "${unsafe_char}" "__EP_MARKER__" safe_input "${input}")
1323   file(TO_CMAKE_PATH "${safe_input}" converted_input)
1324   string(REPLACE "__EP_MARKER__" "${unsafe_char}" output "${converted_input}")
1326   set(${out_var} "${output}" PARENT_SCOPE)
1327 endfunction()
1329 function(_ep_set_directories name)
1330   get_property(prefix TARGET ${name} PROPERTY _EP_PREFIX)
1331   if(NOT prefix)
1332     get_property(prefix DIRECTORY PROPERTY EP_PREFIX)
1333     if(NOT prefix)
1334       get_property(base DIRECTORY PROPERTY EP_BASE)
1335       if(NOT base)
1336         set(prefix "${name}-prefix")
1337       endif()
1338     endif()
1339   endif()
1340   if(prefix)
1341     _ep_to_single_cmake_path(prefix "${prefix}")
1342     set(tmp_default "${prefix}/tmp")
1343     set(download_default "${prefix}/src")
1344     set(source_default "${prefix}/src/${name}")
1345     set(binary_default "${prefix}/src/${name}-build")
1346     set(stamp_default "${prefix}/src/${name}-stamp")
1347     set(install_default "${prefix}")
1348   else()
1349     _ep_to_single_cmake_path(base "${base}")
1350     set(tmp_default "${base}/tmp/${name}")
1351     set(download_default "${base}/Download/${name}")
1352     set(source_default "${base}/Source/${name}")
1353     set(binary_default "${base}/Build/${name}")
1354     set(stamp_default "${base}/Stamp/${name}")
1355     set(install_default "${base}/Install/${name}")
1356   endif()
1357   get_property(build_in_source TARGET ${name} PROPERTY _EP_BUILD_IN_SOURCE)
1358   if(build_in_source)
1359     get_property(have_binary_dir TARGET ${name} PROPERTY _EP_BINARY_DIR SET)
1360     if(have_binary_dir)
1361       message(FATAL_ERROR
1362         "External project ${name} has both BINARY_DIR and BUILD_IN_SOURCE!"
1363       )
1364     endif()
1365   endif()
1366   set(top "${CMAKE_CURRENT_BINARY_DIR}")
1368   # Apply defaults and convert to absolute paths.
1369   set(places stamp download source binary install tmp)
1370   foreach(var IN LISTS places)
1371     string(TOUPPER "${var}" VAR)
1372     get_property(${var}_dir TARGET ${name} PROPERTY _EP_${VAR}_DIR)
1373     if(NOT ${var}_dir)
1374       set(${var}_dir "${${var}_default}")
1375     endif()
1376     if(NOT IS_ABSOLUTE "${${var}_dir}")
1377       get_filename_component(${var}_dir "${top}/${${var}_dir}" ABSOLUTE)
1378     endif()
1379     _ep_to_single_cmake_path(${var}_dir "${${var}_dir}")
1380     set_property(TARGET ${name} PROPERTY _EP_${VAR}_DIR "${${var}_dir}")
1381     set(_EP_${VAR}_DIR "${${var}_dir}" PARENT_SCOPE)
1382   endforeach()
1384   # Special case for default log directory based on stamp directory.
1385   get_property(log_dir TARGET ${name} PROPERTY _EP_LOG_DIR)
1386   if(NOT log_dir)
1387     get_property(log_dir TARGET ${name} PROPERTY _EP_STAMP_DIR)
1388   endif()
1389   if(NOT IS_ABSOLUTE "${log_dir}")
1390     get_filename_component(log_dir "${top}/${log_dir}" ABSOLUTE)
1391   endif()
1392   _ep_to_single_cmake_path(log_dir "${log_dir}")
1393   set_property(TARGET ${name} PROPERTY _EP_LOG_DIR "${log_dir}")
1394   set(_EP_LOG_DIR "${log_dir}" PARENT_SCOPE)
1396   get_property(source_subdir TARGET ${name} PROPERTY _EP_SOURCE_SUBDIR)
1397   if(NOT source_subdir)
1398     set_property(TARGET ${name} PROPERTY _EP_SOURCE_SUBDIR "")
1399     set(_EP_SOURCE_SUBDIR "" PARENT_SCOPE)
1400   elseif(IS_ABSOLUTE "${source_subdir}")
1401     message(FATAL_ERROR
1402       "External project ${name} has non-relative SOURCE_SUBDIR!"
1403     )
1404   else()
1405     # Prefix with a slash so that when appended to the source directory, it
1406     # behaves as expected.
1407     _ep_to_single_cmake_path(source_subdir "${source_subdir}")
1408     set_property(TARGET ${name} PROPERTY _EP_SOURCE_SUBDIR "/${source_subdir}")
1409     set(_EP_SOURCE_SUBDIR "/${source_subdir}" PARENT_SCOPE)
1410   endif()
1411   if(build_in_source)
1412     get_property(source_dir TARGET ${name} PROPERTY _EP_SOURCE_DIR)
1413     if(source_subdir)
1414       set_property(TARGET ${name} PROPERTY
1415         _EP_BINARY_DIR "${source_dir}/${source_subdir}"
1416       )
1417       set(_EP_BINARY_DIR "${source_dir}/${source_subdir}" PARENT_SCOPE)
1418     else()
1419       set_property(TARGET ${name} PROPERTY
1420         _EP_BINARY_DIR "${source_dir}"
1421       )
1422       set(_EP_BINARY_DIR "${source_dir}" PARENT_SCOPE)
1423     endif()
1424   endif()
1426   # This script will be used both here and by the mkdir step. We create the
1427   # directories now at configure time and ensure they exist again at build
1428   # time (since somebody might remove one of the required directories and try
1429   # to rebuild without re-running cmake). They need to exist now at makefile
1430   # generation time for Borland make and wmake so that CMake may generate
1431   # makefiles with "cd C:\short\paths\with\no\spaces" commands in them.
1432   set(script_filename "${tmp_dir}/${name}-mkdirs.cmake")
1433   configure_file(
1434     ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/mkdirs.cmake.in
1435     ${script_filename}
1436     @ONLY
1437   )
1438   unset(cfgdir) # do not leak into mkdirs.cmake script
1439   include(${script_filename})
1440 endfunction()
1443 # IMPORTANT: this MUST be a macro and not a function because of the
1444 # in-place replacements that occur in each ${var}
1446 macro(_ep_replace_location_tags target_name)
1447   set(vars ${ARGN})
1448   foreach(var IN LISTS vars)
1449     if(var)
1450       foreach(dir IN ITEMS
1451         SOURCE_DIR
1452         SOURCE_SUBDIR
1453         BINARY_DIR
1454         INSTALL_DIR
1455         TMP_DIR
1456         DOWNLOAD_DIR
1457         DOWNLOADED_FILE
1458         LOG_DIR
1459       )
1460         get_property(val TARGET ${target_name} PROPERTY _EP_${dir})
1461         string(REPLACE "<${dir}>" "${val}" ${var} "${${var}}")
1462       endforeach()
1463     endif()
1464   endforeach()
1465 endmacro()
1468 function(_ep_command_line_to_initial_cache
1469   var
1470   args
1471   force
1473   set(script_initial_cache "")
1474   set(regex "^([^:]+):([^=]+)=(.*)$")
1475   set(setArg "")
1476   set(forceArg "")
1477   if(force)
1478     set(forceArg "FORCE")
1479   endif()
1480   foreach(line IN LISTS args)
1481     if("${line}" MATCHES "^-D(.*)")
1482       set(line "${CMAKE_MATCH_1}")
1483       if(NOT "${setArg}" STREQUAL "")
1484         # This is required to build up lists in variables, or complete an entry
1485         string(APPEND setArg
1486           "${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})"
1487         )
1488         string(APPEND script_initial_cache "\n${setArg}")
1489         set(accumulator "")
1490         set(setArg "")
1491       endif()
1492       if("${line}" MATCHES "${regex}")
1493         set(name "${CMAKE_MATCH_1}")
1494         set(type "${CMAKE_MATCH_2}")
1495         set(value "${CMAKE_MATCH_3}")
1496         set(setArg "set(${name} \"${value}")
1497       else()
1498         message(WARNING "Line '${line}' does not match regex. Ignoring.")
1499       endif()
1500     else()
1501       # Assume this is a list to append to the last var
1502       string(APPEND accumulator ";${line}")
1503     endif()
1504   endforeach()
1505   # Catch the final line of the args
1506   if(NOT "${setArg}" STREQUAL "")
1507     string(APPEND setArg
1508       "${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})"
1509     )
1510     string(APPEND script_initial_cache "\n${setArg}")
1511   endif()
1512   set(${var} ${script_initial_cache} PARENT_SCOPE)
1513 endfunction()
1516 function(_ep_write_initial_cache
1517   target_name
1518   script_filename
1519   script_initial_cache
1521   # Write out values into an initial cache, that will be passed to CMake with -C
1522   # Replace location tags.
1523   _ep_replace_location_tags(${target_name} script_initial_cache)
1524   _ep_replace_location_tags(${target_name} script_filename)
1525   # Replace list separators.
1526   get_property(sep TARGET ${target_name} PROPERTY _EP_LIST_SEPARATOR)
1527   if(sep AND script_initial_cache)
1528     string(REPLACE "${sep}" ";" script_initial_cache "${script_initial_cache}")
1529   endif()
1530   # Write out the initial cache file to the location specified.
1531   file(GENERATE OUTPUT "${script_filename}" CONTENT "${script_initial_cache}")
1532 endfunction()
1535 function(ExternalProject_Get_Property name)
1536   foreach(var IN LISTS ARGN)
1537     string(TOUPPER "${var}" VAR)
1538     get_property(is_set TARGET ${name} PROPERTY _EP_${VAR} SET)
1539     if(NOT is_set)
1540       message(FATAL_ERROR "External project \"${name}\" has no ${var}")
1541     endif()
1542     get_property(${var} TARGET ${name} PROPERTY _EP_${VAR})
1543     set(${var} "${${var}}" PARENT_SCOPE)
1544   endforeach()
1545 endfunction()
1548 function(_ep_get_configure_command_id
1549   name
1550   cfg_cmd_id_var
1552   get_target_property(cmd ${name} _EP_CONFIGURE_COMMAND)
1554   if(cmd STREQUAL "")
1555     # Explicit empty string means no configure step for this project
1556     set(${cfg_cmd_id_var} "none" PARENT_SCOPE)
1557   else()
1558     if(NOT cmd)
1559       # Default is "use cmake":
1560       set(${cfg_cmd_id_var} "cmake" PARENT_SCOPE)
1561     else()
1562       # Otherwise we have to analyze the value:
1563       if(cmd MATCHES "^[^;]*/configure")
1564         set(${cfg_cmd_id_var} "configure" PARENT_SCOPE)
1565       elseif(cmd MATCHES "^[^;]*/cmake" AND NOT cmd MATCHES ";-[PE];")
1566         set(${cfg_cmd_id_var} "cmake" PARENT_SCOPE)
1567       elseif(cmd MATCHES "config")
1568         set(${cfg_cmd_id_var} "configure" PARENT_SCOPE)
1569       else()
1570         set(${cfg_cmd_id_var} "unknown:${cmd}" PARENT_SCOPE)
1571       endif()
1572     endif()
1573   endif()
1574 endfunction()
1577 function(_ep_get_build_command
1578   name
1579   step
1580   cmd_var
1582   set(cmd "")
1583   set(args)
1584   _ep_get_configure_command_id(${name} cfg_cmd_id)
1585   if(cfg_cmd_id STREQUAL "cmake")
1586     # Adding a CMake project as an External Project.  Select command based on generator
1587     get_property(cmake_generator TARGET ${name} PROPERTY _EP_CMAKE_GENERATOR)
1588     # cmake_generator is the CMake generator of the ExternalProject target being added
1589     # CMAKE_GENERATOR is the CMake generator of the Current Project
1590     if("${CMAKE_GENERATOR}" MATCHES "Make" AND
1591        ("${cmake_generator}" MATCHES "Make" OR NOT cmake_generator))
1592       # The project uses the same Makefile generator.  Use recursive make.
1593       set(cmd "$(MAKE)")
1594       if(step STREQUAL "INSTALL")
1595         set(args install)
1596       endif()
1597       if("x${step}x" STREQUAL "xTESTx")
1598         set(args test)
1599       endif()
1600     else()
1601       # Drive the project with "cmake --build".
1602       if(NOT cmake_generator)
1603         # If there is no CMake Generator defined on the ExternalProject,
1604         # use the same Generator as the current project
1605         set(cmake_generator "${CMAKE_GENERATOR}")
1606       endif()
1607       get_target_property(cmake_command ${name} _EP_CMAKE_COMMAND)
1608       if(cmake_command)
1609         set(cmd "${cmake_command}")
1610       else()
1611         set(cmd "${CMAKE_COMMAND}")
1612       endif()
1613       set(args --build ".")
1614       get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
1615       if(_isMultiConfig)
1616         if (CMAKE_CFG_INTDIR AND
1617             NOT CMAKE_CFG_INTDIR STREQUAL "." AND
1618             NOT CMAKE_CFG_INTDIR MATCHES "\\$")
1619           # CMake 3.4 and below used the CMAKE_CFG_INTDIR placeholder value
1620           # provided by multi-configuration generators.  Some projects were
1621           # taking advantage of that undocumented implementation detail to
1622           # specify a specific configuration here.  They should use
1623           # BUILD_COMMAND to change the default command instead, but for
1624           # compatibility honor the value.
1625           set(config ${CMAKE_CFG_INTDIR})
1626           message(AUTHOR_WARNING
1627             "CMAKE_CFG_INTDIR should not be set by project code.\n"
1628             "To get a non-default build command, use the BUILD_COMMAND option."
1629           )
1630         else()
1631           set(config $<CONFIG>)
1632         endif()
1633         list(APPEND args --config ${config})
1634       endif()
1635       if(step STREQUAL "INSTALL")
1636         if("${cmake_generator}" MATCHES "Green Hills MULTI")
1637           list(APPEND args --target INSTALL)
1638         else()
1639           list(APPEND args --target install)
1640         endif()
1641       endif()
1642       # But for "TEST" drive the project with corresponding "ctest".
1643       if("x${step}x" STREQUAL "xTESTx")
1644         string(REGEX REPLACE "^(.*/)cmake([^/]*)$" "\\1ctest\\2" cmd "${cmd}")
1645         set(args "")
1646         if(_isMultiConfig)
1647           list(APPEND args -C ${config})
1648         endif()
1649       endif()
1650     endif()
1651   else()
1652     # Non-CMake project.  Guess "make" and "make install" and "make test".
1653     if("${CMAKE_GENERATOR}" MATCHES "Makefiles")
1654       # Try to get the parallel arguments
1655       set(cmd "$(MAKE)")
1656     else()
1657       set(cmd "make")
1658     endif()
1659     if(step STREQUAL "INSTALL")
1660       set(args install)
1661     endif()
1662     if("x${step}x" STREQUAL "xTESTx")
1663       set(args test)
1664     endif()
1665   endif()
1667   # Use user-specified arguments instead of default arguments, if any.
1668   get_property(have_args TARGET ${name} PROPERTY _EP_${step}_ARGS SET)
1669   if(have_args)
1670     get_target_property(args ${name} _EP_${step}_ARGS)
1671   endif()
1673   if(NOT "${args}" STREQUAL "")
1674     # args could have empty items, so we must quote it to prevent them
1675     # from being silently removed
1676     list(APPEND cmd "${args}")
1677   endif()
1678   set(${cmd_var} "${cmd}" PARENT_SCOPE)
1679 endfunction()
1682 function(_ep_write_log_script
1683   name
1684   step
1685   cmd_var
1687   ExternalProject_Get_Property(${name} log_dir)
1688   ExternalProject_Get_Property(${name} stamp_dir)
1689   set(command "${${cmd_var}}")
1691   set(make "")
1692   set(code_cygpath_make "")
1693   if(command MATCHES "^\\$\\(MAKE\\)")
1694     # GNU make recognizes the string "$(MAKE)" as recursive make, so
1695     # ensure that it appears directly in the makefile.
1696     string(REGEX REPLACE "^\\$\\(MAKE\\)" "\${make}" command "${command}")
1697     set(make "-Dmake=$(MAKE)")
1699     if(WIN32 AND NOT CYGWIN)
1700       set(code_cygpath_make "
1701 if(\${make} MATCHES \"^/\")
1702   execute_process(
1703     COMMAND cygpath -w \${make}
1704     OUTPUT_VARIABLE cygpath_make
1705     ERROR_VARIABLE cygpath_make
1706     RESULT_VARIABLE cygpath_error
1707     OUTPUT_STRIP_TRAILING_WHITESPACE
1708   )
1709   if(NOT cygpath_error)
1710     set(make \${cygpath_make})
1711   endif()
1712 endif()
1714     endif()
1715   endif()
1717   set(config "")
1718   if("${CMAKE_CFG_INTDIR}" MATCHES "^\\$")
1719     string(REPLACE "${CMAKE_CFG_INTDIR}" "\${config}" command "${command}")
1720     set(config "-Dconfig=${CMAKE_CFG_INTDIR}")
1721   endif()
1723   # Wrap multiple 'COMMAND' lines up into a second-level wrapper
1724   # script so all output can be sent to one log file.
1725   if(command MATCHES "(^|;)COMMAND;")
1726     set(code_execute_process "
1727 ${code_cygpath_make}
1728 execute_process(COMMAND \${command} RESULT_VARIABLE result)
1729 if(result)
1730   set(msg \"Command failed (\${result}):\\n\")
1731   foreach(arg IN LISTS command)
1732     set(msg \"\${msg} '\${arg}'\")
1733   endforeach()
1734   message(FATAL_ERROR \"\${msg}\")
1735 endif()
1737     set(code "")
1738     set(cmd "")
1739     set(sep "")
1740     foreach(arg IN LISTS command)
1741       if("x${arg}" STREQUAL "xCOMMAND")
1742         if(NOT "x${cmd}" STREQUAL "x")
1743           string(APPEND code "set(command \"${cmd}\")${code_execute_process}")
1744         endif()
1745         set(cmd "")
1746         set(sep "")
1747       else()
1748         string(APPEND cmd "${sep}${arg}")
1749         set(sep ";")
1750       endif()
1751     endforeach()
1752     string(APPEND code "set(command \"${cmd}\")${code_execute_process}")
1753     file(GENERATE
1754       OUTPUT "${stamp_dir}/${name}-${step}-$<CONFIG>-impl.cmake"
1755       CONTENT "${code}"
1756     )
1757     set(command
1758       ${CMAKE_COMMAND}
1759       "-Dmake=\${make}"
1760       "-Dconfig=\${config}"
1761       -P ${stamp_dir}/${name}-${step}-$<CONFIG>-impl.cmake
1762     )
1763   endif()
1765   # Wrap the command in a script to log output to files.
1766   set(script ${stamp_dir}/${name}-${step}-$<CONFIG>.cmake)
1767   set(logbase ${log_dir}/${name}-${step})
1768   get_property(log_merged
1769     TARGET ${name}
1770     PROPERTY _EP_LOG_MERGED_STDOUTERR
1771   )
1772   get_property(log_output_on_failure
1773     TARGET ${name}
1774     PROPERTY _EP_LOG_OUTPUT_ON_FAILURE
1775   )
1776   if (log_merged)
1777     set(stdout_log "${logbase}.log")
1778     set(stderr_log "${logbase}.log")
1779   else()
1780     set(stdout_log "${logbase}-out.log")
1781     set(stderr_log "${logbase}-err.log")
1782   endif()
1783   set(code "
1784 cmake_minimum_required(VERSION \${CMAKE_VERSION}) # this file comes with cmake
1785 ${code_cygpath_make}
1786 set(command \"${command}\")
1787 set(log_merged \"${log_merged}\")
1788 set(log_output_on_failure \"${log_output_on_failure}\")
1789 set(stdout_log \"${stdout_log}\")
1790 set(stderr_log \"${stderr_log}\")
1791 execute_process(
1792   COMMAND \${command}
1793   RESULT_VARIABLE result
1794   OUTPUT_FILE \"\${stdout_log}\"
1795   ERROR_FILE \"\${stderr_log}\"
1797 macro(read_up_to_max_size log_file output_var)
1798   file(SIZE \${log_file} determined_size)
1799   set(max_size 10240)
1800   if (determined_size GREATER max_size)
1801     math(EXPR seek_position \"\${determined_size} - \${max_size}\")
1802     file(READ \${log_file} \${output_var} OFFSET \${seek_position})
1803     set(\${output_var} \"...skipping to end...\\n\${\${output_var}}\")
1804   else()
1805     file(READ \${log_file} \${output_var})
1806   endif()
1807 endmacro()
1808 if(result)
1809   set(msg \"Command failed: \${result}\\n\")
1810   foreach(arg IN LISTS command)
1811     set(msg \"\${msg} '\${arg}'\")
1812   endforeach()
1813   if (\${log_merged})
1814     set(msg \"\${msg}\\nSee also\\n  \${stderr_log}\")
1815   else()
1816     set(msg \"\${msg}\\nSee also\\n  ${logbase}-*.log\")
1817   endif()
1818   if (\${log_output_on_failure})
1819     message(SEND_ERROR \"\${msg}\")
1820     if (\${log_merged})
1821       read_up_to_max_size(\"\${stderr_log}\" error_log_contents)
1822       message(STATUS \"Log output is:\\n\${error_log_contents}\")
1823     else()
1824       read_up_to_max_size(\"\${stdout_log}\" out_log_contents)
1825       read_up_to_max_size(\"\${stderr_log}\" err_log_contents)
1826       message(STATUS \"stdout output is:\\n\${out_log_contents}\")
1827       message(STATUS \"stderr output is:\\n\${err_log_contents}\")
1828     endif()
1829     message(FATAL_ERROR \"Stopping after outputting logs.\")
1830   else()
1831     message(FATAL_ERROR \"\${msg}\")
1832   endif()
1833 else()
1834   if(NOT \"${CMAKE_GENERATOR}\" MATCHES \"Ninja\")
1835     set(msg \"${name} ${step} command succeeded.  See also ${logbase}-*.log\")
1836     message(STATUS \"\${msg}\")
1837   endif()
1838 endif()
1840   file(GENERATE OUTPUT "${script}" CONTENT "${code}")
1841   set(command ${CMAKE_COMMAND} ${make} ${config} -P ${script})
1842   set(${cmd_var} "${command}" PARENT_SCOPE)
1843 endfunction()
1846 # On multi-config generators, provide a placeholder for a per-config subdir.
1847 # On single-config generators, this is empty.
1848 function(_ep_get_configuration_subdir_genex suffix_var)
1849   set(suffix "")
1850   get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
1851   if(_isMultiConfig)
1852     if(CMAKE_GENERATOR STREQUAL "Xcode")
1853       # The Xcode generator does not support per-config sources,
1854       # so use the underlying build system's placeholder instead.
1855       # FIXME(#23652): We have no test for the use case requiring
1856       # CMAKE_CFG_INTDIR for XCODE_EMIT_EFFECTIVE_PLATFORM_NAME,
1857       # but $<CONFIG> does not work.
1858       set(suffix "/${CMAKE_CFG_INTDIR}")
1859     else()
1860       set(suffix "/$<CONFIG>")
1861     endif()
1862   endif()
1863   set(${suffix_var} "${suffix}" PARENT_SCOPE)
1864 endfunction()
1867 function(_ep_get_step_stampfile
1868   name
1869   step
1870   stampfile_var
1872   ExternalProject_Get_Property(${name} stamp_dir)
1874   _ep_get_configuration_subdir_genex(cfgdir)
1875   set(stampfile "${stamp_dir}${cfgdir}/${name}-${step}")
1877   set(${stampfile_var} "${stampfile}" PARENT_SCOPE)
1878 endfunction()
1881 function(_ep_get_complete_stampfile
1882   name
1883   stampfile_var
1885   set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)
1886   _ep_get_configuration_subdir_genex(cfgdir)
1887   set(stampfile "${cmf_dir}${cfgdir}/${name}-complete")
1889   set(${stampfile_var} ${stampfile} PARENT_SCOPE)
1890 endfunction()
1893 function(_ep_step_add_target
1894   name
1895   step
1896   no_deps
1898   if(TARGET ${name}-${step})
1899     return()
1900   endif()
1901   get_property(cmp0114 TARGET ${name} PROPERTY _EP_CMP0114)
1902   _ep_get_step_stampfile(${name} ${step} stamp_file)
1903   cmake_policy(PUSH)
1904   if(cmp0114 STREQUAL "NEW")
1905     # To implement CMP0114 NEW behavior with Makefile generators,
1906     # we need CMP0113 NEW behavior.
1907     cmake_policy(SET CMP0113 NEW)
1908   endif()
1909   add_custom_target(${name}-${step} DEPENDS ${stamp_file})
1910   cmake_policy(POP)
1911   set_target_properties(${name}-${step} PROPERTIES
1912     _EP_IS_EXTERNAL_PROJECT_STEP 1
1913     LABELS "${name}"
1914     FOLDER "ExternalProjectTargets/${name}"
1915   )
1917   if(cmp0114 STREQUAL "NEW")
1918     # Add target-level dependencies for the step.
1919     get_property(exclude_from_main
1920       TARGET ${name}
1921       PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN
1922     )
1923     if(NOT exclude_from_main)
1924       add_dependencies(${name} ${name}-${step})
1925     endif()
1926     _ep_step_add_target_dependencies(${name} ${step} ${step})
1927     _ep_step_add_target_dependents(${name} ${step} ${step})
1929     get_property(independent TARGET ${name} PROPERTY _EP_${step}_INDEPENDENT)
1930   else()
1931     if(no_deps AND "${step}" MATCHES "^(configure|build|install|test)$")
1932       message(AUTHOR_WARNING
1933         "Using NO_DEPENDS for \"${step}\" step  might break parallel builds"
1934       )
1935     endif()
1936     set(independent ${no_deps})
1937   endif()
1939   # Depend on other external projects (target-level).
1940   if(NOT independent)
1941     get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
1942     foreach(arg IN LISTS deps)
1943       add_dependencies(${name}-${step} ${arg})
1944     endforeach()
1945   endif()
1946 endfunction()
1949 function(_ep_step_add_target_dependencies
1950   name
1951   step
1952   node
1954   get_property(dependees
1955     TARGET ${name}
1956     PROPERTY _EP_${node}_INTERNAL_DEPENDEES
1957   )
1958   list(REMOVE_DUPLICATES dependees)
1959   foreach(dependee IN LISTS dependees)
1960     get_property(exclude_from_main
1961       TARGET ${name}
1962       PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN
1963     )
1964     get_property(dependee_dependers
1965       TARGET ${name}
1966       PROPERTY _EP_${dependee}_INTERNAL_DEPENDERS
1967     )
1968     if(exclude_from_main OR dependee_dependers MATCHES ";")
1969       # The step on which our step target depends itself has
1970       # dependents in multiple targes.  It needs a step target too
1971       # so that there is a unique place for its custom command.
1972       _ep_step_add_target("${name}" "${dependee}" "FALSE")
1973     endif()
1975     if(TARGET ${name}-${dependee})
1976       add_dependencies(${name}-${step} ${name}-${dependee})
1977     else()
1978       _ep_step_add_target_dependencies(${name} ${step} ${dependee})
1979     endif()
1980   endforeach()
1981 endfunction()
1984 function(_ep_step_add_target_dependents
1985   name
1986   step
1987   node
1989   get_property(dependers
1990     TARGET ${name}
1991     PROPERTY _EP_${node}_INTERNAL_DEPENDERS
1992   )
1993   list(REMOVE_DUPLICATES dependers)
1994   foreach(depender IN LISTS dependers)
1995     if(TARGET ${name}-${depender})
1996       add_dependencies(${name}-${depender} ${name}-${step})
1997     else()
1998       _ep_step_add_target_dependents(${name} ${step} ${depender})
1999     endif()
2000   endforeach()
2001 endfunction()
2004 function(ExternalProject_Add_StepTargets name)
2005   get_property(cmp0114 TARGET ${name} PROPERTY _EP_CMP0114)
2006   set(steps ${ARGN})
2007   if(ARGC GREATER 1 AND "${ARGV1}" STREQUAL "NO_DEPENDS")
2008     set(no_deps 1)
2009     list(REMOVE_AT steps 0)
2010   else()
2011     set(no_deps 0)
2012   endif()
2013   if(cmp0114 STREQUAL "NEW")
2014     if(no_deps)
2015       message(FATAL_ERROR
2016         "The 'NO_DEPENDS' option is no longer allowed.  "
2017         "It has been superseded by the per-step 'INDEPENDENT' option.  "
2018         "See policy CMP0114."
2019       )
2020     endif()
2021   elseif(cmp0114 STREQUAL "")
2022     cmake_policy(GET_WARNING CMP0114 _cmp0114_warning)
2023     string(APPEND _cmp0114_warning "\n"
2024       "ExternalProject target '${name}' would depend on the targets for "
2025       "step(s) '${steps}' under policy CMP0114, but this is being left out "
2026       "for compatibility since the policy is not set."
2027     )
2028     if(no_deps)
2029       string(APPEND _cmp0114_warning "  "
2030         "Also, the NO_DEPENDS option is deprecated in favor of policy CMP0114."
2031       )
2032     endif()
2033     message(AUTHOR_WARNING "${_cmp0114_warning}")
2034   endif()
2035   foreach(step IN LISTS steps)
2036     _ep_step_add_target("${name}" "${step}" "${no_deps}")
2037   endforeach()
2038 endfunction()
2041 # While this function is referenced in shared_internal_commands.cmake in a few
2042 # places, all of those code paths will only be reached by calling one of the
2043 # functions defined in this file. Keep it here, since it is part of the public
2044 # interface of ExternalProject.
2045 function(ExternalProject_Add_Step name step)
2046   get_property(cmp0114 TARGET ${name} PROPERTY _EP_CMP0114)
2047   _ep_get_complete_stampfile(${name} complete_stamp_file)
2048   _ep_get_step_stampfile(${name} ${step} stamp_file)
2050   set(keywords
2051     COMMAND
2052     COMMENT
2053     DEPENDEES
2054     DEPENDERS
2055     DEPENDS
2056     INDEPENDENT
2057     BYPRODUCTS
2058     ALWAYS
2059     JOB_SERVER_AWARE
2060     EXCLUDE_FROM_MAIN
2061     WORKING_DIRECTORY
2062     LOG
2063     USES_TERMINAL
2064   )
2065   _ep_parse_arguments(
2066     ExternalProject_Add_Step
2067     "${keywords}"
2068     ${name}
2069     _EP_${step}_
2070     "${ARGN}"
2071   )
2073   get_property(independent
2074     TARGET ${name}
2075     PROPERTY _EP_${step}_INDEPENDENT
2076   )
2077   if(independent STREQUAL "")
2078     set(independent FALSE)
2079     set_property(TARGET ${name} PROPERTY
2080       _EP_${step}_INDEPENDENT "${independent}"
2081     )
2082   endif()
2084   get_property(exclude_from_main
2085     TARGET ${name}
2086     PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN
2087   )
2088   if(NOT exclude_from_main)
2089     add_custom_command(APPEND
2090       OUTPUT ${complete_stamp_file}
2091       DEPENDS ${stamp_file}
2092     )
2093   endif()
2095   # Steps depending on this step.
2096   get_property(dependers TARGET ${name} PROPERTY _EP_${step}_DEPENDERS)
2097   set_property(TARGET ${name} APPEND PROPERTY
2098     _EP_${step}_INTERNAL_DEPENDERS ${dependers}
2099   )
2100   foreach(depender IN LISTS dependers)
2101     set_property(TARGET ${name} APPEND PROPERTY
2102       _EP_${depender}_INTERNAL_DEPENDEES ${step}
2103     )
2104     _ep_get_step_stampfile(${name} ${depender} depender_stamp_file)
2105     add_custom_command(APPEND
2106       OUTPUT ${depender_stamp_file}
2107       DEPENDS ${stamp_file}
2108     )
2109     if(cmp0114 STREQUAL "NEW" AND NOT independent)
2110       get_property(dep_independent
2111         TARGET ${name}
2112         PROPERTY _EP_${depender}_INDEPENDENT
2113       )
2114       if(dep_independent)
2115         message(FATAL_ERROR
2116           "ExternalProject '${name}' step '${depender}' is marked INDEPENDENT "
2117           "but depends on step '${step}' that is not marked INDEPENDENT."
2118         )
2119       endif()
2120     endif()
2121   endforeach()
2123   # Dependencies on files.
2124   get_property(depends TARGET ${name} PROPERTY _EP_${step}_DEPENDS)
2126   # Byproducts of the step.
2127   get_property(byproducts TARGET ${name} PROPERTY _EP_${step}_BYPRODUCTS)
2129   # Dependencies on steps.
2130   get_property(dependees TARGET ${name} PROPERTY _EP_${step}_DEPENDEES)
2131   set_property(TARGET ${name} APPEND PROPERTY
2132     _EP_${step}_INTERNAL_DEPENDEES ${dependees}
2133   )
2134   foreach(dependee IN LISTS dependees)
2135     set_property(TARGET ${name} APPEND PROPERTY
2136       _EP_${dependee}_INTERNAL_DEPENDERS ${step}
2137     )
2138     _ep_get_step_stampfile(${name} ${dependee} dependee_stamp_file)
2139     list(APPEND depends ${dependee_stamp_file})
2140     if(cmp0114 STREQUAL "NEW" AND independent)
2141       get_property(dep_independent
2142         TARGET ${name}
2143         PROPERTY _EP_${dependee}_INDEPENDENT
2144       )
2145       if(NOT dep_independent)
2146         message(FATAL_ERROR
2147           "ExternalProject '${name}' step '${step}' is marked INDEPENDENT "
2148           "but depends on step '${dependee}' that is not marked INDEPENDENT."
2149         )
2150       endif()
2151     endif()
2152   endforeach()
2154   # The command to run.
2155   get_property(command TARGET ${name} PROPERTY _EP_${step}_COMMAND)
2156   if(command)
2157     set(comment "Performing ${step} step for '${name}'")
2158   else()
2159     set(comment "No ${step} step for '${name}'")
2160   endif()
2161   get_property(work_dir
2162     TARGET ${name}
2163     PROPERTY _EP_${step}_WORKING_DIRECTORY
2164   )
2166   # Replace list separators.
2167   get_property(sep
2168     TARGET ${name}
2169     PROPERTY _EP_LIST_SEPARATOR
2170   )
2171   if(sep AND command)
2172     string(REPLACE "${sep}" "\\;" command "${command}")
2173   endif()
2175   # Replace location tags.
2176   _ep_replace_location_tags(
2177     ${name}
2178     comment
2179     command
2180     work_dir
2181     byproducts
2182   )
2184   if(NOT "x${work_dir}" STREQUAL "x")
2185     set(maybe_WORKING_DIRECTORY "WORKING_DIRECTORY [==[${work_dir}]==]")
2186   else()
2187     set(maybe_WORKING_DIRECTORY "")
2188   endif()
2190   # Custom comment?
2191   get_property(comment_set
2192     TARGET ${name}
2193     PROPERTY _EP_${step}_COMMENT
2194     SET
2195   )
2196   if(comment_set)
2197     get_property(comment
2198       TARGET ${name}
2199       PROPERTY _EP_${step}_COMMENT
2200     )
2201   endif()
2203   # Uses terminal?
2204   get_property(uses_terminal
2205     TARGET ${name}
2206     PROPERTY _EP_${step}_USES_TERMINAL
2207   )
2208   if(uses_terminal)
2209     set(maybe_USES_TERMINAL USES_TERMINAL)
2210   else()
2211     set(maybe_USES_TERMINAL "")
2212   endif()
2214   # Run every time?
2215   get_property(always
2216     TARGET ${name}
2217     PROPERTY _EP_${step}_ALWAYS
2218   )
2219   if(always)
2220     set(maybe_COMMAND_touch "")
2221     # Mark stamp files for all configs as SYMBOLIC since we do not create them.
2222     # Remove any existing stamp in case the option changed in an existing tree.
2223     get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
2224     if(_isMultiConfig)
2225       _ep_get_configuration_subdir_genex(cfgdir)
2226       foreach(cfg IN LISTS CMAKE_CONFIGURATION_TYPES)
2227         string(REPLACE "${cfgdir}" "/${cfg}"
2228           stamp_file_config "${stamp_file}"
2229         )
2230         set_property(SOURCE ${stamp_file_config} PROPERTY SYMBOLIC 1)
2231         file(REMOVE ${stamp_file_config})
2232       endforeach()
2233       if(CMAKE_GENERATOR STREQUAL "Xcode")
2234         # See Xcode case in _ep_get_configuration_subdir_genex.
2235         set_property(SOURCE ${stamp_file} PROPERTY SYMBOLIC 1)
2236       endif()
2237     else()
2238       set_property(SOURCE ${stamp_file} PROPERTY SYMBOLIC 1)
2239       file(REMOVE ${stamp_file})
2240     endif()
2241   else()
2242     set(maybe_COMMAND_touch "COMMAND \${CMAKE_COMMAND} -E touch \${stamp_file}")
2243   endif()
2245   get_property(job_server_aware
2246     TARGET ${name}
2247     PROPERTY _EP_${step}_JOB_SERVER_AWARE
2248   )
2249   if(job_server_aware)
2250     set(maybe_JOB_SERVER_AWARE "JOB_SERVER_AWARE 1")
2251   else()
2252     set(maybe_JOB_SERVER_AWARE "")
2253   endif()
2255   # Wrap with log script?
2256   get_property(log TARGET ${name} PROPERTY _EP_${step}_LOG)
2257   if(command AND log)
2258     _ep_write_log_script(${name} ${step} command)
2259   endif()
2261   if("${command}" STREQUAL "")
2262     # Some generators (i.e. Xcode) will not generate a file level target
2263     # if no command is set, and therefore the dependencies on this
2264     # target will be broken.
2265     # The empty command is replaced by an echo command here in order to
2266     # avoid this issue.
2267     set(command ${CMAKE_COMMAND} -E echo_append)
2268   endif()
2270   set(__cmdQuoted)
2271   foreach(__item IN LISTS command)
2272     string(APPEND __cmdQuoted " [==[${__item}]==]")
2273   endforeach()
2274   cmake_language(EVAL CODE "
2275     add_custom_command(
2276       OUTPUT \${stamp_file}
2277       BYPRODUCTS \${byproducts}
2278       COMMENT [===[${comment}]===]
2279       COMMAND ${__cmdQuoted}
2280       DEPENDS \${depends}
2281       VERBATIM
2282       ${maybe_COMMAND_touch}
2283       ${maybe_JOB_SERVER_AWARE}
2284       ${maybe_WORKING_DIRECTORY}
2285       ${maybe_USES_TERMINAL}
2286     )"
2287   )
2288   set_property(TARGET ${name} APPEND PROPERTY _EP_STEPS ${step})
2290   # Add custom "step target"?
2291   get_property(step_targets
2292     TARGET ${name}
2293     PROPERTY _EP_STEP_TARGETS
2294   )
2295   if(NOT step_targets)
2296     get_property(step_targets
2297       DIRECTORY
2298       PROPERTY EP_STEP_TARGETS
2299     )
2300   endif()
2301   foreach(st IN LISTS step_targets)
2302     if("${st}" STREQUAL "${step}")
2303       _ep_step_add_target("${name}" "${step}" "FALSE")
2304       break()
2305     endif()
2306   endforeach()
2308   get_property(independent_step_targets
2309     TARGET ${name} PROPERTY
2310     _EP_INDEPENDENT_STEP_TARGETS
2311   )
2312   if(NOT independent_step_targets)
2313     get_property(independent_step_targets
2314       DIRECTORY
2315       PROPERTY EP_INDEPENDENT_STEP_TARGETS
2316     )
2317   endif()
2318   if(cmp0114 STREQUAL "NEW")
2319     if(independent_step_targets)
2320       message(FATAL_ERROR
2321         "ExternalProject '${name}' option 'INDEPENDENT_STEP_TARGETS' is set to"
2322         "\n  ${independent_step_targets}\n"
2323         "but the option is no longer allowed.  "
2324         "It has been superseded by the per-step 'INDEPENDENT' option.  "
2325         "See policy CMP0114."
2326       )
2327     endif()
2328   else()
2329     if(independent_step_targets AND cmp0114 STREQUAL "")
2330       get_property(warned
2331         TARGET ${name}
2332         PROPERTY _EP_CMP0114_WARNED_INDEPENDENT_STEP_TARGETS
2333       )
2334       if(NOT warned)
2335         set_property(TARGET ${name} PROPERTY
2336           _EP_CMP0114_WARNED_INDEPENDENT_STEP_TARGETS 1
2337         )
2338         cmake_policy(GET_WARNING CMP0114 _cmp0114_warning)
2339         string(APPEND _cmp0114_warning
2340           "\n"
2341           "ExternalProject '${name}' option INDEPENDENT_STEP_TARGETS is set to"
2342           "\n  ${independent_step_targets}\n"
2343           "but the option is deprecated in favor of policy CMP0114."
2344         )
2345         message(AUTHOR_WARNING "${_cmp0114_warning}")
2346       endif()
2347     endif()
2348     foreach(st IN LISTS independent_step_targets)
2349       if("${st}" STREQUAL "${step}")
2350         _ep_step_add_target("${name}" "${step}" "TRUE")
2351         break()
2352       endif()
2353     endforeach()
2354   endif()
2355 endfunction()
2358 function(ExternalProject_Add_StepDependencies name step)
2359   set(dependencies ${ARGN})
2361   # Sanity checks on "name" and "step".
2362   if(NOT TARGET ${name})
2363     message(FATAL_ERROR
2364       "Cannot find target \"${name}\". Perhaps it has not yet been created "
2365       "using ExternalProject_Add."
2366     )
2367   endif()
2369   get_property(type TARGET ${name} PROPERTY TYPE)
2370   if(NOT type STREQUAL "UTILITY")
2371     message(FATAL_ERROR
2372       "Target \"${name}\" was not generated by ExternalProject_Add."
2373     )
2374   endif()
2376   get_property(is_ep TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT)
2377   if(NOT is_ep)
2378     message(FATAL_ERROR
2379       "Target \"${name}\" was not generated by ExternalProject_Add."
2380     )
2381   endif()
2383   get_property(steps TARGET ${name} PROPERTY _EP_STEPS)
2384   list(FIND steps ${step} is_step)
2385   if(is_step LESS 0)
2386     message(FATAL_ERROR
2387       "External project \"${name}\" does not have a step \"${step}\"."
2388     )
2389   endif()
2391   if(TARGET ${name}-${step})
2392     get_property(type TARGET ${name}-${step} PROPERTY TYPE)
2393     if(NOT type STREQUAL "UTILITY")
2394       message(FATAL_ERROR
2395         "Target \"${name}-${step}\" was not generated by "
2396         "ExternalProject_Add_StepTargets."
2397       )
2398     endif()
2399     get_property(is_ep_step
2400       TARGET ${name}-${step}
2401       PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP
2402     )
2403     if(NOT is_ep_step)
2404       message(FATAL_ERROR
2405         "Target \"${name}-${step}\" was not generated by "
2406         "ExternalProject_Add_StepTargets."
2407       )
2408     endif()
2409   endif()
2411   # Always add file-level dependency, but add target-level dependency
2412   # only if the target exists for that step.
2413   _ep_get_step_stampfile(${name} ${step} stamp_file)
2414   foreach(dep IN LISTS dependencies)
2415     add_custom_command(APPEND
2416       OUTPUT ${stamp_file}
2417       DEPENDS ${dep}
2418     )
2419   endforeach()
2420   if(TARGET ${name}-${step})
2421     add_dependencies(${name}-${step} ${dependencies})
2422   endif()
2424 endfunction()
2427 function(_ep_add_mkdir_command name)
2428   ExternalProject_Get_Property(${name} tmp_dir)
2429   set(script_filename "${tmp_dir}/${name}-mkdirs.cmake")
2430   _ep_get_configuration_subdir_genex(cfgdir)
2432   ExternalProject_Add_Step(${name} mkdir
2433     INDEPENDENT TRUE
2434     COMMENT "Creating directories for '${name}'"
2435     COMMAND ${CMAKE_COMMAND} -Dcfgdir=${cfgdir} -P ${script_filename}
2436   )
2437 endfunction()
2440 function(_ep_get_file_deps var name)
2441   set(file_deps)
2443   get_property(deps
2444     TARGET ${name}
2445     PROPERTY _EP_DEPENDS
2446   )
2447   foreach(dep IN LISTS deps)
2448     get_property(dep_type
2449       TARGET ${dep}
2450       PROPERTY TYPE
2451     )
2452     if(dep_type STREQUAL "UTILITY")
2453       get_property(is_ep
2454         TARGET ${dep}
2455         PROPERTY _EP_IS_EXTERNAL_PROJECT
2456       )
2457       if(is_ep)
2458         _ep_get_step_stampfile(${dep} "done" done_stamp_file)
2459         list(APPEND file_deps ${done_stamp_file})
2460       endif()
2461     endif()
2462   endforeach()
2464   set("${var}" "${file_deps}" PARENT_SCOPE)
2465 endfunction()
2468 function(_ep_extract_configure_command var name)
2469   get_property(cmd_set
2470     TARGET ${name}
2471     PROPERTY _EP_CONFIGURE_COMMAND
2472     SET
2473   )
2474   if(cmd_set)
2475     get_property(cmd
2476       TARGET ${name}
2477       PROPERTY _EP_CONFIGURE_COMMAND
2478     )
2479   else()
2480     get_target_property(cmake_command ${name} _EP_CMAKE_COMMAND)
2481     if(cmake_command)
2482       set(cmd "${cmake_command}")
2483     else()
2484       set(cmd "${CMAKE_COMMAND}")
2485     endif()
2487     get_property(cmake_args
2488       TARGET ${name}
2489       PROPERTY _EP_CMAKE_ARGS
2490     )
2491     list(APPEND cmd ${cmake_args})
2493     # If there are any CMAKE_CACHE_ARGS or CMAKE_CACHE_DEFAULT_ARGS,
2494     # write an initial cache and use it
2495     get_property(cmake_cache_args
2496       TARGET ${name}
2497       PROPERTY _EP_CMAKE_CACHE_ARGS
2498     )
2499     get_property(cmake_cache_default_args
2500       TARGET ${name}
2501       PROPERTY _EP_CMAKE_CACHE_DEFAULT_ARGS
2502     )
2504     set(has_cmake_cache_args 0)
2505     if(NOT "${cmake_cache_args}" STREQUAL "")
2506       set(has_cmake_cache_args 1)
2507     endif()
2509     set(has_cmake_cache_default_args 0)
2510     if(NOT "${cmake_cache_default_args}" STREQUAL "")
2511       set(has_cmake_cache_default_args 1)
2512     endif()
2514     get_target_property(cmake_generator ${name}
2515       _EP_CMAKE_GENERATOR
2516     )
2517     get_target_property(cmake_generator_instance ${name}
2518       _EP_CMAKE_GENERATOR_INSTANCE
2519     )
2520     get_target_property(cmake_generator_platform ${name}
2521       _EP_CMAKE_GENERATOR_PLATFORM
2522     )
2523     get_target_property(cmake_generator_toolset ${name}
2524       _EP_CMAKE_GENERATOR_TOOLSET
2525     )
2526     if(cmake_generator)
2527       list(APPEND cmd "-G${cmake_generator}")
2528       if(cmake_generator_platform)
2529         list(APPEND cmd "-A${cmake_generator_platform}")
2530       endif()
2531       if(cmake_generator_toolset)
2532         list(APPEND cmd "-T${cmake_generator_toolset}")
2533       endif()
2534       if(cmake_generator_instance)
2535         list(APPEND cmd
2536           "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${cmake_generator_instance}"
2537         )
2538       endif()
2539     else()
2540       if(CMAKE_EXTRA_GENERATOR)
2541         list(APPEND cmd "-G${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}")
2542       else()
2543         list(APPEND cmd "-G${CMAKE_GENERATOR}")
2544         # GreenHills needs to know about the compiler and toolset.
2545         # Be sure to update the similar section in
2546         # FetchContent.cmake:__FetchContent_directPopulate()
2547         if("${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI")
2548           set(has_cmake_cache_default_args 1)
2549           list(APPEND cmake_cache_default_args
2550             "-DGHS_TARGET_PLATFORM:STRING=${GHS_TARGET_PLATFORM}"
2551             "-DGHS_PRIMARY_TARGET:STRING=${GHS_PRIMARY_TARGET}"
2552             "-DGHS_TOOLSET_ROOT:STRING=${GHS_TOOLSET_ROOT}"
2553             "-DGHS_OS_ROOT:STRING=${GHS_OS_ROOT}"
2554             "-DGHS_OS_DIR:STRING=${GHS_OS_DIR}"
2555             "-DGHS_BSP_NAME:STRING=${GHS_BSP_NAME}"
2556           )
2557         endif()
2558       endif()
2559       if(cmake_generator_platform)
2560         message(FATAL_ERROR
2561           "Option CMAKE_GENERATOR_PLATFORM not allowed without "
2562           "CMAKE_GENERATOR."
2563         )
2564       endif()
2565       if(CMAKE_GENERATOR_PLATFORM)
2566         list(APPEND cmd "-A${CMAKE_GENERATOR_PLATFORM}")
2567       endif()
2568       if(cmake_generator_toolset)
2569         message(FATAL_ERROR
2570           "Option CMAKE_GENERATOR_TOOLSET not allowed without CMAKE_GENERATOR."
2571         )
2572       endif()
2573       if(CMAKE_GENERATOR_TOOLSET)
2574         list(APPEND cmd "-T${CMAKE_GENERATOR_TOOLSET}")
2575       endif()
2576       if(cmake_generator_instance)
2577         message(FATAL_ERROR
2578           "Option CMAKE_GENERATOR_INSTANCE not allowed without CMAKE_GENERATOR."
2579         )
2580       endif()
2581       if(CMAKE_GENERATOR_INSTANCE)
2582         list(APPEND cmd
2583           "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}"
2584         )
2585       endif()
2586     endif()
2588     if(has_cmake_cache_args OR has_cmake_cache_default_args)
2589       set(_ep_cache_args_script "<TMP_DIR>/${name}-cache-$<CONFIG>.cmake")
2590       if(has_cmake_cache_args)
2591         _ep_command_line_to_initial_cache(
2592           script_initial_cache_force
2593           "${cmake_cache_args}"
2594           1
2595         )
2596       endif()
2597       if(has_cmake_cache_default_args)
2598         _ep_command_line_to_initial_cache(
2599           script_initial_cache_default
2600           "${cmake_cache_default_args}"
2601           0
2602         )
2603       endif()
2604       _ep_write_initial_cache(
2605         ${name}
2606         "${_ep_cache_args_script}"
2607         "${script_initial_cache_force}${script_initial_cache_default}"
2608       )
2609       list(APPEND cmd "-C${_ep_cache_args_script}")
2610       _ep_replace_location_tags(${name} _ep_cache_args_script)
2611       set(_ep_cache_args_script
2612         "${_ep_cache_args_script}"
2613         PARENT_SCOPE
2614       )
2615     endif()
2617     list(APPEND cmd -S "<SOURCE_DIR><SOURCE_SUBDIR>" -B "<BINARY_DIR>")
2618   endif()
2620   set("${var}" "${cmd}" PARENT_SCOPE)
2621 endfunction()
2624 # TODO: Make sure external projects use the proper compiler
2625 function(_ep_add_configure_command name)
2626   ExternalProject_Get_Property(${name} binary_dir tmp_dir)
2628   set(file_deps)
2629   get_property(configure_handled_by_build
2630     TARGET ${name}
2631     PROPERTY _EP_CONFIGURE_HANDLED_BY_BUILD
2632   )
2633   if(NOT configure_handled_by_build)
2634     # Depend on other external projects (file-level)
2635     _ep_get_file_deps(file_deps ${name})
2636   endif()
2638   _ep_extract_configure_command(cmd ${name})
2640   # If anything about the configure command changes, (command itself, cmake
2641   # used, cmake args or cmake generator) then re-run the configure step.
2642   # Fixes issue https://gitlab.kitware.com/cmake/cmake/-/issues/10258
2643   #
2644   configure_file(
2645     ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/cfgcmd.txt.in
2646     ${tmp_dir}/${name}-cfgcmd.txt
2647     @ONLY
2648   )
2649   list(APPEND file_deps ${tmp_dir}/${name}-cfgcmd.txt)
2650   list(APPEND file_deps ${_ep_cache_args_script})
2652   _ep_get_update_disconnected(update_disconnected ${name})
2653   if(update_disconnected)
2654     set(dependees patch_disconnected)
2655   else()
2656     set(dependees patch)
2657   endif()
2659   get_property(log
2660     TARGET ${name}
2661     PROPERTY _EP_LOG_CONFIGURE
2662   )
2663   if(log)
2664     set(log LOG 1)
2665   else()
2666     set(log "")
2667   endif()
2669   get_property(uses_terminal
2670     TARGET ${name}
2671     PROPERTY _EP_USES_TERMINAL_CONFIGURE
2672   )
2673   if(uses_terminal)
2674     set(uses_terminal USES_TERMINAL 1)
2675   else()
2676     set(uses_terminal "")
2677   endif()
2679   set(__cmdQuoted)
2680   foreach(__item IN LISTS cmd)
2681     string(APPEND __cmdQuoted " [==[${__item}]==]")
2682   endforeach()
2683   cmake_language(EVAL CODE "
2684     ExternalProject_Add_Step(${name} configure
2685       INDEPENDENT FALSE
2686       COMMAND ${__cmdQuoted}
2687       WORKING_DIRECTORY \${binary_dir}
2688       DEPENDEES \${dependees}
2689       DEPENDS \${file_deps}
2690       ${log}
2691       ${uses_terminal}
2692     )"
2693   )
2694 endfunction()
2697 function(_ep_add_build_command name)
2698   ExternalProject_Get_Property(${name} binary_dir)
2700   set(file_deps)
2701   get_property(configure_handled_by_build
2702     TARGET ${name}
2703     PROPERTY _EP_CONFIGURE_HANDLED_BY_BUILD
2704   )
2705   if(configure_handled_by_build)
2706     # Depend on other external projects (file-level)
2707     _ep_get_file_deps(file_deps ${name})
2708   endif()
2710   get_property(cmd_set
2711     TARGET ${name}
2712     PROPERTY _EP_BUILD_COMMAND
2713     SET
2714   )
2715   if(cmd_set)
2716     get_property(cmd
2717       TARGET ${name}
2718       PROPERTY _EP_BUILD_COMMAND
2719     )
2720   else()
2721     _ep_get_build_command(${name} BUILD cmd)
2722   endif()
2724   get_property(log
2725     TARGET ${name}
2726     PROPERTY _EP_LOG_BUILD
2727   )
2728   if(log)
2729     set(log LOG 1)
2730   else()
2731     set(log "")
2732   endif()
2734   get_property(uses_terminal
2735     TARGET ${name}
2736     PROPERTY _EP_USES_TERMINAL_BUILD
2737   )
2738   if(uses_terminal)
2739     set(uses_terminal USES_TERMINAL 1)
2740   else()
2741     set(uses_terminal "")
2742   endif()
2744   get_property(build_always
2745     TARGET ${name}
2746     PROPERTY _EP_BUILD_ALWAYS
2747   )
2748   if(build_always)
2749     set(always 1)
2750   else()
2751     set(always 0)
2752   endif()
2754   get_property(build_byproducts
2755     TARGET ${name}
2756     PROPERTY _EP_BUILD_BYPRODUCTS
2757   )
2759   get_property(build_job_server_aware
2760     TARGET ${name}
2761     PROPERTY _EP_BUILD_JOB_SERVER_AWARE
2762   )
2763   if(build_job_server_aware)
2764     set(maybe_JOB_SERVER_AWARE "JOB_SERVER_AWARE 1")
2765   else()
2766     set(maybe_JOB_SERVER_AWARE "")
2767   endif()
2770   set(__cmdQuoted)
2771   foreach(__item IN LISTS cmd)
2772     string(APPEND __cmdQuoted " [==[${__item}]==]")
2773   endforeach()
2774   cmake_language(EVAL CODE "
2775     ExternalProject_Add_Step(${name} build
2776       INDEPENDENT FALSE
2777       COMMAND ${__cmdQuoted}
2778       BYPRODUCTS \${build_byproducts}
2779       WORKING_DIRECTORY \${binary_dir}
2780       DEPENDEES configure
2781       DEPENDS \${file_deps}
2782       ALWAYS \${always}
2783       ${maybe_JOB_SERVER_AWARE}
2784       ${log}
2785       ${uses_terminal}
2786     )"
2787   )
2788 endfunction()
2791 function(_ep_add_install_command name)
2792   ExternalProject_Get_Property(${name} binary_dir)
2794   get_property(cmd_set
2795     TARGET ${name}
2796     PROPERTY _EP_INSTALL_COMMAND
2797     SET
2798   )
2799   if(cmd_set)
2800     get_property(cmd
2801       TARGET ${name}
2802       PROPERTY _EP_INSTALL_COMMAND
2803     )
2804   else()
2805     _ep_get_build_command(${name} INSTALL cmd)
2806   endif()
2808   get_property(log
2809     TARGET ${name}
2810     PROPERTY _EP_LOG_INSTALL
2811   )
2812   if(log)
2813     set(log LOG 1)
2814   else()
2815     set(log "")
2816   endif()
2818   get_property(uses_terminal
2819     TARGET ${name}
2820     PROPERTY _EP_USES_TERMINAL_INSTALL
2821   )
2822   if(uses_terminal)
2823     set(uses_terminal USES_TERMINAL 1)
2824   else()
2825     set(uses_terminal "")
2826   endif()
2828   # With BUILD_ALWAYS+BUILD_BYPRODUCTS, Ninja restats the
2829   # build step outputs and may not consider this step to
2830   # be out-of-date.  Explicitly mark it out-of-date too.
2831   get_property(build_always
2832     TARGET ${name}
2833     PROPERTY _EP_BUILD_ALWAYS
2834   )
2835   if(build_always)
2836     set(always 1)
2837   else()
2838     set(always 0)
2839   endif()
2841   get_property(install_byproducts
2842     TARGET ${name}
2843     PROPERTY _EP_INSTALL_BYPRODUCTS
2844   )
2846   get_property(install_job_server_aware
2847     TARGET ${name}
2848     PROPERTY _EP_INSTALL_JOB_SERVER_AWARE
2849   )
2850   if(install_job_server_aware)
2851     set(maybe_JOB_SERVER_AWARE "JOB_SERVER_AWARE 1")
2852   else()
2853     set(maybe_JOB_SERVER_AWARE "")
2854   endif()
2856   set(__cmdQuoted)
2857   foreach(__item IN LISTS cmd)
2858     string(APPEND __cmdQuoted " [==[${__item}]==]")
2859   endforeach()
2860   cmake_language(EVAL CODE "
2861     ExternalProject_Add_Step(${name} install
2862       INDEPENDENT FALSE
2863       COMMAND ${__cmdQuoted}
2864       BYPRODUCTS \${install_byproducts}
2865       WORKING_DIRECTORY \${binary_dir}
2866       DEPENDEES build
2867       ALWAYS \${always}
2868       ${maybe_JOB_SERVER_AWARE}
2869       ${log}
2870       ${uses_terminal}
2871     )"
2872   )
2873 endfunction()
2876 function(_ep_add_test_command name)
2877   ExternalProject_Get_Property(${name} binary_dir)
2879   get_property(before TARGET ${name} PROPERTY _EP_TEST_BEFORE_INSTALL)
2880   get_property(after TARGET ${name} PROPERTY _EP_TEST_AFTER_INSTALL)
2881   get_property(exclude TARGET ${name} PROPERTY _EP_TEST_EXCLUDE_FROM_MAIN)
2882   get_property(cmd_set TARGET ${name} PROPERTY _EP_TEST_COMMAND SET)
2884   # Only actually add the test step if one of the test related properties is
2885   # explicitly set. (i.e. the test step is omitted unless requested...)
2886   #
2887   if(cmd_set OR before OR after OR exclude)
2888     if(cmd_set)
2889       get_property(cmd
2890         TARGET ${name}
2891         PROPERTY _EP_TEST_COMMAND
2892       )
2893     else()
2894       _ep_get_build_command(${name} TEST cmd)
2895     endif()
2897     if(before)
2898       set(dependees_args DEPENDEES build)
2899     else()
2900       set(dependees_args DEPENDEES install)
2901     endif()
2903     if(exclude)
2904       set(dependers_args "")
2905       set(exclude_args EXCLUDE_FROM_MAIN 1)
2906     else()
2907       if(before)
2908         set(dependers_args DEPENDERS install)
2909       else()
2910         set(dependers_args "")
2911       endif()
2912       set(exclude_args "")
2913     endif()
2915     get_property(log
2916       TARGET ${name}
2917       PROPERTY _EP_LOG_TEST
2918     )
2919     if(log)
2920       set(log LOG 1)
2921     else()
2922       set(log "")
2923     endif()
2925     get_property(uses_terminal
2926       TARGET ${name}
2927       PROPERTY _EP_USES_TERMINAL_TEST
2928     )
2929     if(uses_terminal)
2930       set(uses_terminal USES_TERMINAL 1)
2931     else()
2932       set(uses_terminal "")
2933     endif()
2935     set(__cmdQuoted)
2936     foreach(__item IN LISTS cmd)
2937       string(APPEND __cmdQuoted " [==[${__item}]==]")
2938     endforeach()
2939     cmake_language(EVAL CODE "
2940       ExternalProject_Add_Step(${name} test
2941         INDEPENDENT FALSE
2942         COMMAND ${__cmdQuoted}
2943         WORKING_DIRECTORY \${binary_dir}
2944         ${dependees_args}
2945         ${dependers_args}
2946         ${exclude_args}
2947         ${log}
2948         ${uses_terminal}
2949       )"
2950     )
2951   endif()
2952 endfunction()
2955 function(ExternalProject_Add name)
2956   cmake_policy(GET CMP0097 _EP_CMP0097
2957     PARENT_SCOPE # undocumented, do not use outside of CMake
2958   )
2959   cmake_policy(GET CMP0114 cmp0114
2960     PARENT_SCOPE # undocumented, do not use outside of CMake
2961   )
2962   if(CMAKE_XCODE_BUILD_SYSTEM VERSION_GREATER_EQUAL 12 AND
2963      NOT cmp0114 STREQUAL "NEW")
2964     message(AUTHOR_WARNING
2965       "Policy CMP0114 is not set to NEW.  "
2966       "In order to support the Xcode \"new build system\", "
2967       "this project must be updated to set policy CMP0114 to NEW."
2968       "\n"
2969       "Since CMake is generating for the Xcode \"new build system\", "
2970       "ExternalProject_Add will use policy CMP0114's NEW behavior anyway, "
2971       "but the generated build system may not match what the project intends."
2972     )
2973     set(cmp0114 "NEW")
2974   endif()
2975   cmake_policy(GET CMP0135 _EP_CMP0135
2976     PARENT_SCOPE # undocumented, do not use outside of CMake
2977   )
2979   _ep_get_configuration_subdir_genex(cfgdir)
2981   # Add a custom target for the external project.
2982   set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)
2983   _ep_get_complete_stampfile(${name} complete_stamp_file)
2985   cmake_policy(PUSH)
2986   if(cmp0114 STREQUAL "NEW")
2987     # To implement CMP0114 NEW behavior with Makefile generators,
2988     # we need CMP0113 NEW behavior.
2989     cmake_policy(SET CMP0113 NEW)
2990   endif()
2991   # The "ALL" option to add_custom_target just tells it to not set the
2992   # EXCLUDE_FROM_ALL target property. Later, if the EXCLUDE_FROM_ALL
2993   # argument was passed, we explicitly set it for the target.
2994   add_custom_target(${name} ALL DEPENDS ${complete_stamp_file})
2995   cmake_policy(POP)
2996   set_target_properties(${name} PROPERTIES
2997     _EP_IS_EXTERNAL_PROJECT 1
2998     LABELS ${name}
2999     FOLDER "ExternalProjectTargets/${name}"
3000     _EP_CMP0114 "${cmp0114}"
3001   )
3003   _ep_get_add_keywords(keywords)
3004   _ep_parse_arguments(
3005     ExternalProject_Add
3006     "${keywords}"
3007     ${name}
3008     _EP_
3009     "${ARGN}"
3010   )
3011   _ep_set_directories(${name})
3012   _ep_get_step_stampfile(${name} "done" done_stamp_file)
3013   _ep_get_step_stampfile(${name} "install" install_stamp_file)
3015   # Set the EXCLUDE_FROM_ALL target property if required.
3016   get_property(exclude_from_all
3017     TARGET ${name}
3018     PROPERTY _EP_EXCLUDE_FROM_ALL
3019   )
3020   if(exclude_from_all)
3021     set_property(TARGET ${name} PROPERTY EXCLUDE_FROM_ALL TRUE)
3022   endif()
3024   get_property(repo TARGET ${name} PROPERTY _EP_GIT_REPOSITORY)
3025   if(NOT repo STREQUAL "")
3026     cmake_policy(GET CMP0150 cmp0150
3027       PARENT_SCOPE # undocumented, do not use outside of CMake
3028     )
3029     get_property(source_dir TARGET ${name} PROPERTY _EP_SOURCE_DIR)
3030     get_filename_component(work_dir "${source_dir}" PATH)
3031     _ep_resolve_git_remote(resolved_git_repository "${repo}" "${cmp0150}" "${work_dir}")
3032     set_property(TARGET ${name} PROPERTY _EP_GIT_REPOSITORY ${resolved_git_repository})
3033     set(_EP_GIT_REPOSITORY "${resolved_git_repository}")
3034   endif()
3036   # The 'complete' step depends on all other steps and creates a
3037   # 'done' mark.  A dependent external project's 'configure' step
3038   # depends on the 'done' mark so that it rebuilds when this project
3039   # rebuilds.  It is important that 'done' is not the output of any
3040   # custom command so that CMake does not propagate build rules to
3041   # other external project targets, which may cause problems during
3042   # parallel builds.  However, the Ninja generator needs to see the entire
3043   # dependency graph, and can cope with custom commands belonging to
3044   # multiple targets, so we add the 'done' mark as an output for Ninja only.
3045   set(complete_outputs ${complete_stamp_file})
3046   if(${CMAKE_GENERATOR} MATCHES "Ninja")
3047     set(complete_outputs ${complete_outputs} ${done_stamp_file})
3048   endif()
3050   add_custom_command(
3051     OUTPUT ${complete_outputs}
3052     COMMENT "Completed '${name}'"
3053     COMMAND ${CMAKE_COMMAND} -E make_directory ${cmf_dir}${cfgdir}
3054     COMMAND ${CMAKE_COMMAND} -E touch ${complete_stamp_file}
3055     COMMAND ${CMAKE_COMMAND} -E touch ${done_stamp_file}
3056     DEPENDS ${install_stamp_file}
3057     VERBATIM
3058   )
3060   # Depend on other external projects (target-level).
3061   get_property(deps
3062     TARGET ${name}
3063     PROPERTY _EP_DEPENDS
3064   )
3065   foreach(arg IN LISTS deps)
3066     add_dependencies(${name} ${arg})
3067   endforeach()
3069   # Set up custom build steps based on the target properties.
3070   # Each step depends on the previous one.
3071   #
3072   # The target depends on the output of the final step.
3073   # (Already set up above in the DEPENDS of the add_custom_target command.)
3074   #
3075   _ep_add_mkdir_command(${name})
3076   _ep_add_download_command(${name})
3077   _ep_add_update_command(${name})
3078   _ep_add_patch_command(${name})
3079   _ep_add_configure_command(${name})
3080   _ep_add_build_command(${name})
3081   _ep_add_install_command(${name})
3083   # Test is special in that it might depend on build, or it might depend
3084   # on install.
3085   #
3086   _ep_add_test_command(${name})
3087 endfunction()