# Generator expression $\<INSTALL\_PREFIX\> doesn't work with env variable DESTDIR

**URL:** https://discourse.cmake.org/t/generator-expression-install-prefix-doesnt-work-with-env-variable-destdir/15645
**Category:** Usage
**Tags:** os:linux
**Created:** [May 8, 2026, 2:09pm UTC](https://discourse.cmake.org/t/generator-expression-install-prefix-doesnt-work-with-env-variable-destdir/15645 "2026-05-08T14:09:11Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![jst\_mbs](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/j/51bf81/32.png) [@jst\_mbs](https://discourse.cmake.org/u/jst_mbs)
#### Post date: [May 8, 2026, 2:09pm UTC](https://discourse.cmake.org/t/generator-expression-install-prefix-doesnt-work-with-env-variable-destdir/15645/1 "2026-05-08T14:09:11Z")

</div>

Using the generator expression `$<INSTALL_PREFIX>` in `install(CODE )` should work with CMake 3.27 and later. But the generator expression doesn’t work with the enviroment variable `DESTDIR`. I don’t know if this is the intended behavior.

# Example

```CMake
cmake_minimum_required(VERSION 3.27)

project(install_code_bug)

install(CODE "file(TOUCH $<INSTALL_PREFIX>/test_file.txt)")

```

Configure the above project `cmake -B ./build -S ./ && mkdir install`.

Running `unset DESTDIR && cmake --install ./build --prefix "$(pwd)/install"` will result in file ‘install/test\_file.txt’ been created.

However, if `DESTDIR`is used like this `export DESTDIR="$(pwd)/install" && cmake --install ./build` it will result in an error:

```auto
CMake Error at build/cmake_install.cmake:46 (file):
  file problem touching file: /usr/local/test_file.txt

```

cmake version 3.31.6

OS: Ubuntu 25.10

---

<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: [May 8, 2026, 2:40pm UTC](https://discourse.cmake.org/t/generator-expression-install-prefix-doesnt-work-with-env-variable-destdir/15645/2 "2026-05-08T14:40:42Z")

</div>

`$ENV{DESTDIR}$<INSTALL_PREFIX>` is what you should use here.

---

<div class="post-metadata">

### Author: ![jst\_mbs](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/j/51bf81/32.png) [@jst\_mbs](https://discourse.cmake.org/u/jst_mbs)
#### Post date: [May 8, 2026, 2:52pm UTC](https://discourse.cmake.org/t/generator-expression-install-prefix-doesnt-work-with-env-variable-destdir/15645/3 "2026-05-08T14:52:31Z")

</div>

This only works if `DESTDIR` is set during configuration.

---

<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: [May 8, 2026, 7:21pm UTC](https://discourse.cmake.org/t/generator-expression-install-prefix-doesnt-work-with-env-variable-destdir/15645/4 "2026-05-08T19:21:05Z")

</div>

Yes, it’ll need the proper level of escaping to end up in the code as intended.

---

<div class="post-metadata">

### Author: ![jst\_mbs](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/j/51bf81/32.png) [@jst\_mbs](https://discourse.cmake.org/u/jst_mbs)
#### Post date: [May 12, 2026, 11:32am UTC](https://discourse.cmake.org/t/generator-expression-install-prefix-doesnt-work-with-env-variable-destdir/15645/5 "2026-05-12T11:32:21Z")

</div>

Thank you, yes, that works. I think I understand the underlying difference in the CMake install script between `file()` and `install` but isn’t it still error-prone that you have to write `\$ENV\\{DESTDIR\}$<INSTALL_PREFIX>` for `INSTALL(CODE …)` but not for `INSTALL(FILES …)`?

---

<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: [May 12, 2026, 2:51pm UTC](https://discourse.cmake.org/t/generator-expression-install-prefix-doesnt-work-with-env-variable-destdir/15645/6 "2026-05-12T14:51:21Z")

</div>

If escaping is a worry, you can use `install(SCRIPT)` instead. CMake generates the appropriate code to use `DESTDIR` itself for `install(FILES)`. CMake isn’t going to parse your `CODE` or `SCRIPT` to second guess your intent if you miss it yourself; the install prefix is something different from `DESTDIR` and knowing what the intent of any given `$<INSTALL_PREFIX>` usage is intended to be is beyond CMake’s scope.
