# Pulling in ExternalProject\_Add from other subproject in add\_subdirectory

**URL:** https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951
**Category:** Usage
**Created:** [January 27, 2024, 5:08pm UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951 "2024-01-27T17:08:36Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![Desperado17](https://discourse.cmake.org/user_avatar/discourse.cmake.org/desperado17/32/4197_2.png) [@Desperado17](https://discourse.cmake.org/u/Desperado17)
#### Post date: [January 27, 2024, 5:08pm UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/1 "2024-01-27T17:08:36Z")

</div>

Greetings,

I have a cmake project that combines some external dependencies with subdirectories.

The first dependency is pulled in via FetchContent\_Dependency / FetchContent\_MakeAvailable. This dependency in its own CMakeLists.txt pulls in libceres as prebuilt binary via ExternalProject\_Add.

After the first dependency’s FetchContent\_MakeAvailable call, a subdirectory is added via add\_subdirectory on top level. The files in this directory could also need libceres which I try to pull in from the first dependency via find\_package ( ceres .

Problem: The ExternalProject\_Add in the first dependency does not download libceres before the build process of the add\_subdirectory files starts although FetchContent\_MakeAvailable comes before the latter in the top level CMakeLists.txt.

Any idea why?

Regards

---

<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: [January 28, 2024, 4:57am UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/2 "2024-01-28T04:57:18Z")

</div>

You’re trying to mix projects in a way they aren’t really designed to be. If a dependency forces using `ExternalProject_Add()` to bring in its own dependencies, I don’t recommend you pull it into your project with `FetchContent`. Pretty much once any dependency uses `ExternalProject`, it doesn’t play nice with any other project wanting to use it as a dependency.

In your situation, I would not add your immediate dependency with `FetchContent`. Find a way to have that dependency pre-built and bring it in as a binary package using `find_package()`. You’ll have to find a way to do that which fits within your project’s constraints. There are different solutions depending on what the dependency is and what rules you have to follow for your project. In an ideal scenario, it’s a commonly used dependency and you’re allowed to use a package manager like Conan to bring it into your build.

---

<div class="post-metadata">

### Author: ![Desperado17](https://discourse.cmake.org/user_avatar/discourse.cmake.org/desperado17/32/4197_2.png) [@Desperado17](https://discourse.cmake.org/u/Desperado17)
#### Post date: [January 28, 2024, 11:12am UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/3 "2024-01-28T11:12:27Z")

</div>

Yeah I feared something like that.

Just out of curiosity: Can you tell me which command actually triggers the download and deployment of an ExternalProject\_Add dependency?

Regards

---

<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: [January 28, 2024, 9:26pm UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/4 "2024-01-28T21:26:36Z")

</div>

The download part is an internal detail of `ExternalProject_Add()`. The actual command(s) called depend on the download method used. It might use `file(DOWNLOAD)`, or it might call a command line tool like `git`. These are private details that the calling project shouldn’t care about nor try to interfere with.

As for the deployment part, that’s the INSTALL step of `ExternalProject_Add()`. For a CMake-based external project, this will default to building the `install` target. For non-CMake-based external projects, the default assumes a Makefiles-based project and does a `make install`. Projects can override these defaults and specify their own install command with `INSTALL_COMMAND`.

---

<div class="post-metadata">

### Author: ![Desperado17](https://discourse.cmake.org/user_avatar/discourse.cmake.org/desperado17/32/4197_2.png) [@Desperado17](https://discourse.cmake.org/u/Desperado17)
#### Post date: [January 29, 2024, 7:00am UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/5 "2024-01-29T07:00:08Z")

</div>

And the install step of the ExternalProject\_Add is not finished before FetchContent\_MakeAvailable of the parent?

---

<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: [January 29, 2024, 10:57am UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/6 "2024-01-29T10:57:29Z")

</div>

No part of `ExternalProject_Add()` executes during the configure step. All parts of that only happen at build time. The `FetchContent_MakeAvailable()` command, on the other hand, executes entirely at configure time. If you bring in a dependency “A” via FetchContent, and that dependency brings in another dependency “B” by ExternalProject, no part of “B” will be available when `FetchContent_MakeAvailable(A)` returns. Not even the configure step for “B” will have been executed, that only happens at build time.

---

<div class="post-metadata">

### Author: ![Desperado17](https://discourse.cmake.org/user_avatar/discourse.cmake.org/desperado17/32/4197_2.png) [@Desperado17](https://discourse.cmake.org/u/Desperado17)
#### Post date: [January 29, 2024, 7:08pm UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/7 "2024-01-29T19:08:45Z")

</div>

But the build complains about lacking includes from ceres while it builds the add\_subdirectory. Shouldn’t `ExternalProject_Add` finish before this build step is started?

---

<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: [January 29, 2024, 9:42pm UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/8 "2024-01-29T21:42:12Z")

</div>

You are confusing terms. When you run CMake, that’s the configure and generation phase. The purpose of those is to generate the files that the build tool needs (eg. `Makefile`, `build.ninja`, and so on). The build hasn’t started yet. You invoke the build tool after configure and generation to perform the build step. All the FetchContent stuff happens during configure. All the ExternalProject stuff happens during the build. There is no overlap other than the `ExternalProject_Add()` command is called during configure, but that only defines build rules. It doesn’t do any of the external project steps at that time.

---

<div class="post-metadata">

### Author: ![Desperado17](https://discourse.cmake.org/user_avatar/discourse.cmake.org/desperado17/32/4197_2.png) [@Desperado17](https://discourse.cmake.org/u/Desperado17)
#### Post date: [January 29, 2024, 9:50pm UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/9 "2024-01-29T21:50:45Z")

</div>

Yeah `ExternalProject_Add` creates a target and add\_subdirectory goes into the main target of the top CMakeLists.txt where the fetch is yes? Shouldn’t the targets created by the ExternalProject\_Add be processed before the final one of the main target?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [February 4, 2024, 2:15pm UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/10 "2024-02-04T14:15:08Z")

</div>

> [@Desperado17](#):
>
> Shouldn’t the targets created by the ExternalProject\_Add be processed before the final one of the main target?

The _targets_ are, but nothing has executed them yet. Nothing from `libceres` will exist until `cmake --build` is performed.

---

<div class="post-metadata">

### Author: ![Desperado17](https://discourse.cmake.org/user_avatar/discourse.cmake.org/desperado17/32/4197_2.png) [@Desperado17](https://discourse.cmake.org/u/Desperado17)
#### Post date: [February 4, 2024, 3:31pm UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/11 "2024-02-04T15:31:28Z")

</div>

Yeah but the cmake --build of ceres should be executed before the cmake --build of the main target, right? So why does the main target compile complain about lacking ceres headers when ceres hasn’t even downloaded yet?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [February 4, 2024, 7:37pm UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/12 "2024-02-04T19:37:10Z")

</div>

Can you share the error message you’re getting?

---

<div class="post-metadata">

### Author: ![Desperado17](https://discourse.cmake.org/user_avatar/discourse.cmake.org/desperado17/32/4197_2.png) [@Desperado17](https://discourse.cmake.org/u/Desperado17)
#### Post date: [February 4, 2024, 8:05pm UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/13 "2024-02-04T20:05:00Z")

</div>

It complains that it doesn’t find a header of ceres during the build of the main target. The reason is that ceres has not been downloaded at the time the main target is built although it should I think.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [February 5, 2024, 1:06pm UTC](https://discourse.cmake.org/t/pulling-in-externalproject-add-from-other-subproject-in-add-subdirectory/9951/14 "2024-02-05T13:06:46Z")

</div>

Something is missing a dependency on `ceres` completing. It’s hard to say what, exactly, without the project, but basically anything directly linking to the results of building the `ceres` project should get `add_dependencies(uses-ceres ceres)`.
