# Passing all elemental environment into ExternalProject\_Add

**URL:** https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878
**Category:** Usage
**Created:** [January 18, 2024, 9:02pm UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878 "2024-01-18T21:02:11Z")
**Posts on this page:** 13
**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 18, 2024, 9:02pm UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/1 "2024-01-18T21:02:11Z")

</div>

Greetings, I have to add a 3rd party CMake project to our own one. The 3rd party project has several submodules that it adds with ExternalProject\_Add. Problem: The submodules use find\_package extensively and apparently the CMAKE\_FIND\_ROOT\_PATH variable is not transferred to the submodule by ExternalProject\_Add. The project does not explicitly transfer CMAKE\_FIND\_ROOT\_PATH in the CMAKE\_ARGS list.

Is there a way for the outer project to make sure essential variables are transferred into all submodules imported by ExternalProject\_Add or is this just a design flaw by the 3rd party lib?

Regards

---

<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: [January 18, 2024, 9:08pm UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/2 "2024-01-18T21:08:32Z")

</div>

You can pass it explicitly with `-DCMAKE_FIND_ROOT_PATH:STRING=$ENV{CMAKE_FIND_ROOT_PATH}` when configuring the projects. But there’s no built-in way to set up the environment for `ExternalProject` projects.

---

<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 18, 2024, 9:13pm UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/3 "2024-01-18T21:13:48Z")

</div>

So that means I would have to edit the ExternalProject\_Add calls in the 3rd party library to make sure all Variables I need are passed, right?

Is there an alternative to ExternalProject\_Add that is more comfortable in this regard?

---

<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: [January 18, 2024, 11:17pm UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/4 "2024-01-18T23:17:21Z")

</div>

Not AFAIK.

@craig.scott ?

---

<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 19, 2024, 7:39am UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/5 "2024-01-19T07:39:04Z")

</div>

`ExternalProject_Add()` only really works well if you’re following the classic superbuild pattern closely. Once you have sub-projects that call `ExternalProject_Add()`, or your main project tries to add anything to its build other than through `ExternalProject_Add()`, it starts to fall apart pretty quickly.

If a dependency uses `ExternalProject_Add()`, that’s usually a pretty clear signal that it isn’t all that well suited to being absorbed into a larger build other than as a pre-built package. I’m afraid I don’t have any good news or workarounds to offer you for your situation that don’t involve editing the third party project.

---

<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 19, 2024, 8:25am UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/6 "2024-01-19T08:25:50Z")

</div>

Ok, just to be sure:

What would the author have used if he wanted the variables to be handed over? add\_subdirectory?

---

<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 19, 2024, 9:19am UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/7 "2024-01-19T09:19:48Z")

</div>

In general, the most flexible strategy is for your project to use `find_package()` to bring in its dependencies. The project is then specifying the “what”, but not the “how”. It is up to the user to decide how they want to make the dependencies available, and they can choose the strategy that best fits their situation.

CMake 3.24 and later has dedicated support for facilitating the “how” through a feature called dependency providers. With earlier CMake versions, the user has to essentially prepare the dependencies pre-built beforehand, then tell the project where to find them by setting variables like `CMAKE_PREFIX_PATH`.

Another strategy is to use `FetchContent` instead of `find_package()`. This is most suitable for companies where all the sources that are needed by the project will be under the organisation’s control. Some dependencies might be internal, others may be open source. This approach is well-suited to cases where you want to build all your dependencies from sources, but it can be used to provide pre-built binaries if needed (not typically what you’d use `FetchContent` for though). Dependency providers also support intercepting `FetchContent` too, not just `find_package()`, so the user is still in control and able to override details the project provides in its calls to `FetchContent_Declare()`.

The `FetchContent` approach has the advantage that the dependencies are absorbed directly into your project, so they would see variables like `CMAKE_FIND_ROOT_PATH`. But they wouldn’t need those variables unless they were calling `find_package()` for some of their own dependencies. `find_package()` has the advantage that it is very mature and well-supported with mainstream package managers like conan and vcpkg.

For the third party dependency you’re talking about, it’s not likely to be a simple case of replacing `ExternalProject_Add()` calls with something else. If they are all CMake projects, you _might_ be able to replace them with equivalent FetchContent calls, in which case the close relationship between ExternalProject and FetchContent may make that easier. But that would only work if all the dependencies were written in such a way that they support being added to a larger parent project. Many older projects use patterns or techniques that prevent that though.

---

<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 19, 2024, 9:27am UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/8 "2024-01-19T09:27:15Z")

</div>

Ok, thank you!

---

<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 19, 2024, 5:37pm UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/9 "2024-01-19T17:37:35Z")

</div>

Btw the $ENV{ doesn’t seem to work for me, an empty CMAKE\_FIND\_ROOT\_PATH appears in the dependent object. Does this work if CMAKE\_FIND\_ROOT\_PATH is multiple semicolon separated paths?

---

<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: [January 19, 2024, 6:03pm UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/10 "2024-01-19T18:03:36Z")

</div>

> [@Desperado17](#):
>
> Does this work if CMAKE\_FIND\_ROOT\_PATH is multiple semicolon separated paths?

Oh…no. You’ll need to replace `;` with a separator to get it through the `ExternalProject` calls. See [`LIST_SEPARATOR`](https://cmake.org/cmake/help/latest/module/ExternalProject.html#miscellaneous-options) docs.

---

<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 19, 2024, 8:08pm UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/11 "2024-01-19T20:08:23Z")

</div>

Ah yeah I see tx.

---

<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 19, 2024, 10:28pm UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/12 "2024-01-19T22:28:37Z")

</div>

Just out of curiosity: The semicolon is a cmake standard, right? Why does cmake have troubles passing it through its own calls?

---

<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: [January 22, 2024, 2:54pm UTC](https://discourse.cmake.org/t/passing-all-elemental-environment-into-externalproject-add/9878/13 "2024-01-22T14:54:59Z")

</div>

There’s no way to escape it to arbitrary levels (and even if so, to know how many layers are needed for a given call site). It’s just one of those weird unfortunate things baked into CMake’s DNA at this point though.
