# Generator expressions in external projects.

**URL:** <https://discourse.cmake.org/t/generator-expressions-in-external-projects/805>\
**Category:** Code\
**Created:** [March 14, 2020, 5:03pm UTC](https://discourse.cmake.org/t/generator-expressions-in-external-projects/805 "2020-03-14T17:03:46Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![karliss](https://discourse.cmake.org/user_avatar/discourse.cmake.org/karliss/32/428_2.png) [@karliss](https://discourse.cmake.org/u/karliss)\
**Post date:** [March 14, 2020, 5:03pm UTC](https://discourse.cmake.org/t/generator-expressions-in-external-projects/805/1 "2020-03-14T17:03:46Z")

</div>

Most external project commands support generator expressions. `INSTALL_DIR ` isn’t used by CMake directly but instead used as placeholder in commands which support generator expressions. Documentation doesn’t mention and from experimental results it seems that using generator expressions inside `INSTALL_DIR` doesn’t work as CMake tries to validate the path without expanding generator expressions. In case of `INSTALL_DIR` workaround is not using \<INSTALL\_DIR\> and specifying generator expression directly, but in case BINARY\_DIR where the project gets built such workaround doesn’t work.

Is there a reason for not supporting generator expressions for external project directories? Am I using external projects incorrectly?

My motivation is that using “Visual Studio” generator executables get placed in directory that depends on Config (Release or Debug). I want to install the dlls from external project in the same directory so that development build can be run.

---

<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:** [March 16, 2020, 12:15pm UTC](https://discourse.cmake.org/t/generator-expressions-in-external-projects/805/2 "2020-03-16T12:15:04Z")

</div>

I think that may be something that just hasn’t come up yet. Which error message are you getting?

As for a workaround, you may be able to use `$(Configuration)` which ends up letting MSBuild do the replacement (it only works for the VS generators though).

---

<div class="post-metadata">

**Author:** ![karliss](https://discourse.cmake.org/user_avatar/discourse.cmake.org/karliss/32/428_2.png) [@karliss](https://discourse.cmake.org/u/karliss)\
**Post date:** [June 13, 2020, 6:09am UTC](https://discourse.cmake.org/t/generator-expressions-in-external-projects/805/3 "2020-06-13T06:09:16Z")

</div>

Error looks something like this. It happens during configuration.

```
CMake Error at C:/Program Files/CMake/share/cmake-3.17/Modules/ExternalProject.cmake:1713 (message):
  dir 'C:/Users/karlis/source/repos/cutter/build/$<CONFIG>' does not exist
  after file(MAKE_DIRECTORY)
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.17/Modules/ExternalProject.cmake:3223 (_ep_set_directories)
  cmake/BundledRadare2.cmake:29 (ExternalProject_Add)

```

At least during my first attempt I wasn’t able to repeat it on Linux. I wonder if it succeeds on Linux by actually creating directory with “$\<\>” symbols in the path.

---

<div class="post-metadata">

**Author:** ![karliss](https://discourse.cmake.org/user_avatar/discourse.cmake.org/karliss/32/428_2.png) [@karliss](https://discourse.cmake.org/u/karliss)\
**Post date:** [June 13, 2020, 6:28am UTC](https://discourse.cmake.org/t/generator-expressions-in-external-projects/805/4 "2020-06-13T06:28:55Z")

</div>

Yes, on Linux it creates directory called `$<CONFIG>` later during build creates the corresponding directory with `$<CONFIG>` correctly substituted.

---

<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:** [June 14, 2020, 2:20am UTC](https://discourse.cmake.org/t/generator-expressions-in-external-projects/805/5 "2020-06-14T02:20:37Z")

</div>

`file(MAKE_DIRECTORY)` is a configure-time action and does not support generator expressions. If you do `file(GENERATE OUTPUT "dir/with/$<CONFIG>/.dummy" CONTENT "")`, CMake will generate the directory that way (though you’ll be stuck with the `.dummy` placeholder files).

---

<div class="post-metadata">

**Author:** ![d3x0r](https://discourse.cmake.org/user_avatar/discourse.cmake.org/d3x0r/32/3550_2.png) [@d3x0r](https://discourse.cmake.org/u/d3x0r)\
**Post date:** [June 23, 2023, 5:38am UTC](https://discourse.cmake.org/t/generator-expressions-in-external-projects/805/6 "2023-06-23T05:38:19Z")

</div>

I ran into this same issue… switched to use and that directory can’t be made…(Windows doesn’t allow \< and \> in filenames). $(Configuration) almost works, but I’d really like to have it indirected into the generated .sln files.

cmake\_all/CMakeLists.txt generates builds for several sub-projects within the same source tree. for $(Configuration)\_out The sub-projects then get Debug\_out, but only when the top-level is re-generated; I would like to work with the projects generated directly, and have them have $(Configuration) in their setup; otherwise when I build a subproject with Release it still goes to Debug\_out. I tried like $$(Configuration) but then I get $Debug\_out as the target (for example)… so even if worked, I’d want to pass that to the target projects and have it resolved when they are built.

I do get a $(Configuration)\_out directory created which is empty - not sure why external project is even trying to make this directory, since the install part will handle creation of the directory anyway.

Actually - seems the install\_prefix gets stuck with whatever the first build generated…
