# External Project and debug/release builds with multi-config generators

**URL:** https://discourse.cmake.org/t/external-project-and-debug-release-builds-with-multi-config-generators/7469
**Category:** Usage
**Created:** [February 14, 2023, 9:39pm UTC](https://discourse.cmake.org/t/external-project-and-debug-release-builds-with-multi-config-generators/7469 "2023-02-14T21:39:54Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![neundorf](https://discourse.cmake.org/user_avatar/discourse.cmake.org/neundorf/32/2075_2.png) [@neundorf](https://discourse.cmake.org/u/neundorf)
#### Post date: [February 14, 2023, 9:39pm UTC](https://discourse.cmake.org/t/external-project-and-debug-release-builds-with-multi-config-generators/7469/1 "2023-02-14T21:39:54Z")

</div>

Hi,

I’m struggling a bit with ExternalProject and multi-config generators (MSVC).  
How do I “tell” ExternalProject\_Add() whether I need a debug or a release build depending on the currently selected build type ?  
The external project has nmake Makefiles.

---

<div class="post-metadata">

### Author: ![bill.hoffman](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bill.hoffman/32/13_2.png) [@bill.hoffman](https://discourse.cmake.org/u/bill.hoffman)
#### Post date: [February 14, 2023, 10:22pm UTC](https://discourse.cmake.org/t/external-project-and-debug-release-builds-with-multi-config-generators/7469/2 "2023-02-14T22:22:47Z")

</div>

I would think that you would want to use generator expressions to control the build of the external project using nmake.

---

<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 15, 2023, 6:12pm UTC](https://discourse.cmake.org/t/external-project-and-debug-release-builds-with-multi-config-generators/7469/3 "2023-02-15T18:12:11Z")

</div>

In addition to a `-DCMAKE_BUILD_TYPE:STRING=$<CONFIG>`, you’ll likely also want `BUILD_DIR something/$<CONFIG> STAMP_DIR/something/$<CONFIG>` or the like to avoid rebuilds on every configuration switch. The install tree may also get very confused if the contents of files overlap in ways that are configuration-sensitive (e.g., not changing library names).

---

<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: [February 15, 2023, 11:17pm UTC](https://discourse.cmake.org/t/external-project-and-debug-release-builds-with-multi-config-generators/7469/4 "2023-02-15T23:17:23Z")

</div>

I would have expected the ExternalProject to follow the same config used to build the main project. Is that not happening for you, or are you trying to force a particular config different to the main build? When the main project is using a multi-config generator, the ExternalProject module explicitly passes the config to use as `--config $<CONFIG>` on the `cmake --build ...` command line it constructs.

---

<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 15, 2023, 11:26pm UTC](https://discourse.cmake.org/t/external-project-and-debug-release-builds-with-multi-config-generators/7469/5 "2023-02-15T23:26:22Z")

</div>

AFAIK, `cmake --config x --build` does nothing for single-config generators (as it was baked in at configure time via `CMAKE_BUILD_TYPE`).

---

<div class="post-metadata">

### Author: ![neundorf](https://discourse.cmake.org/user_avatar/discourse.cmake.org/neundorf/32/2075_2.png) [@neundorf](https://discourse.cmake.org/u/neundorf)
#### Post date: [May 3, 2025, 4:47pm UTC](https://discourse.cmake.org/t/external-project-and-debug-release-builds-with-multi-config-generators/7469/6 "2025-05-03T16:47:49Z")

</div>

I created a small example project (not using nmake, but the ninja single-config generator):

> **[GitHub - neundorf/CMakeExternalProjectExample: Small cmake example with external project on...](https://github.com/neundorf/CMakeExternalProjectExample)**
>
> Small cmake example with external project on multi-config generators

It seems to be mostly working.  
I am seeing one problem, after the initial cmake run, not all build types are working:

```auto
build> /opt/cmake-3.31.7-linux-x86_64/bin/cmake -G "Ninja Multi-Config" ..
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/alex/src/tests/extproj2/build
build> /opt/cmake-3.31.7-linux-x86_64/bin/cmake --build . --config Debug
ninja: error: '3rdparty/Install/Release/lib/libfoo.so', needed by 'Debug/footest', missing and no known rule to make it

```

But I can build “Release”:

```auto
~/src/tests/extproj2/build> /opt/cmake-3.31.7-linux-x86_64/bin/cmake --build . --config Release
[5/10] Performing configure step for 'EP_libfoo'
Not searching for unused variables given on the command line.
-- The C compiler identification is GNU 14.2.1
-- The CXX compiler identification is GNU 14.2.1
...
[6/10] Performing build step for 'EP_libfoo'
[1/2] Building CXX object CMakeFiles/foo.dir/Release/foo.cpp.o
[2/2] Linking CXX shared library Release/libfoo.so
[7/10] Performing install step for 'EP_libfoo'
[0/1] Install the project...
-- Install configuration: "Release"
-- Installing: /home/alex/src/tests/extproj2/build/3rdparty/Install/Release/lib/libfoo.so
-- Installing: /home/alex/src/tests/extproj2/build/3rdparty/Install/Release/include/foo/foo.h
[10/10] Linking CXX executable Release/footest

```

Trying to build Debug afterwards works:

```auto
build> /opt/cmake-3.31.7-linux-x86_64/bin/cmake --build . --config Debug
[5/10] Performing configure step for 'EP_libfoo'
Not searching for unused variables given on the command line.
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/alex/src/tests/extproj2/build/ExternalProjects/src/EP_libfoo-build
[6/10] Performing build step for 'EP_libfoo'
[1/2] Building CXX object CMakeFiles/foo.dir/Debug/foo.cpp.o
[2/2] Linking CXX shared library Debug/libfoo.so
[7/10] Performing install step for 'EP_libfoo'
[0/1] Install the project...
-- Install configuration: "Debug"
-- Installing: /home/alex/src/tests/extproj2/build/3rdparty/Install/Debug/lib/libfoo.so
-- Installing: /home/alex/src/tests/extproj2/build/3rdparty/Install/Debug/include/foo/foo.h
[10/10] Linking CXX executable Debug/footest

```

Why does it complain in Debug mode “no known rule to make it”, but after building in Release mode, it works ?

Why do I have to set the IMPORTED\_LOCATION target property, I thought it is good enough to set the \_Release, \_Debug and \_RelWithDebInfo properties ?

---

<div class="post-metadata">

### Author: ![neundorf](https://discourse.cmake.org/user_avatar/discourse.cmake.org/neundorf/32/2075_2.png) [@neundorf](https://discourse.cmake.org/u/neundorf)
#### Post date: [June 17, 2025, 8:38pm UTC](https://discourse.cmake.org/t/external-project-and-debug-release-builds-with-multi-config-generators/7469/7 "2025-06-17T20:38:21Z")

</div>

Ok, found the problem.  
In the IMPORTED\_LOCATION\_ property the build type has to be ALLUPPERCASE.  
So this works now with make, ninja, ninja-multiconfig (when setting the properties correctly also under Windows, also when using Visual Studio).

> **[GitHub - neundorf/CMakeExternalProjectExample: Small cmake example with external project on...](https://github.com/neundorf/CMakeExternalProjectExample)**
>
> Small cmake example with external project on multi-config generators
