# How can I install a custom target?

**URL:** https://discourse.cmake.org/t/how-can-i-install-a-custom-target/11340
**Category:** Usage
**Created:** [July 28, 2024, 6:33am UTC](https://discourse.cmake.org/t/how-can-i-install-a-custom-target/11340 "2024-07-28T06:33:15Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![cjdb](https://discourse.cmake.org/user_avatar/discourse.cmake.org/cjdb/32/4806_2.png) [@cjdb](https://discourse.cmake.org/u/cjdb)
#### Post date: [July 28, 2024, 6:33am UTC](https://discourse.cmake.org/t/how-can-i-install-a-custom-target/11340/1 "2024-07-28T06:33:15Z")

</div>

**tl;dr I want to run a tool that writes to a file during the install step, and then install that file. I can’t work out how to do this.**

I’d like to be able to install split debug info alongside my targets. [Improving C++ Builds with Split DWARF](https://www.productive-cpp.com/improving-cpp-builds-with-split-dwarf) gives a good overview of how to do this, but a quick summary is:

1. `clang++ -gsplit-dwarf -o target source.cpp` will produce `target.dwo`.
2. dwo files shouldn’t be installed for various reasons, so we need to run `llvm-dwp -e target` to produce `target.dwp`, which is an installable target.

I have an `add_custom_command` and `add_custom_target` that should produce a dwp file:

```cmake
# ${target} is a function parameter that has the add_(executable|library) target.
# ${DWP_EXECUTABLE} is either llvm-dwp or dwp, and set by Finddwp.cmake.
add_custom_command(
  OUTPUT $<TARGET_FILE:${target}>.dwp
  COMMAND "${DWP_EXECUTABLE}" -e $<TARGET_FILE:${target}>
  DEPENDS $<TARGET_FILE:${target}>
)
add_custom_target(
  _${target}.dwp
  DEPENDS $<TARGET_FILE:${target}>.dwp
)

```

The problem I’m facing is that I want this command to run only during the install step, because dwp files are only important for installed targets. It seems that custom targets can’t be installed using `install(TARGET)`, meaning that this doesn’t work:

```cmake
# ${directory} is whatever the corresponding target's GNUInstallDirs value
# would be.
install(
  TARGETS _${target}.dwp
  DESTINATION "${directory}"
  PERMISSIONS
    OWNER_READ OWNER_WRITE
    GROUP_READ
    WORLD_READ
)

```

Given that I only want `llvm-dwp` to run during the install step, I think this rules out turning my custom command into a post-build command and then use `install(FILES)`. It might be possible to run `install(SCRIPT)` or `install(CODE)` to achieve this, but that feels very heavy-handed for something that ought to be just installing a target.

What’s the best way to go about generating my dwp files at install time, and then installing them to the right directory?

---

<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: [July 28, 2024, 10:27pm UTC](https://discourse.cmake.org/t/how-can-i-install-a-custom-target/11340/2 "2024-07-28T22:27:33Z")

</div>

You don’t want to use a custom target for this. Targets are a build time thing, installs are completely separate. Don’t be fooled into thinking an install is still part of the build just because there’s an `install` build target. That isn’t really a proper build target in that it acts mostly just as a convenience wrapper for running the install. I normally recommend if people want to do an install, the more canonical way is to run `cmake --install /path/to/build/dir --prefix /where/you/want/to/install/to`. The install details are all contained in dedicated files in the build directory, completely separate from the build description in your `build.ninja`, `Makefile`, or whatever build system you’ve used.

For logic you want to run as part of an install, you should indeed be using `install(CODE)` or `install(SCRIPT)`.

---

<div class="post-metadata">

### Author: ![cjdb](https://discourse.cmake.org/user_avatar/discourse.cmake.org/cjdb/32/4806_2.png) [@cjdb](https://discourse.cmake.org/u/cjdb)
#### Post date: [July 29, 2024, 1:52am UTC](https://discourse.cmake.org/t/how-can-i-install-a-custom-target/11340/3 "2024-07-29T01:52:09Z")

</div>

Ah, that explains a lot, thank you! It also seems the `install(CODE)` that I need is much simpler than I thought (`execute_process`, not `add_custom_command` and `add_custom_target`).
