# Can you combine FetchContent and ExternalProject?

**URL:** <https://discourse.cmake.org/t/can-you-combine-fetchcontent-and-externalproject/228>\
**Category:** Code\
**Created:** [November 18, 2019, 8:15pm UTC](https://discourse.cmake.org/t/can-you-combine-fetchcontent-and-externalproject/228 "2019-11-18T20:15:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mathomp4](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mathomp4/32/176_2.png) [@mathomp4](https://discourse.cmake.org/u/mathomp4)\
**Post date:** [November 18, 2019, 8:15pm UTC](https://discourse.cmake.org/t/can-you-combine-fetchcontent-and-externalproject/228/1 "2019-11-18T20:15:42Z")

</div>

A query for the experts. I’m trying to transition building a set of base libraries currently done with GNU Make to CMake. Now, I’m having fairly good luck with ExternalProject\_Add, but I have only one issue with that: downloading is done at build time, not configure time. This is only a problem for me because I would like to build these libraries at a supercomputing center on a compute node so that I don’t take up shared head nodes. But compute nodes cannot see the internet, thus any URL fetches will fail.

So, I’d love to be able to use FetchContent to get the needed tarballs at cmake time (maybe for a variety of compiler/MPI stacks) and then get compute nodes and do a ‘make -j10’ on each in the build dirs where ExternalProject takes care of that.

Is this possible? I know at some point a user (say, me) will need to do _something_ on a head node. I’d just prefer it to be the thin Fetch step and not the expensive Build step.

---

<div class="post-metadata">

**Author:** ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)\
**Post date:** [November 19, 2019, 11:08am UTC](https://discourse.cmake.org/t/can-you-combine-fetchcontent-and-externalproject/228/2 "2019-11-19T11:08:05Z")

</div>

Ordinarily, I advise choosing one or the other rather than mixing `FetchContent` and `ExternalProject`. More specifically, if you can use `FetchContent` to not just download the dependencies but also to add them directly to your build, that is typically simpler than `ExternalProject` (read up on using [`FetchContent_MakeAvailable()`](https://cmake.org/cmake/help/latest/module/FetchContent.html#command:fetchcontent_makeavailable) specifically). It relies on the dependency projects not doing things like assuming they are the top level project or using target names that other projects also define, but if you don’t hit either of those problems, then it’s probably the simpler route.

In your situation, it may still make sense to mix the two approaches. You want the sources to be downloaded at configure time, which FetchContent can achieve for you (you can’t use `FetchContent_MakeAvailable()` then though). If you genuinely do need to build the dependencies as external builds, then `ExternalProject` is the right tool for that. You can tell `ExternalProject` to use the source locations that `FetchContent` will have already populated for you at configure time. In the call to `ExternalProject_Add()`, omit any download or update details and instead provide `SOURCE_DIR`, with a value being provided by `FetchContent`. For example (untested, but hopefully you get the idea):

```cmake
FetchContent_Declare(someproj
    GIT_REPOSITORY https://github.com/someGroup/someproj
    ...
)
FetchContent_GetProperties(someproj)
if(NOT someproj_POPULATED)
  FetchContent_Populate(someproj)
endif()

ExternalProject_Add(someproj
    SOURCE_DIR ${someproj_SOURCE_DIR} # Provided by FetchContent
    ...
)

```

Just to be clear, your approach relies on the head node being identically configured to the compute nodes (same paths, exact same tool versions, etc.).

---

<div class="post-metadata">

**Author:** ![mathomp4](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mathomp4/32/176_2.png) [@mathomp4](https://discourse.cmake.org/u/mathomp4)\
**Post date:** [November 19, 2019, 5:57pm UTC](https://discourse.cmake.org/t/can-you-combine-fetchcontent-and-externalproject/228/3 "2019-11-19T17:57:21Z")

</div>

This does indeed work, thanks! Unfortunately, it looks like the CMake in HDF5 and netCDF is currently not quite good enough for me to do a “let’s use CMake as much as we can” version. Time for fun with `CONFIGURE_COMMAND`
