# TARGET\_RUNTIME\_DLLS produces a malformed post-build copy command

**URL:** https://discourse.cmake.org/t/target-runtime-dlls-produces-a-malformed-post-build-copy-command/4398
**Category:** Code
**Tags:** os:windows
**Created:** [November 2, 2021, 12:43am UTC](https://discourse.cmake.org/t/target-runtime-dlls-produces-a-malformed-post-build-copy-command/4398 "2021-11-02T00:43:45Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Eugene](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/e/8797f3/32.png) [@Eugene](https://discourse.cmake.org/u/Eugene)
#### Post date: [November 2, 2021, 12:43am UTC](https://discourse.cmake.org/t/target-runtime-dlls-produces-a-malformed-post-build-copy-command/4398/1 "2021-11-02T00:43:45Z")

</div>

Let’s say I have two targets that I am working on Windows. Both of those targets include this CmakeLists.txt file as it is where the main executable is created for both of them. I use a visual studio generator for both of them.

```auto
cmake_minimum_required (VERSION 3.21)

project(min_proj CXX C)
add_executable(min_proj)

target_sources(min_proj
PRIVATE
  src/main.cpp

target_include_directories(min_proj
PRIVATE
  "src"
)
  
add_custom_command(TARGET min_proj POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:min_proj> $<TARGET_FILE_DIR:min_proj> 
  COMMAND_EXPAND_LISTS
)

```

One target has a dependency on some other external **my\_awesome.dll** library that is linked to the executable and is its runtime dependency. The other target is just standalone main.cpp

So what happens is that target with the external library dependency will build successfully while the other will build but will error out at a post-build step. The reason is that TARGET\_RUNTIME\_DLLS will evaluate to an empty string and CMake will try to use that empty string as an argument for a CMake post-build copy command and will fail since the command will look malformed.

The copy command will look like below which will miss the actual DLL file that is needed to be copied.  
Since there should be no DLL, I would expect that this post-build command should not even show up in the first place.

Error out log looks like this

```auto
Error MSB3073 ...
"C:\Program Files\CMake\bin\cmake.exe" -E copy .../single_target/build_folder/Debug

```

On the other target with dependency library

```auto
"C:\Program Files\CMake\bin\cmake.exe" -E copy my_awesome.dll .../single_target/build_folder/Debug

```

I think TARGET\_RUNTIME\_DLLS behaviour could be a bit more accommodative.  
Is this a bug or I am using this feature wrong?

---

<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: [November 2, 2021, 11:35am UTC](https://discourse.cmake.org/t/target-runtime-dlls-produces-a-malformed-post-build-copy-command/4398/2 "2021-11-02T11:35:01Z")

</div>

I think that `cmake -E copy` could have better syntax here. There is the `cp -t <dest>` flag which, if supported, would allow `cmake -E copy -t $<TARGET_FILE_DIR:exe> $<TARGET_RUNTIME_DLLS:exe>` which would work much better if the `DLLS` genex expands to nothing.

---

<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: [November 3, 2021, 3:58pm UTC](https://discourse.cmake.org/t/target-runtime-dlls-produces-a-malformed-post-build-copy-command/4398/3 "2021-11-03T15:58:00Z")

</div>

Note that the code example you have does not have any DLL dependencies, so it being empty is fine. I would first check that the imported targets you’re using actually know where their `.dll` file is (i.e., check the properties on the targets).

See also this issue:

[https://gitlab.kitware.com/cmake/cmake/-/issues/22845](https://gitlab.kitware.com/cmake/cmake/-/issues/22845)

---

<div class="post-metadata">

### Author: ![Eugene](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/e/8797f3/32.png) [@Eugene](https://discourse.cmake.org/u/Eugene)
#### Post date: [November 3, 2021, 4:53pm UTC](https://discourse.cmake.org/t/target-runtime-dlls-produces-a-malformed-post-build-copy-command/4398/4 "2021-11-03T16:53:34Z")

</div>

My ticket is just a simple example that I took from a big codebase.

What Robbert has reported is the same flavour of this error, and I agree with him is a bug.

---

<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: [November 4, 2021, 11:01am UTC](https://discourse.cmake.org/t/target-runtime-dlls-produces-a-malformed-post-build-copy-command/4398/5 "2021-11-04T11:01:08Z")

</div>

Sure, it could be improved (mainly be CMake providing better imported target utility bits myself). I’m just saying that there are times you’ll also actually have no dependencies and `-E copy` will fail.

---

<div class="post-metadata">

### Author: ![alex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/alex/32/125_2.png) [@alex](https://discourse.cmake.org/u/alex)
#### Post date: [May 22, 2022, 10:03pm UTC](https://discourse.cmake.org/t/target-runtime-dlls-produces-a-malformed-post-build-copy-command/4398/6 "2022-05-22T22:03:08Z")

</div>

Is there any plan to add this functionality? It seems easy and would really help simplify custom commands (even beyond this). I just bumped in to this exact issue today and wound up “fixing” it with an `if (WIN32)` check.

---

<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 23, 2022, 1:50pm UTC](https://discourse.cmake.org/t/target-runtime-dlls-produces-a-malformed-post-build-copy-command/4398/7 "2022-05-23T13:50:13Z")

</div>

I think an issue would be the first step. But a solution would be accepted. I think best would be to add a `-t <target dir>` flag to `cmake -E copy` so that an otherwise-empty list of arguments still makes sense. That signature can then be used to do this.

---

<div class="post-metadata">

### Author: ![alex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/alex/32/125_2.png) [@alex](https://discourse.cmake.org/u/alex)
#### Post date: [May 23, 2022, 6:48pm UTC](https://discourse.cmake.org/t/target-runtime-dlls-produces-a-malformed-post-build-copy-command/4398/8 "2022-05-23T18:48:03Z")

</div>

Thanks, I opened [https://gitlab.kitware.com/cmake/cmake/-/issues/23543](https://gitlab.kitware.com/cmake/cmake/-/issues/23543)
