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