# using build preset with ExternalProject\_Add

**URL:** https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902
**Category:** Code
**Created:** [November 6, 2024, 5:35am UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902 "2024-11-06T05:35:21Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![fws](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fws/32/5104_2.png) [@fws](https://discourse.cmake.org/u/fws)
#### Post date: [November 6, 2024, 5:35am UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/1 "2024-11-06T05:35:21Z")

</div>

Hello,

for a part of my project I use a qnx compiler that needs QNX\_HOST and QNX\_TARGET environment variables to be set.  
To archive that I use cmake --preset for configuration and for building

the project is build for QNX and for Linux therefore I also used the preset to set the toolchainfile and some cached variables

because both variants (QNX and Linux) should be delivered I now wanted to use ExternalProject\_Add to build both variants and include the build output of the linux and the qnx version in one package.

with the CMAKE\_ARGS parameter of ExternalProject\_Add it is possible to specify a preset but it is only used as a configuration preset  
the default build commad is make --build and it is run inside the build directory. Changing it to cmake --build ./ --preset=linux does not work because the cmakepreset.json is not in the build directory. I didt find a way to set the directory in which the build command is run

is there a way to use a build preset with ExternalProject\_Add?

Any Help is appreciated

kind regards

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [November 6, 2024, 6:25am UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/2 "2024-11-06T06:25:26Z")

</div>

Why not use **FetchContent** instead?

---

<div class="post-metadata">

### Author: ![fws](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fws/32/5104_2.png) [@fws](https://discourse.cmake.org/u/fws)
#### Post date: [November 6, 2024, 6:34am UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/3 "2024-11-06T06:34:21Z")

</div>

sorry I don’t understand how would that solve the problem? How can I set a build preset with FetchContent?

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [November 6, 2024, 7:55am UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/4 "2024-11-06T07:55:24Z")

</div>

With `FetchContents` default the external projects are cloned in your binary directory while `configure step`.

So it is a sub-project of your own master project.  
And you build it with your `cmake preset`.

---

<div class="post-metadata">

### Author: ![fws](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fws/32/5104_2.png) [@fws](https://discourse.cmake.org/u/fws)
#### Post date: [November 6, 2024, 8:44am UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/5 "2024-11-06T08:44:15Z")

</div>

thank you for your fast reply  
but there is no build command for the FetchContents or did I miss something?  
In the SubProject I add with ExternalProject\_Add I want to use the build preset from the CMakePrests.json of SubProject Project not from the master Project.  
At the moment I defined a build preset in the master project but only because I didn’t find a way for the ExternalProject\_add command to use the build preset from the CMakePresets.json in the external project.

MasterProject/CMakeLists.txt  
MasterProject/SubProject  
MasterProject/SubProject/CMakeLists.txt  
MasterProject/SubProject/CMakePresets.json

thank you for your help, I am sorry that its so confusing

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [November 6, 2024, 8:51am UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/6 "2024-11-06T08:51:30Z")

</div>

see too [How to configure multiple cmake projects with CMakePresets.json?](https://discourse.cmake.org/t/how-to-configure-multiple-cmake-projects-with-cmakepresets-json/12673)

Q: is your `SubProject` a **git submodule** of your `MasterProject`?

---

<div class="post-metadata">

### Author: ![fws](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fws/32/5104_2.png) [@fws](https://discourse.cmake.org/u/fws)
#### Post date: [November 6, 2024, 9:32am UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/7 "2024-11-06T09:32:06Z")

</div>

no they are not submodules, I am already using CMakePresets at SubProject level for the configuration step of the SubProject they already work. But I don’t know how to also use the build preset during build step. I am using the SubProject standalone I can use:

```auto
cmake -B ./build/xyz_a --preset=a
cmake --build ./build/xyz_a --preset=a

cmake -B ./build/xyz_b --preset=b
cmake --build ./build/xyz_b --preset=b

```

and the behavior is as I would expected but if I am using

```auto
ExternalProject_Add(ScuSoftwareLinux 
                    SOURCE_DIR "${CMAKE_SOURCE_DIR}/SubProject/"
                    STEP_TARGETS build 
                    CMAKE_ARGS --preset=a
                    )

```

the build behaves as I would run in the SubProjects directory

```auto
cmake -B ./build/xyz_a --preset=a
cmake --build ./build/xyz_a

```

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [November 6, 2024, 10:16am UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/8 "2024-11-06T10:16:49Z")

</div>

> [@fws](#):
>
> `cmake --build ./build/xyz_a --preset=a`

### This is wrong and should give an error!

A build preset is started with: `cmake --build --preset=a`

---

<div class="post-metadata">

### Author: ![fws](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fws/32/5104_2.png) [@fws](https://discourse.cmake.org/u/fws)
#### Post date: [November 6, 2024, 10:43am UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/9 "2024-11-06T10:43:21Z")

</div>

from the documentation I don’t see why this should give me an error and is wrong in general.

[https://cmake.org/cmake/help/latest/manual/cmake.1.html#manual:cmake(1)](https://cmake.org/cmake/help/latest/manual/cmake.1.html#manual:cmake(1))

chapter: **Build a Project**  
says  
`cmake --build --preset <preset> [<options>] [-- <build-tool-options>]`

it does not state that the option `--preset` is excluded

neither does it say in the chapter option that `--preset` is not allowed in case` cmake --build` is used

how should `cmake --build` now where to build

I see you should probably define a “binaryDir” in the CMakePreset.json and I am guessing that this maybe will solve my issues but I get why the command it self is wrong in general.

But I will check if setting the "binaryDir in the CMakePreset.json will solve my issues

Again thank you for your Help!

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [November 6, 2024, 10:44am UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/10 "2024-11-06T10:44:12Z")

</div>

@ben.boeckel some combinations of `cmake` command line arguments may resut in very strange conditions:

```bash
klein_cl@lx005535:~/Workspace/cpp$ cmake -S execution26 --preset release
Preset CMake variables:

  CMAKE_BUILD_TYPE="RelWithDebInfo"
  CMAKE_CXX_EXTENSIONS:BOOL="FALSE"
  CMAKE_CXX_FLAGS="-Wall -Wextra -Wpedantic -Wno-shadow -Wconversion -Wsign-conversion -Wcast-align -Wcast-qual -Woverloaded-virtual -Wformat=2 -Wno-error"
  CMAKE_CXX_STANDARD="23"
  CMAKE_CXX_STANDARD_REQUIRED:BOOL="TRUE"
  CMAKE_EXPORT_COMPILE_COMMANDS:BOOL="TRUE"
  CMAKE_INSTALL_PREFIX:PATH="/home/klein_cl/Workspace/cpp/execution26/stagedir"
  CMAKE_PREFIX_PATH:STRING="/home/klein_cl/Workspace/cpp/execution26/stagedir"
  CMAKE_SKIP_TEST_ALL_DEPENDENCY:BOOL="FALSE"

-- The CXX compiler identification is Clang 17.0.6
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/lib/llvm-17/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- TARGET_ALIAS="beman_execution26::beman_execution26" ; TARGET_LIBRARY="beman_execution26" ; TARGET_PREFIX="beman.execution26" ; PROJECT_SOURCE_DIR="/home/klein_cl/Workspace/cpp/execution26"
-- Configuring done (0.4s)
-- Generating done (0.1s)
-- Build files have been written to: /home/klein_cl/Workspace/cpp/execution26/build/release
klein_cl@lx005535:~/Workspace/cpp$ cmake --build execution26 --preset release
CMake Error: Could not read presets from /home/klein_cl/Workspace/cpp:
File not found: /home/klein_cl/Workspace/cpp/CMakePresets.json
klein_cl@lx005535:~/Workspace/cpp$ cmake --build execution26/build/release/ --preset release
CMake Error: Could not read presets from /home/klein_cl/Workspace/cpp:
File not found: /home/klein_cl/Workspace/cpp/CMakePresets.json
klein_cl@lx005535:~/Workspace/cpp$ 

```

---

<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 6, 2024, 9:33pm UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/11 "2024-11-06T21:33:57Z")

</div>

> [@fws](#):
>
> ```auto
> cmake -B ./build/xyz_b --preset=b
> cmake --build ./build/xyz_b --preset=b
> 
> ```

The build directory shouldn’t be given after `--build` if you’re also giving the `--preset` option. I think that’s what @ClausKlein was trying to communicate. Here’s how the documentation of the `--preset` option explains it:

> –preset , --preset=
> 
> Use a build preset to specify build options. The project binary directory is inferred from the `configurePreset` key. The current working directory must contain CMake preset files. See [`preset`](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#manual:cmake-presets(7)) for more details.

When you use `ExternalProject_Add()`, its defaults for the build command come from a time before presets existed. It sets the working directory to the build directory, which isn’t what you need if you want to use a build preset. You can work around that by using the `cmake -E chdir` command to issue a command with a different working directory. Here’s how you would do that:

```cmake
ExternalProject_Add(someTarget
    # ... Specify where to get things using GIT_REPOSITORY or whatever ...
    BUILD_COMMAND
        ${CMAKE_COMMAND} -E chdir <SOURCE_DIR>
            ${CMAKE_COMMAND} --build --preset YourPresetName
)

```

I’ve used indenting to make things a bit clearer to read, but that’s just personal preference. The `ExternalProject_Add()` command automatically replaces `<SOURCE_DIR>` with the source directory, so it’s a convenient way to avoid having to work out where that will be.

---

<div class="post-metadata">

### Author: ![fws](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fws/32/5104_2.png) [@fws](https://discourse.cmake.org/u/fws)
#### Post date: [November 7, 2024, 7:00am UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/12 "2024-11-07T07:00:36Z")

</div>

ok I think things are getting a bit more clear to me. What I am still missing is:

if I set `binaryDir` in the configure preset shouldn’t it also be used in the configuration step or at least depend on it?

would id make sense to have for example set `"binaryDir": "./build/xyz_b",` in the CMakePresets file but configure with `cmake -B ./build/xyz_c --preset=b`?  
for my understanding binaryDir almost always depends on the build path configured with `cmake -B` so in this example it would depend on `./build/xyz_c`

Thank you

---

<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 7, 2024, 7:25pm UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/13 "2024-11-07T19:25:13Z")

</div>

Build presets (and also test, package, and workflow presets) rely on you using the binary directory specified in the configure preset. If you override the binary directory when you configure your project (i.e. you use the `-B` option), you won’t be able to use build presets with it.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [November 8, 2024, 8:02pm UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/14 "2024-11-08T20:02:15Z")

</div>

`cmake -B ./build/xyz_b --preset=gcc-release`

@craig.scott  
It should not be allowed to use the **-B** with **–preset** or **–workflow** option together!  
**IMHO** : And the `configure preset` **must** have a `binaryDir` item.

---

<div class="post-metadata">

### Author: ![fws](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fws/32/5104_2.png) [@fws](https://discourse.cmake.org/u/fws)
#### Post date: [November 8, 2024, 9:15pm UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/15 "2024-11-08T21:15:23Z")

</div>

ok now I understand, makes sense thank you, I didn’t used the binaryDir option which led to confusion. I also didn’t know that it’s possible to use multiple BUILD\_COMMANDS for the ExternalProject\_Add.

Again thank you, I learned a Lot

---

<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 9, 2024, 9:08pm UTC](https://discourse.cmake.org/t/using-build-preset-with-externalproject-add/12902/16 "2024-11-09T21:08:58Z")

</div>

> [@fws](#):
>
> I also didn’t know that it’s possible to use multiple BUILD\_COMMANDS for the ExternalProject\_Add.

The example I gave is only one single command for the build step:

```cmake
ExternalProject_Add(someTarget
    # ... Specify where to get things using GIT_REPOSITORY or whatever ...
    BUILD_COMMAND
        ${CMAKE_COMMAND} -E chdir <SOURCE_DIR>
            ${CMAKE_COMMAND} --build --preset YourPresetName
)

```

I just split it across multiple lines to make it easier to read, but CMake will still consider that all a single command line. But if needed, you _can_ specify multiple commands. Put the first one after `BUILD_COMMAND`, and then subsequent ones immediately following it preceded by `COMMAND`. For example:

```cmake
ExternalProject_Add(someTarget
    # ... Specify where to get things using GIT_REPOSITORY or whatever ...
    BUILD_COMMAND
        ${CMAKE_COMMAND} -E chdir <SOURCE_DIR>
            ${CMAKE_COMMAND} --build --preset YourPresetName
    COMMAND ${CMAKE_COMMAND} -E echo "This is a second command"
)

```
