1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4#[=======================================================================[.rst:
5FetchContent
6------------------
7
8.. versionadded:: 3.11
9
10.. only:: html
11
12  .. contents::
13
14Overview
15^^^^^^^^
16
17This module enables populating content at configure time via any method
18supported by the :module:`ExternalProject` module.  Whereas
19:command:`ExternalProject_Add` downloads at build time, the
20``FetchContent`` module makes content available immediately, allowing the
21configure step to use the content in commands like :command:`add_subdirectory`,
22:command:`include` or :command:`file` operations.
23
24Content population details should be defined separately from the command that
25performs the actual population.  This separation ensures that all the
26dependency details are defined before anything might try to use them to
27populate content.  This is particularly important in more complex project
28hierarchies where dependencies may be shared between multiple projects.
29
30The following shows a typical example of declaring content details for some
31dependencies and then ensuring they are populated with a separate call:
32
33.. code-block:: cmake
34
35  FetchContent_Declare(
36    googletest
37    GIT_REPOSITORY https://github.com/google/googletest.git
38    GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
39  )
40  FetchContent_Declare(
41    myCompanyIcons
42    URL      https://intranet.mycompany.com/assets/iconset_1.12.tar.gz
43    URL_HASH MD5=5588a7b18261c20068beabfb4f530b87
44  )
45
46  FetchContent_MakeAvailable(googletest secret_sauce)
47
48The :command:`FetchContent_MakeAvailable` command ensures the named
49dependencies have been populated, either by an earlier call or by populating
50them itself.  When performing the population, it will also add them to the
51main build, if possible, so that the main build can use the populated
52projects' targets, etc.  See the command's documentation for how these steps
53are performed.
54
55When using a hierarchical project arrangement, projects at higher levels in
56the hierarchy are able to override the declared details of content specified
57anywhere lower in the project hierarchy.  The first details to be declared
58for a given dependency take precedence, regardless of where in the project
59hierarchy that occurs.  Similarly, the first call that tries to populate a
60dependency "wins", with subsequent populations reusing the result of the
61first instead of repeating the population again.
62See the :ref:`Examples <fetch-content-examples>` which demonstrate
63this scenario.
64
65In some cases, the main project may need to have more precise control over
66the population, or it may be required to explicitly define the population
67steps in a way that cannot be captured by the declared details alone.
68For such situations, the lower level :command:`FetchContent_GetProperties` and
69:command:`FetchContent_Populate` commands can be used.  These lack the richer
70features provided by :command:`FetchContent_MakeAvailable` though, so their
71direct use should be considered a last resort.  The typical pattern of such
72custom steps looks like this:
73
74.. code-block:: cmake
75
76  # NOTE: Where possible, prefer to use FetchContent_MakeAvailable()
77  #       instead of custom logic like this
78
79  # Check if population has already been performed
80  FetchContent_GetProperties(depname)
81  if(NOT depname_POPULATED)
82    # Fetch the content using previously declared details
83    FetchContent_Populate(depname)
84
85    # Set custom variables, policies, etc.
86    # ...
87
88    # Bring the populated content into the build
89    add_subdirectory(${depname_SOURCE_DIR} ${depname_BINARY_DIR})
90  endif()
91
92The ``FetchContent`` module also supports defining and populating
93content in a single call, with no check for whether the content has been
94populated elsewhere already.  This should not be done in projects, but may
95be appropriate for populating content in CMake's script mode.
96See :command:`FetchContent_Populate` for details.
97
98Commands
99^^^^^^^^
100
101.. command:: FetchContent_Declare
102
103  .. code-block:: cmake
104
105    FetchContent_Declare(<name> <contentOptions>...)
106
107  The ``FetchContent_Declare()`` function records the options that describe
108  how to populate the specified content.  If such details have already
109  been recorded earlier in this project (regardless of where in the project
110  hierarchy), this and all later calls for the same content ``<name>`` are
111  ignored.  This "first to record, wins" approach is what allows hierarchical
112  projects to have parent projects override content details of child projects.
113
114  The content ``<name>`` can be any string without spaces, but good practice
115  would be to use only letters, numbers and underscores.  The name will be
116  treated case-insensitively and it should be obvious for the content it
117  represents, often being the name of the child project or the value given
118  to its top level :command:`project` command (if it is a CMake project).
119  For well-known public projects, the name should generally be the official
120  name of the project.  Choosing an unusual name makes it unlikely that other
121  projects needing that same content will use the same name, leading to
122  the content being populated multiple times.
123
124  The ``<contentOptions>`` can be any of the download, update or patch options
125  that the :command:`ExternalProject_Add` command understands.  The configure,
126  build, install and test steps are explicitly disabled and therefore options
127  related to them will be ignored.  The ``SOURCE_SUBDIR`` option is an
128  exception, see :command:`FetchContent_MakeAvailable` for details on how that
129  affects behavior.
130
131  In most cases, ``<contentOptions>`` will just be a couple of options defining
132  the download method and method-specific details like a commit tag or archive
133  hash.  For example:
134
135  .. code-block:: cmake
136
137    FetchContent_Declare(
138      googletest
139      GIT_REPOSITORY https://github.com/google/googletest.git
140      GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
141    )
142
143    FetchContent_Declare(
144      myCompanyIcons
145      URL      https://intranet.mycompany.com/assets/iconset_1.12.tar.gz
146      URL_HASH MD5=5588a7b18261c20068beabfb4f530b87
147    )
148
149    FetchContent_Declare(
150      myCompanyCertificates
151      SVN_REPOSITORY svn+ssh://svn.mycompany.com/srv/svn/trunk/certs
152      SVN_REVISION   -r12345
153    )
154
155  Where contents are being fetched from a remote location and you do not
156  control that server, it is advisable to use a hash for ``GIT_TAG`` rather
157  than a branch or tag name.  A commit hash is more secure and helps to
158  confirm that the downloaded contents are what you expected.
159
160  .. versionchanged:: 3.14
161    Commands for the download, update or patch steps can access the terminal.
162    This may be needed for things like password prompts or real-time display
163    of command progress.
164
165  .. versionadded:: 3.22
166    The :variable:`CMAKE_TLS_VERIFY`, :variable:`CMAKE_TLS_CAINFO`,
167    :variable:`CMAKE_NETRC` and :variable:`CMAKE_NETRC_FILE` variables now
168    provide the defaults for their corresponding content options, just like
169    they do for :command:`ExternalProject_Add`. Previously, these variables
170    were ignored by the ``FetchContent`` module.
171
172.. command:: FetchContent_MakeAvailable
173
174  .. versionadded:: 3.14
175
176  .. code-block:: cmake
177
178    FetchContent_MakeAvailable(<name1> [<name2>...])
179
180  This command ensures that each of the named dependencies are populated and
181  potentially added to the build by the time it returns.  It iterates over
182  the list, and for each dependency, the following logic is applied:
183
184  * If the dependency has already been populated earlier in this run, set
185    the ``<lowercaseName>_POPULATED``, ``<lowercaseName>_SOURCE_DIR`` and
186    ``<lowercaseName>_BINARY_DIR`` variables in the same way as a call to
187    :command:`FetchContent_GetProperties`, then skip the remaining steps
188    below and move on to the next dependency in the list.
189
190  * Call :command:`FetchContent_Populate` to populate the dependency using
191    the details recorded by an earlier call to :command:`FetchContent_Declare`.
192    Halt with a fatal error if no such details have been recorded.
193    :variable:`FETCHCONTENT_SOURCE_DIR_<uppercaseName>` can be used to override
194    the declared details and use content provided at the specified location
195    instead.
196
197  * If the top directory of the populated content contains a ``CMakeLists.txt``
198    file, call :command:`add_subdirectory` to add it to the main build.
199    It is not an error for there to be no ``CMakeLists.txt`` file, which
200    allows the command to be used for dependencies that make downloaded
201    content available at a known location, but which do not need or support
202    being added directly to the build.
203
204    .. versionadded:: 3.18
205      The ``SOURCE_SUBDIR`` option can be given in the declared details to
206      look somewhere below the top directory instead (i.e. the same way that
207      ``SOURCE_SUBDIR`` is used by the :command:`ExternalProject_Add`
208      command).  The path provided with ``SOURCE_SUBDIR`` must be relative
209      and will be treated as relative to the top directory.  It can also
210      point to a directory that does not contain a ``CMakeLists.txt`` file
211      or even to a directory that doesn't exist.  This can be used to avoid
212      adding a project that contains a ``CMakeLists.txt`` file in its top
213      directory.
214
215  Projects should aim to declare the details of all dependencies they might
216  use before they call ``FetchContent_MakeAvailable()`` for any of them.
217  This ensures that if any of the dependencies are also sub-dependencies of
218  one or more of the others, the main project still controls the details
219  that will be used (because it will declare them first before the
220  dependencies get a chance to).  In the following code samples, assume that
221  the ``uses_other`` dependency also uses ``FetchContent`` to add the ``other``
222  dependency internally:
223
224  .. code-block:: cmake
225
226    # WRONG: Should declare all details first
227    FetchContent_Declare(uses_other ...)
228    FetchContent_MakeAvailable(uses_other)
229
230    FetchContent_Declare(other ...)    # Will be ignored, uses_other beat us to it
231    FetchContent_MakeAvailable(other)  # Would use details declared by uses_other
232
233  .. code-block:: cmake
234
235    # CORRECT: All details declared first, so they will take priority
236    FetchContent_Declare(uses_other ...)
237    FetchContent_Declare(other ...)
238    FetchContent_MakeAvailable(uses_other other)
239
240.. command:: FetchContent_Populate
241
242  .. note::
243    Where possible, prefer to use :command:`FetchContent_MakeAvailable`
244    instead of implementing population manually with this command.
245
246  .. code-block:: cmake
247
248    FetchContent_Populate(<name>)
249
250  In most cases, the only argument given to ``FetchContent_Populate()`` is the
251  ``<name>``.  When used this way, the command assumes the content details have
252  been recorded by an earlier call to :command:`FetchContent_Declare`.  The
253  details are stored in a global property, so they are unaffected by things
254  like variable or directory scope.  Therefore, it doesn't matter where in the
255  project the details were previously declared, as long as they have been
256  declared before the call to ``FetchContent_Populate()``.  Those saved details
257  are then used to construct a call to :command:`ExternalProject_Add` in a
258  private sub-build to perform the content population immediately.  The
259  implementation of ``ExternalProject_Add()`` ensures that if the content has
260  already been populated in a previous CMake run, that content will be reused
261  rather than repopulating them again.  For the common case where population
262  involves downloading content, the cost of the download is only paid once.
263
264  An internal global property records when a particular content population
265  request has been processed.  If ``FetchContent_Populate()`` is called more
266  than once for the same content name within a configure run, the second call
267  will halt with an error.  Projects can and should check whether content
268  population has already been processed with the
269  :command:`FetchContent_GetProperties` command before calling
270  ``FetchContent_Populate()``.
271
272  ``FetchContent_Populate()`` will set three variables in the scope of the
273  caller:
274
275  ``<lowercaseName>_POPULATED``
276    This will always be set to ``TRUE`` by the call.
277
278  ``<lowercaseName>_SOURCE_DIR``
279    The location where the populated content can be found upon return.
280
281  ``<lowercaseName>_BINARY_DIR``
282    A directory intended for use as a corresponding build directory.
283
284  The main use case for the ``<lowercaseName>_SOURCE_DIR`` and
285  ``<lowercaseName>_BINARY_DIR`` variables is to call
286  :command:`add_subdirectory` immediately after population:
287
288  .. code-block:: cmake
289
290    FetchContent_Populate(FooBar)
291    add_subdirectory(${foobar_SOURCE_DIR} ${foobar_BINARY_DIR})
292
293  The values of the three variables can also be retrieved from anywhere in the
294  project hierarchy using the :command:`FetchContent_GetProperties` command.
295
296  The ``FetchContent_Populate()`` command also supports a syntax allowing the
297  content details to be specified directly rather than using any saved
298  details.  This is more low-level and use of this form is generally to be
299  avoided in favor of using saved content details as outlined above.
300  Nevertheless, in certain situations it can be useful to invoke the content
301  population as an isolated operation (typically as part of implementing some
302  other higher level feature or when using CMake in script mode):
303
304  .. code-block:: cmake
305
306    FetchContent_Populate(
307      <name>
308      [QUIET]
309      [SUBBUILD_DIR <subBuildDir>]
310      [SOURCE_DIR <srcDir>]
311      [BINARY_DIR <binDir>]
312      ...
313    )
314
315  This form has a number of key differences to that where only ``<name>`` is
316  provided:
317
318  - All required population details are assumed to have been provided directly
319    in the call to ``FetchContent_Populate()``. Any saved details for
320    ``<name>`` are ignored.
321  - No check is made for whether content for ``<name>`` has already been
322    populated.
323  - No global property is set to record that the population has occurred.
324  - No global properties record the source or binary directories used for the
325    populated content.
326  - The ``FETCHCONTENT_FULLY_DISCONNECTED`` and
327    ``FETCHCONTENT_UPDATES_DISCONNECTED`` cache variables are ignored.
328
329  The ``<lowercaseName>_SOURCE_DIR`` and ``<lowercaseName>_BINARY_DIR``
330  variables are still returned to the caller, but since these locations are
331  not stored as global properties when this form is used, they are only
332  available to the calling scope and below rather than the entire project
333  hierarchy.  No ``<lowercaseName>_POPULATED`` variable is set in the caller's
334  scope with this form.
335
336  The supported options for ``FetchContent_Populate()`` are the same as those
337  for :command:`FetchContent_Declare()`.  Those few options shown just
338  above are either specific to ``FetchContent_Populate()`` or their behavior is
339  slightly modified from how :command:`ExternalProject_Add` treats them:
340
341  ``QUIET``
342    The ``QUIET`` option can be given to hide the output associated with
343    populating the specified content.  If the population fails, the output will
344    be shown regardless of whether this option was given or not so that the
345    cause of the failure can be diagnosed.  The global ``FETCHCONTENT_QUIET``
346    cache variable has no effect on ``FetchContent_Populate()`` calls where the
347    content details are provided directly.
348
349  ``SUBBUILD_DIR``
350    The ``SUBBUILD_DIR`` argument can be provided to change the location of the
351    sub-build created to perform the population.  The default value is
352    ``${CMAKE_CURRENT_BINARY_DIR}/<lowercaseName>-subbuild`` and it would be
353    unusual to need to override this default.  If a relative path is specified,
354    it will be interpreted as relative to :variable:`CMAKE_CURRENT_BINARY_DIR`.
355    This option should not be confused with the ``SOURCE_SUBDIR`` option which
356    only affects the :command:`FetchContent_MakeAvailable` command.
357
358  ``SOURCE_DIR``, ``BINARY_DIR``
359    The ``SOURCE_DIR`` and ``BINARY_DIR`` arguments are supported by
360    :command:`ExternalProject_Add`, but different default values are used by
361    ``FetchContent_Populate()``.  ``SOURCE_DIR`` defaults to
362    ``${CMAKE_CURRENT_BINARY_DIR}/<lowercaseName>-src`` and ``BINARY_DIR``
363    defaults to ``${CMAKE_CURRENT_BINARY_DIR}/<lowercaseName>-build``.
364    If a relative path is specified, it will be interpreted as relative to
365    :variable:`CMAKE_CURRENT_BINARY_DIR`.
366
367  In addition to the above explicit options, any other unrecognized options are
368  passed through unmodified to :command:`ExternalProject_Add` to perform the
369  download, patch and update steps.  The following options are explicitly
370  prohibited (they are disabled by the ``FetchContent_Populate()`` command):
371
372  - ``CONFIGURE_COMMAND``
373  - ``BUILD_COMMAND``
374  - ``INSTALL_COMMAND``
375  - ``TEST_COMMAND``
376
377  If using ``FetchContent_Populate()`` within CMake's script mode, be aware
378  that the implementation sets up a sub-build which therefore requires a CMake
379  generator and build tool to be available. If these cannot be found by
380  default, then the :variable:`CMAKE_GENERATOR` and/or
381  :variable:`CMAKE_MAKE_PROGRAM` variables will need to be set appropriately
382  on the command line invoking the script.
383
384  .. versionadded:: 3.18
385    Added support for the ``DOWNLOAD_NO_EXTRACT`` option.
386
387.. command:: FetchContent_GetProperties
388
389  When using saved content details, a call to
390  :command:`FetchContent_MakeAvailable` or :command:`FetchContent_Populate`
391  records information in global properties which can be queried at any time.
392  This information includes the source and binary directories associated with
393  the content and also whether or not the content population has been processed
394  during the current configure run.
395
396  .. code-block:: cmake
397
398    FetchContent_GetProperties(
399      <name>
400      [SOURCE_DIR <srcDirVar>]
401      [BINARY_DIR <binDirVar>]
402      [POPULATED <doneVar>]
403    )
404
405  The ``SOURCE_DIR``, ``BINARY_DIR`` and ``POPULATED`` options can be used to
406  specify which properties should be retrieved.  Each option accepts a value
407  which is the name of the variable in which to store that property.  Most of
408  the time though, only ``<name>`` is given, in which case the call will then
409  set the same variables as a call to
410  :command:`FetchContent_MakeAvailable(name) <FetchContent_MakeAvailable>` or
411  :command:`FetchContent_Populate(name) <FetchContent_Populate>`.
412
413  This command is rarely needed when using
414  :command:`FetchContent_MakeAvailable`.  It is more commonly used as part of
415  implementing the following pattern with :command:`FetchContent_Populate`,
416  which ensures that the relevant variables will always be defined regardless
417  of whether or not the population has been performed elsewhere in the project
418  already:
419
420  .. code-block:: cmake
421
422    # Check if population has already been performed
423    FetchContent_GetProperties(depname)
424    if(NOT depname_POPULATED)
425      # Fetch the content using previously declared details
426      FetchContent_Populate(depname)
427
428      # Set custom variables, policies, etc.
429      # ...
430
431      # Bring the populated content into the build
432      add_subdirectory(${depname_SOURCE_DIR} ${depname_BINARY_DIR})
433    endif()
434
435Variables
436^^^^^^^^^
437
438A number of cache variables can influence the behavior where details from a
439:command:`FetchContent_Declare` call are used to populate content.
440The variables are all intended for the developer to customize behavior and
441should not normally be set by the project.
442
443.. variable:: FETCHCONTENT_BASE_DIR
444
445  In most cases, the saved details do not specify any options relating to the
446  directories to use for the internal sub-build, final source and build areas.
447  It is generally best to leave these decisions up to the ``FetchContent``
448  module to handle on the project's behalf.  The ``FETCHCONTENT_BASE_DIR``
449  cache variable controls the point under which all content population
450  directories are collected, but in most cases, developers would not need to
451  change this.  The default location is ``${CMAKE_BINARY_DIR}/_deps``, but if
452  developers change this value, they should aim to keep the path short and
453  just below the top level of the build tree to avoid running into path
454  length problems on Windows.
455
456.. variable:: FETCHCONTENT_QUIET
457
458  The logging output during population can be quite verbose, making the
459  configure stage quite noisy.  This cache option (``ON`` by default) hides
460  all population output unless an error is encountered.  If experiencing
461  problems with hung downloads, temporarily switching this option off may
462  help diagnose which content population is causing the issue.
463
464.. variable:: FETCHCONTENT_FULLY_DISCONNECTED
465
466  When this option is enabled, no attempt is made to download or update
467  any content.  It is assumed that all content has already been populated in
468  a previous run or the source directories have been pointed at existing
469  contents the developer has provided manually (using options described
470  further below).  When the developer knows that no changes have been made to
471  any content details, turning this option ``ON`` can significantly speed up
472  the configure stage.  It is ``OFF`` by default.
473
474.. variable:: FETCHCONTENT_UPDATES_DISCONNECTED
475
476  This is a less severe download/update control compared to
477  :variable:`FETCHCONTENT_FULLY_DISCONNECTED`.  Instead of bypassing all
478  download and update logic, ``FETCHCONTENT_UPDATES_DISCONNECTED`` only
479  disables the update stage.  Therefore, if content has not been downloaded
480  previously, it will still be downloaded when this option is enabled.
481  This can speed up the configure stage, but not as much as
482  :variable:`FETCHCONTENT_FULLY_DISCONNECTED`.  It is ``OFF`` by default.
483
484In addition to the above cache variables, the following cache variables are
485also defined for each content name:
486
487.. variable:: FETCHCONTENT_SOURCE_DIR_<uppercaseName>
488
489  If this is set, no download or update steps are performed for the specified
490  content and the ``<lowercaseName>_SOURCE_DIR`` variable returned to the
491  caller is pointed at this location.  This gives developers a way to have a
492  separate checkout of the content that they can modify freely without
493  interference from the build.  The build simply uses that existing source,
494  but it still defines ``<lowercaseName>_BINARY_DIR`` to point inside its own
495  build area.  Developers are strongly encouraged to use this mechanism rather
496  than editing the sources populated in the default location, as changes to
497  sources in the default location can be lost when content population details
498  are changed by the project.
499
500.. variable:: FETCHCONTENT_UPDATES_DISCONNECTED_<uppercaseName>
501
502  This is the per-content equivalent of
503  :variable:`FETCHCONTENT_UPDATES_DISCONNECTED`.  If the global option or
504  this option is ``ON``, then updates will be disabled for the named content.
505  Disabling updates for individual content can be useful for content whose
506  details rarely change, while still leaving other frequently changing content
507  with updates enabled.
508
509.. _`fetch-content-examples`:
510
511Examples
512^^^^^^^^
513
514This first fairly straightforward example ensures that some popular testing
515frameworks are available to the main build:
516
517.. code-block:: cmake
518
519  include(FetchContent)
520  FetchContent_Declare(
521    googletest
522    GIT_REPOSITORY https://github.com/google/googletest.git
523    GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
524  )
525  FetchContent_Declare(
526    Catch2
527    GIT_REPOSITORY https://github.com/catchorg/Catch2.git
528    GIT_TAG        de6fe184a9ac1a06895cdd1c9b437f0a0bdf14ad # v2.13.4
529  )
530
531  # After the following call, the CMake targets defined by googletest and
532  # Catch2 will be available to the rest of the build
533  FetchContent_MakeAvailable(googletest Catch2)
534
535If the sub-project's ``CMakeLists.txt`` file is not at the top level of its
536source tree, the ``SOURCE_SUBDIR`` option can be used to tell ``FetchContent``
537where to find it.  The following example shows how to use that option and
538it also sets a variable which is meaningful to the subproject before pulling
539it into the main build:
540
541.. code-block:: cmake
542
543  include(FetchContent)
544  FetchContent_Declare(
545    protobuf
546    GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
547    GIT_TAG        ae50d9b9902526efd6c7a1907d09739f959c6297 # v3.15.0
548    SOURCE_SUBDIR  cmake
549  )
550  set(protobuf_BUILD_TESTS OFF)
551  FetchContent_MakeAvailable(protobuf)
552
553In more complex project hierarchies, the dependency relationships can be more
554complicated.  Consider a hierarchy where ``projA`` is the top level project and
555it depends directly on projects ``projB`` and ``projC``.  Both ``projB`` and
556``projC`` can be built standalone and they also both depend on another project
557``projD``.  ``projB`` additionally depends on ``projE``.  This example assumes
558that all five projects are available on a company git server.  The
559``CMakeLists.txt`` of each project might have sections like the following:
560
561*projA*:
562
563.. code-block:: cmake
564
565  include(FetchContent)
566  FetchContent_Declare(
567    projB
568    GIT_REPOSITORY [email protected]:git/projB.git
569    GIT_TAG        4a89dc7e24ff212a7b5167bef7ab079d
570  )
571  FetchContent_Declare(
572    projC
573    GIT_REPOSITORY [email protected]:git/projC.git
574    GIT_TAG        4ad4016bd1d8d5412d135cf8ceea1bb9
575  )
576  FetchContent_Declare(
577    projD
578    GIT_REPOSITORY [email protected]:git/projD.git
579    GIT_TAG        origin/integrationBranch
580  )
581  FetchContent_Declare(
582    projE
583    GIT_REPOSITORY [email protected]:git/projE.git
584    GIT_TAG        v2.3-rc1
585  )
586
587  # Order is important, see notes in the discussion further below
588  FetchContent_MakeAvailable(projD projB projC)
589
590*projB*:
591
592.. code-block:: cmake
593
594  include(FetchContent)
595  FetchContent_Declare(
596    projD
597    GIT_REPOSITORY [email protected]:git/projD.git
598    GIT_TAG        20b415f9034bbd2a2e8216e9a5c9e632
599  )
600  FetchContent_Declare(
601    projE
602    GIT_REPOSITORY [email protected]:git/projE.git
603    GIT_TAG        68e20f674a48be38d60e129f600faf7d
604  )
605
606  FetchContent_MakeAvailable(projD projE)
607
608*projC*:
609
610.. code-block:: cmake
611
612  include(FetchContent)
613  FetchContent_Declare(
614    projD
615    GIT_REPOSITORY [email protected]:git/projD.git
616    GIT_TAG        7d9a17ad2c962aa13e2fbb8043fb6b8a
617  )
618
619  # This particular version of projD requires workarounds
620  FetchContent_GetProperties(projD)
621  if(NOT projd_POPULATED)
622    FetchContent_Populate(projD)
623
624    # Copy an additional/replacement file into the populated source
625    file(COPY someFile.c DESTINATION ${projd_SOURCE_DIR}/src)
626
627    add_subdirectory(${projd_SOURCE_DIR} ${projd_BINARY_DIR})
628  endif()
629
630A few key points should be noted in the above:
631
632- ``projB`` and ``projC`` define different content details for ``projD``,
633  but ``projA`` also defines a set of content details for ``projD``.
634  Because ``projA`` will define them first, the details from ``projB`` and
635  ``projC`` will not be used.  The override details defined by ``projA``
636  are not required to match either of those from ``projB`` or ``projC``, but
637  it is up to the higher level project to ensure that the details it does
638  define still make sense for the child projects.
639- In the ``projA`` call to :command:`FetchContent_MakeAvailable`, ``projD``
640  is listed ahead of ``projB`` and ``projC`` to ensure that ``projA`` is in
641  control of how ``projD`` is populated.
642- While ``projA`` defines content details for ``projE``, it does not need
643  to explicitly call ``FetchContent_MakeAvailable(projE)`` or
644  ``FetchContent_Populate(projD)`` itself.  Instead, it leaves that to the
645  child ``projB``.  For higher level projects, it is often enough to just
646  define the override content details and leave the actual population to the
647  child projects.  This saves repeating the same thing at each level of the
648  project hierarchy unnecessarily.
649
650
651Projects don't always need to add the populated content to the build.
652Sometimes the project just wants to make the downloaded content available at
653a predictable location.  The next example ensures that a set of standard
654company toolchain files (and potentially even the toolchain binaries
655themselves) is available early enough to be used for that same build.
656
657.. code-block:: cmake
658
659  cmake_minimum_required(VERSION 3.14)
660
661  include(FetchContent)
662  FetchContent_Declare(
663    mycom_toolchains
664    URL  https://intranet.mycompany.com//toolchains_1.3.2.tar.gz
665  )
666  FetchContent_MakeAvailable(mycom_toolchains)
667
668  project(CrossCompileExample)
669
670The project could be configured to use one of the downloaded toolchains like
671so:
672
673.. code-block:: shell
674
675  cmake -DCMAKE_TOOLCHAIN_FILE=_deps/mycom_toolchains-src/toolchain_arm.cmake /path/to/src
676
677When CMake processes the ``CMakeLists.txt`` file, it will download and unpack
678the tarball into ``_deps/mycompany_toolchains-src`` relative to the build
679directory.  The :variable:`CMAKE_TOOLCHAIN_FILE` variable is not used until
680the :command:`project` command is reached, at which point CMake looks for the
681named toolchain file relative to the build directory.  Because the tarball has
682already been downloaded and unpacked by then, the toolchain file will be in
683place, even the very first time that ``cmake`` is run in the build directory.
684
685Lastly, the following example demonstrates how one might download and unpack a
686firmware tarball using CMake's :manual:`script mode <cmake(1)>`.  The call to
687:command:`FetchContent_Populate` specifies all the content details and the
688unpacked firmware will be placed in a ``firmware`` directory below the
689current working directory.
690
691*getFirmware.cmake*:
692
693.. code-block:: cmake
694
695  # NOTE: Intended to be run in script mode with cmake -P
696  include(FetchContent)
697  FetchContent_Populate(
698    firmware
699    URL        https://mycompany.com/assets/firmware-1.23-arm.tar.gz
700    URL_HASH   MD5=68247684da89b608d466253762b0ff11
701    SOURCE_DIR firmware
702  )
703
704#]=======================================================================]
705
706#=======================================================================
707# Recording and retrieving content details for later population
708#=======================================================================
709
710# Internal use, projects must not call this directly. It is
711# intended for use by FetchContent_Declare() only.
712#
713# Sets a content-specific global property (not meant for use
714# outside of functions defined here in this file) which can later
715# be retrieved using __FetchContent_getSavedDetails() with just the
716# same content name. If there is already a value stored in the
717# property, it is left unchanged and this call has no effect.
718# This allows parent projects to define the content details,
719# overriding anything a child project may try to set (properties
720# are not cached between runs, so the first thing to set it in a
721# build will be in control).
722function(__FetchContent_declareDetails contentName)
723
724  string(TOLOWER ${contentName} contentNameLower)
725  set(propertyName "_FetchContent_${contentNameLower}_savedDetails")
726  get_property(alreadyDefined GLOBAL PROPERTY ${propertyName} DEFINED)
727  if(NOT alreadyDefined)
728    define_property(GLOBAL PROPERTY ${propertyName}
729      BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
730      FULL_DOCS  "Details used by FetchContent_Populate() for ${contentName}"
731    )
732    set(__cmdArgs)
733    foreach(__item IN LISTS ARGN)
734      string(APPEND __cmdArgs " [==[${__item}]==]")
735    endforeach()
736    cmake_language(EVAL CODE
737      "set_property(GLOBAL PROPERTY ${propertyName} ${__cmdArgs})")
738  endif()
739
740endfunction()
741
742
743# Internal use, projects must not call this directly. It is
744# intended for use by the FetchContent_Declare() function.
745#
746# Retrieves details saved for the specified content in an
747# earlier call to __FetchContent_declareDetails().
748function(__FetchContent_getSavedDetails contentName outVar)
749
750  string(TOLOWER ${contentName} contentNameLower)
751  set(propertyName "_FetchContent_${contentNameLower}_savedDetails")
752  get_property(alreadyDefined GLOBAL PROPERTY ${propertyName} DEFINED)
753  if(NOT alreadyDefined)
754    message(FATAL_ERROR "No content details recorded for ${contentName}")
755  endif()
756  get_property(propertyValue GLOBAL PROPERTY ${propertyName})
757  set(${outVar} "${propertyValue}" PARENT_SCOPE)
758
759endfunction()
760
761
762# Saves population details of the content, sets defaults for the
763# SOURCE_DIR and BUILD_DIR.
764function(FetchContent_Declare contentName)
765
766  set(options "")
767  set(oneValueArgs SVN_REPOSITORY)
768  set(multiValueArgs "")
769
770  cmake_parse_arguments(PARSE_ARGV 1 ARG
771    "${options}" "${oneValueArgs}" "${multiValueArgs}")
772
773  unset(srcDirSuffix)
774  unset(svnRepoArgs)
775  if(ARG_SVN_REPOSITORY)
776    # Add a hash of the svn repository URL to the source dir. This works
777    # around the problem where if the URL changes, the download would
778    # fail because it tries to checkout/update rather than switch the
779    # old URL to the new one. We limit the hash to the first 7 characters
780    # so that the source path doesn't get overly long (which can be a
781    # problem on windows due to path length limits).
782    string(SHA1 urlSHA ${ARG_SVN_REPOSITORY})
783    string(SUBSTRING ${urlSHA} 0 7 urlSHA)
784    set(srcDirSuffix "-${urlSHA}")
785    set(svnRepoArgs  SVN_REPOSITORY ${ARG_SVN_REPOSITORY})
786  endif()
787
788  string(TOLOWER ${contentName} contentNameLower)
789
790  set(__argsQuoted)
791  foreach(__item IN LISTS ARG_UNPARSED_ARGUMENTS)
792    string(APPEND __argsQuoted " [==[${__item}]==]")
793  endforeach()
794  cmake_language(EVAL CODE "
795    __FetchContent_declareDetails(
796      ${contentNameLower}
797      SOURCE_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src${srcDirSuffix}\"
798      BINARY_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build\"
799      \${svnRepoArgs}
800      # List these last so they can override things we set above
801      ${__argsQuoted}
802    )"
803  )
804
805endfunction()
806
807
808#=======================================================================
809# Set/get whether the specified content has been populated yet.
810# The setter also records the source and binary dirs used.
811#=======================================================================
812
813# Internal use, projects must not call this directly. It is
814# intended for use by the FetchContent_Populate() function to
815# record when FetchContent_Populate() is called for a particular
816# content name.
817function(__FetchContent_setPopulated contentName sourceDir binaryDir)
818
819  string(TOLOWER ${contentName} contentNameLower)
820  set(prefix "_FetchContent_${contentNameLower}")
821
822  set(propertyName "${prefix}_sourceDir")
823  define_property(GLOBAL PROPERTY ${propertyName}
824    BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
825    FULL_DOCS  "Details used by FetchContent_Populate() for ${contentName}"
826  )
827  set_property(GLOBAL PROPERTY ${propertyName} ${sourceDir})
828
829  set(propertyName "${prefix}_binaryDir")
830  define_property(GLOBAL PROPERTY ${propertyName}
831    BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
832    FULL_DOCS  "Details used by FetchContent_Populate() for ${contentName}"
833  )
834  set_property(GLOBAL PROPERTY ${propertyName} ${binaryDir})
835
836  set(propertyName "${prefix}_populated")
837  define_property(GLOBAL PROPERTY ${propertyName}
838    BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
839    FULL_DOCS  "Details used by FetchContent_Populate() for ${contentName}"
840  )
841  set_property(GLOBAL PROPERTY ${propertyName} True)
842
843endfunction()
844
845
846# Set variables in the calling scope for any of the retrievable
847# properties. If no specific properties are requested, variables
848# will be set for all retrievable properties.
849#
850# This function is intended to also be used by projects as the canonical
851# way to detect whether they should call FetchContent_Populate()
852# and pull the populated source into the build with add_subdirectory(),
853# if they are using the populated content in that way.
854function(FetchContent_GetProperties contentName)
855
856  string(TOLOWER ${contentName} contentNameLower)
857
858  set(options "")
859  set(oneValueArgs SOURCE_DIR BINARY_DIR POPULATED)
860  set(multiValueArgs "")
861
862  cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
863
864  if(NOT ARG_SOURCE_DIR AND
865     NOT ARG_BINARY_DIR AND
866     NOT ARG_POPULATED)
867    # No specific properties requested, provide them all
868    set(ARG_SOURCE_DIR ${contentNameLower}_SOURCE_DIR)
869    set(ARG_BINARY_DIR ${contentNameLower}_BINARY_DIR)
870    set(ARG_POPULATED  ${contentNameLower}_POPULATED)
871  endif()
872
873  set(prefix "_FetchContent_${contentNameLower}")
874
875  if(ARG_SOURCE_DIR)
876    set(propertyName "${prefix}_sourceDir")
877    get_property(value GLOBAL PROPERTY ${propertyName})
878    if(value)
879      set(${ARG_SOURCE_DIR} ${value} PARENT_SCOPE)
880    endif()
881  endif()
882
883  if(ARG_BINARY_DIR)
884    set(propertyName "${prefix}_binaryDir")
885    get_property(value GLOBAL PROPERTY ${propertyName})
886    if(value)
887      set(${ARG_BINARY_DIR} ${value} PARENT_SCOPE)
888    endif()
889  endif()
890
891  if(ARG_POPULATED)
892    set(propertyName "${prefix}_populated")
893    get_property(value GLOBAL PROPERTY ${propertyName} DEFINED)
894    set(${ARG_POPULATED} ${value} PARENT_SCOPE)
895  endif()
896
897endfunction()
898
899
900#=======================================================================
901# Performing the population
902#=======================================================================
903
904# The value of contentName will always have been lowercased by the caller.
905# All other arguments are assumed to be options that are understood by
906# ExternalProject_Add(), except for QUIET and SUBBUILD_DIR.
907function(__FetchContent_directPopulate contentName)
908
909  set(options
910      QUIET
911  )
912  set(oneValueArgs
913      SUBBUILD_DIR
914      SOURCE_DIR
915      BINARY_DIR
916      # We need special processing if DOWNLOAD_NO_EXTRACT is true
917      DOWNLOAD_NO_EXTRACT
918      # Prevent the following from being passed through
919      CONFIGURE_COMMAND
920      BUILD_COMMAND
921      INSTALL_COMMAND
922      TEST_COMMAND
923      # We force both of these to be ON since we are always executing serially
924      # and we want all steps to have access to the terminal in case they
925      # need input from the command line (e.g. ask for a private key password)
926      # or they want to provide timely progress. We silently absorb and
927      # discard these if they are set by the caller.
928      USES_TERMINAL_DOWNLOAD
929      USES_TERMINAL_UPDATE
930  )
931  set(multiValueArgs "")
932
933  cmake_parse_arguments(PARSE_ARGV 1 ARG
934    "${options}" "${oneValueArgs}" "${multiValueArgs}")
935
936  if(NOT ARG_SUBBUILD_DIR)
937    message(FATAL_ERROR "Internal error: SUBBUILD_DIR not set")
938  elseif(NOT IS_ABSOLUTE "${ARG_SUBBUILD_DIR}")
939    set(ARG_SUBBUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/${ARG_SUBBUILD_DIR}")
940  endif()
941
942  if(NOT ARG_SOURCE_DIR)
943    message(FATAL_ERROR "Internal error: SOURCE_DIR not set")
944  elseif(NOT IS_ABSOLUTE "${ARG_SOURCE_DIR}")
945    set(ARG_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/${ARG_SOURCE_DIR}")
946  endif()
947
948  if(NOT ARG_BINARY_DIR)
949    message(FATAL_ERROR "Internal error: BINARY_DIR not set")
950  elseif(NOT IS_ABSOLUTE "${ARG_BINARY_DIR}")
951    set(ARG_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/${ARG_BINARY_DIR}")
952  endif()
953
954  # Ensure the caller can know where to find the source and build directories
955  # with some convenient variables. Doing this here ensures the caller sees
956  # the correct result in the case where the default values are overridden by
957  # the content details set by the project.
958  set(${contentName}_SOURCE_DIR "${ARG_SOURCE_DIR}" PARENT_SCOPE)
959  set(${contentName}_BINARY_DIR "${ARG_BINARY_DIR}" PARENT_SCOPE)
960
961  # The unparsed arguments may contain spaces, so build up ARG_EXTRA
962  # in such a way that it correctly substitutes into the generated
963  # CMakeLists.txt file with each argument quoted.
964  unset(ARG_EXTRA)
965  foreach(arg IN LISTS ARG_UNPARSED_ARGUMENTS)
966    set(ARG_EXTRA "${ARG_EXTRA} \"${arg}\"")
967  endforeach()
968
969  if(ARG_DOWNLOAD_NO_EXTRACT)
970    set(ARG_EXTRA "${ARG_EXTRA} DOWNLOAD_NO_EXTRACT YES")
971    set(__FETCHCONTENT_COPY_FILE
972"
973ExternalProject_Get_Property(${contentName}-populate DOWNLOADED_FILE)
974get_filename_component(dlFileName \"\${DOWNLOADED_FILE}\" NAME)
975
976ExternalProject_Add_Step(${contentName}-populate copyfile
977  COMMAND    \"${CMAKE_COMMAND}\" -E copy_if_different
978             \"<DOWNLOADED_FILE>\" \"${ARG_SOURCE_DIR}\"
979  DEPENDEES  patch
980  DEPENDERS  configure
981  BYPRODUCTS \"${ARG_SOURCE_DIR}/\${dlFileName}\"
982  COMMENT    \"Copying file to SOURCE_DIR\"
983)
984")
985  else()
986    unset(__FETCHCONTENT_COPY_FILE)
987  endif()
988
989  # Hide output if requested, but save it to a variable in case there's an
990  # error so we can show the output upon failure. When not quiet, don't
991  # capture the output to a variable because the user may want to see the
992  # output as it happens (e.g. progress during long downloads). Combine both
993  # stdout and stderr in the one capture variable so the output stays in order.
994  if (ARG_QUIET)
995    set(outputOptions
996        OUTPUT_VARIABLE capturedOutput
997        ERROR_VARIABLE  capturedOutput
998    )
999  else()
1000    set(capturedOutput)
1001    set(outputOptions)
1002    message(STATUS "Populating ${contentName}")
1003  endif()
1004
1005  if(CMAKE_GENERATOR)
1006    set(subCMakeOpts "-G${CMAKE_GENERATOR}")
1007    if(CMAKE_GENERATOR_PLATFORM)
1008      list(APPEND subCMakeOpts "-A${CMAKE_GENERATOR_PLATFORM}")
1009    endif()
1010    if(CMAKE_GENERATOR_TOOLSET)
1011      list(APPEND subCMakeOpts "-T${CMAKE_GENERATOR_TOOLSET}")
1012    endif()
1013
1014    if(CMAKE_MAKE_PROGRAM)
1015      list(APPEND subCMakeOpts "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
1016    endif()
1017
1018  else()
1019    # Likely we've been invoked via CMake's script mode where no
1020    # generator is set (and hence CMAKE_MAKE_PROGRAM could not be
1021    # trusted even if provided). We will have to rely on being
1022    # able to find the default generator and build tool.
1023    unset(subCMakeOpts)
1024  endif()
1025
1026  set(__FETCHCONTENT_CACHED_INFO "")
1027  set(__passthrough_vars
1028    CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY
1029    CMAKE_TLS_VERIFY
1030    CMAKE_TLS_CAINFO
1031    CMAKE_NETRC
1032    CMAKE_NETRC_FILE
1033  )
1034  foreach(var IN LISTS __passthrough_vars)
1035    if(DEFINED ${var})
1036      # Embed directly in the generated CMakeLists.txt file to avoid making
1037      # the cmake command line excessively long. It also makes debugging and
1038      # testing easier.
1039      string(APPEND __FETCHCONTENT_CACHED_INFO "set(${var} [==[${${var}}]==])\n")
1040    endif()
1041  endforeach()
1042
1043  # Avoid using if(... IN_LIST ...) so we don't have to alter policy settings
1044  list(FIND ARG_UNPARSED_ARGUMENTS GIT_REPOSITORY indexResult)
1045  if(indexResult GREATER_EQUAL 0)
1046    find_package(Git QUIET)
1047    string(APPEND __FETCHCONTENT_CACHED_INFO "
1048# Pass through things we've already detected in the main project to avoid
1049# paying the cost of redetecting them again in ExternalProject_Add()
1050set(GIT_EXECUTABLE [==[${GIT_EXECUTABLE}]==])
1051set(GIT_VERSION_STRING [==[${GIT_VERSION_STRING}]==])
1052set_property(GLOBAL PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION
1053  [==[${GIT_EXECUTABLE};${GIT_VERSION_STRING}]==]
1054)
1055")
1056  endif()
1057
1058  # Create and build a separate CMake project to carry out the population.
1059  # If we've already previously done these steps, they will not cause
1060  # anything to be updated, so extra rebuilds of the project won't occur.
1061  # Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project
1062  # has this set to something not findable on the PATH.
1063  configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FetchContent/CMakeLists.cmake.in"
1064                 "${ARG_SUBBUILD_DIR}/CMakeLists.txt")
1065  execute_process(
1066    COMMAND ${CMAKE_COMMAND} ${subCMakeOpts} .
1067    RESULT_VARIABLE result
1068    ${outputOptions}
1069    WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
1070  )
1071  if(result)
1072    if(capturedOutput)
1073      message("${capturedOutput}")
1074    endif()
1075    message(FATAL_ERROR "CMake step for ${contentName} failed: ${result}")
1076  endif()
1077  execute_process(
1078    COMMAND ${CMAKE_COMMAND} --build .
1079    RESULT_VARIABLE result
1080    ${outputOptions}
1081    WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
1082  )
1083  if(result)
1084    if(capturedOutput)
1085      message("${capturedOutput}")
1086    endif()
1087    message(FATAL_ERROR "Build step for ${contentName} failed: ${result}")
1088  endif()
1089
1090endfunction()
1091
1092
1093option(FETCHCONTENT_FULLY_DISCONNECTED   "Disables all attempts to download or update content and assumes source dirs already exist")
1094option(FETCHCONTENT_UPDATES_DISCONNECTED "Enables UPDATE_DISCONNECTED behavior for all content population")
1095option(FETCHCONTENT_QUIET                "Enables QUIET option for all content population" ON)
1096set(FETCHCONTENT_BASE_DIR "${CMAKE_BINARY_DIR}/_deps" CACHE PATH "Directory under which to collect all populated content")
1097
1098# Populate the specified content using details stored from
1099# an earlier call to FetchContent_Declare().
1100function(FetchContent_Populate contentName)
1101
1102  if(NOT contentName)
1103    message(FATAL_ERROR "Empty contentName not allowed for FetchContent_Populate()")
1104  endif()
1105
1106  string(TOLOWER ${contentName} contentNameLower)
1107
1108  if(ARGN)
1109    # This is the direct population form with details fully specified
1110    # as part of the call, so we already have everything we need
1111    __FetchContent_directPopulate(
1112      ${contentNameLower}
1113      SUBBUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/${contentNameLower}-subbuild"
1114      SOURCE_DIR   "${CMAKE_CURRENT_BINARY_DIR}/${contentNameLower}-src"
1115      BINARY_DIR   "${CMAKE_CURRENT_BINARY_DIR}/${contentNameLower}-build"
1116      ${ARGN}  # Could override any of the above ..._DIR variables
1117    )
1118
1119    # Pass source and binary dir variables back to the caller
1120    set(${contentNameLower}_SOURCE_DIR "${${contentNameLower}_SOURCE_DIR}" PARENT_SCOPE)
1121    set(${contentNameLower}_BINARY_DIR "${${contentNameLower}_BINARY_DIR}" PARENT_SCOPE)
1122
1123    # Don't set global properties, or record that we did this population, since
1124    # this was a direct call outside of the normal declared details form.
1125    # We only want to save values in the global properties for content that
1126    # honors the hierarchical details mechanism so that projects are not
1127    # robbed of the ability to override details set in nested projects.
1128    return()
1129  endif()
1130
1131  # No details provided, so assume they were saved from an earlier call
1132  # to FetchContent_Declare(). Do a check that we haven't already
1133  # populated this content before in case the caller forgot to check.
1134  FetchContent_GetProperties(${contentName})
1135  if(${contentNameLower}_POPULATED)
1136    message(FATAL_ERROR "Content ${contentName} already populated in ${${contentNameLower}_SOURCE_DIR}")
1137  endif()
1138
1139  __FetchContent_getSavedDetails(${contentName} contentDetails)
1140  if("${contentDetails}" STREQUAL "")
1141    message(FATAL_ERROR "No details have been set for content: ${contentName}")
1142  endif()
1143
1144  string(TOUPPER ${contentName} contentNameUpper)
1145  set(FETCHCONTENT_SOURCE_DIR_${contentNameUpper}
1146      "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}"
1147      CACHE PATH "When not empty, overrides where to find pre-populated content for ${contentName}")
1148
1149  if(FETCHCONTENT_SOURCE_DIR_${contentNameUpper})
1150    # The source directory has been explicitly provided in the cache,
1151    # so no population is required. The build directory may still be specified
1152    # by the declared details though.
1153
1154    if(NOT IS_ABSOLUTE "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")
1155      # Don't check this directory because we don't know what location it is
1156      # expected to be relative to. We can't make this a hard error for backward
1157      # compatibility reasons.
1158      message(WARNING "Relative source directory specified. This is not safe, "
1159        "as it depends on the calling directory scope.\n"
1160        "  FETCHCONTENT_SOURCE_DIR_${contentNameUpper} --> ${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")
1161    elseif(NOT EXISTS "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")
1162      message(FATAL_ERROR "Manually specified source directory is missing:\n"
1163        "  FETCHCONTENT_SOURCE_DIR_${contentNameUpper} --> ${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")
1164    endif()
1165
1166    set(${contentNameLower}_SOURCE_DIR "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")
1167
1168    cmake_parse_arguments(savedDetails "" "BINARY_DIR" "" ${contentDetails})
1169
1170    if(savedDetails_BINARY_DIR)
1171      set(${contentNameLower}_BINARY_DIR ${savedDetails_BINARY_DIR})
1172    else()
1173      set(${contentNameLower}_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")
1174    endif()
1175
1176  elseif(FETCHCONTENT_FULLY_DISCONNECTED)
1177    # Bypass population and assume source is already there from a previous run.
1178    # Declared details may override the default source or build directories.
1179
1180    cmake_parse_arguments(savedDetails "" "SOURCE_DIR;BINARY_DIR" "" ${contentDetails})
1181
1182    if(savedDetails_SOURCE_DIR)
1183      set(${contentNameLower}_SOURCE_DIR ${savedDetails_SOURCE_DIR})
1184    else()
1185      set(${contentNameLower}_SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src")
1186    endif()
1187
1188    if(savedDetails_BINARY_DIR)
1189      set(${contentNameLower}_BINARY_DIR ${savedDetails_BINARY_DIR})
1190    else()
1191      set(${contentNameLower}_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")
1192    endif()
1193
1194  else()
1195    # Support both a global "disconnect all updates" and a per-content
1196    # update test (either one being set disables updates for this content).
1197    option(FETCHCONTENT_UPDATES_DISCONNECTED_${contentNameUpper}
1198           "Enables UPDATE_DISCONNECTED behavior just for population of ${contentName}")
1199    if(FETCHCONTENT_UPDATES_DISCONNECTED OR
1200       FETCHCONTENT_UPDATES_DISCONNECTED_${contentNameUpper})
1201      set(disconnectUpdates True)
1202    else()
1203      set(disconnectUpdates False)
1204    endif()
1205
1206    if(FETCHCONTENT_QUIET)
1207      set(quietFlag QUIET)
1208    else()
1209      unset(quietFlag)
1210    endif()
1211
1212    set(__detailsQuoted)
1213    foreach(__item IN LISTS contentDetails)
1214      string(APPEND __detailsQuoted " [==[${__item}]==]")
1215    endforeach()
1216    cmake_language(EVAL CODE "
1217      __FetchContent_directPopulate(
1218        ${contentNameLower}
1219        ${quietFlag}
1220        UPDATE_DISCONNECTED ${disconnectUpdates}
1221        SUBBUILD_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-subbuild\"
1222        SOURCE_DIR   \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src\"
1223        BINARY_DIR   \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build\"
1224        # Put the saved details last so they can override any of the
1225        # the options we set above (this can include SOURCE_DIR or
1226        # BUILD_DIR)
1227        ${__detailsQuoted}
1228      )"
1229    )
1230  endif()
1231
1232  __FetchContent_setPopulated(
1233    ${contentName}
1234    ${${contentNameLower}_SOURCE_DIR}
1235    ${${contentNameLower}_BINARY_DIR}
1236  )
1237
1238  # Pass variables back to the caller. The variables passed back here
1239  # must match what FetchContent_GetProperties() sets when it is called
1240  # with just the content name.
1241  set(${contentNameLower}_SOURCE_DIR "${${contentNameLower}_SOURCE_DIR}" PARENT_SCOPE)
1242  set(${contentNameLower}_BINARY_DIR "${${contentNameLower}_BINARY_DIR}" PARENT_SCOPE)
1243  set(${contentNameLower}_POPULATED  True PARENT_SCOPE)
1244
1245endfunction()
1246
1247# Arguments are assumed to be the names of dependencies that have been
1248# declared previously and should be populated. It is not an error if
1249# any of them have already been populated (they will just be skipped in
1250# that case). The command is implemented as a macro so that the variables
1251# defined by the FetchContent_GetProperties() and FetchContent_Populate()
1252# calls will be available to the caller.
1253macro(FetchContent_MakeAvailable)
1254
1255  foreach(__cmake_contentName IN ITEMS ${ARGV})
1256    string(TOLOWER ${__cmake_contentName} __cmake_contentNameLower)
1257    FetchContent_GetProperties(${__cmake_contentName})
1258    if(NOT ${__cmake_contentNameLower}_POPULATED)
1259      FetchContent_Populate(${__cmake_contentName})
1260
1261      # Only try to call add_subdirectory() if the populated content
1262      # can be treated that way. Protecting the call with the check
1263      # allows this function to be used for projects that just want
1264      # to ensure the content exists, such as to provide content at
1265      # a known location. We check the saved details for an optional
1266      # SOURCE_SUBDIR which can be used in the same way as its meaning
1267      # for ExternalProject. It won't matter if it was passed through
1268      # to the ExternalProject sub-build, since it would have been
1269      # ignored there.
1270      set(__cmake_srcdir "${${__cmake_contentNameLower}_SOURCE_DIR}")
1271      __FetchContent_getSavedDetails(${__cmake_contentName} __cmake_contentDetails)
1272      if("${__cmake_contentDetails}" STREQUAL "")
1273        message(FATAL_ERROR "No details have been set for content: ${__cmake_contentName}")
1274      endif()
1275      cmake_parse_arguments(__cmake_arg "" "SOURCE_SUBDIR" "" ${__cmake_contentDetails})
1276      if(NOT "${__cmake_arg_SOURCE_SUBDIR}" STREQUAL "")
1277        string(APPEND __cmake_srcdir "/${__cmake_arg_SOURCE_SUBDIR}")
1278      endif()
1279
1280      if(EXISTS ${__cmake_srcdir}/CMakeLists.txt)
1281        add_subdirectory(${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR})
1282      endif()
1283
1284      unset(__cmake_srcdir)
1285    endif()
1286  endforeach()
1287
1288  # clear local variables to prevent leaking into the caller's scope
1289  unset(__cmake_contentName)
1290  unset(__cmake_contentNameLower)
1291  unset(__cmake_contentDetails)
1292  unset(__cmake_arg_SOURCE_SUBDIR)
1293
1294endmacro()
1295