# FILE(COPY header\_set) or file\_set

**URL:** https://discourse.cmake.org/t/file-copy-header-set-or-file-set/7282
**Category:** Code
**Created:** [January 19, 2023, 7:28pm UTC](https://discourse.cmake.org/t/file-copy-header-set-or-file-set/7282 "2023-01-19T19:28:31Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![jk000](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jk000/32/3097_2.png) [@jk000](https://discourse.cmake.org/u/jk000)
#### Post date: [January 19, 2023, 7:28pm UTC](https://discourse.cmake.org/t/file-copy-header-set-or-file-set/7282/1 "2023-01-19T19:28:31Z")

</div>

It would be useful to be able to copy a file\_set to the build tree so other targets could depend on it.

In the case where header files are installed in a specific directory layout different from the source tree, this would enable other targets to properly #include based on this layout.

[https://gitlab.kitware.com/cmake/cmake/-/issues/24341](https://gitlab.kitware.com/cmake/cmake/-/issues/24341) was closed, so I’d like to discuss how to achieve this.

File\_set works great to take header files from the project, remove base\_dirs, and install in a certain destination in the install directory. I have other files in my project that include the public headers both based on their install path, and based on their source tree path (it’s a mix). Ultimately I’d like to create a target that can use target\_include\_directory on the file\_set based on the install path. Currently, it doesn’t seem possible to do this without copying the file\_set to the build tree, which seems also isn’t possible.

I can’t change the directory structure for this project; is the only way to run configure\_file on each header to copy it to the build tree?

---

<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: [January 19, 2023, 7:49pm UTC](https://discourse.cmake.org/t/file-copy-header-set-or-file-set/7282/2 "2023-01-19T19:49:29Z")

</div>

> [@jk000](#):
>
> I can’t change the directory structure for this project; is the only way to run configure\_file on each header to copy it to the build tree?

Yeah, pretty much. Note that doing this means that the _copy_ gets reported for warnings, errors, or “go to declaration” when using an editor to look for things. Editing these usually ends up poorly because it doesn’t end up where it _should_: in the copy’s source path. I’m a pretty big believer in “make the build tree look like the install tree”, but copying headers and (installed) source files has just caused more headaches than it’s worth IME.

---

<div class="post-metadata">

### Author: ![jk000](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jk000/32/3097_2.png) [@jk000](https://discourse.cmake.org/u/jk000)
#### Post date: [January 21, 2023, 4:04pm UTC](https://discourse.cmake.org/t/file-copy-header-set-or-file-set/7282/3 "2023-01-21T16:04:20Z")

</div>

Thanks for the response. I ended up creating the desired public header directory structure in the build tree first, by using `execute_process` with the CMake command `create_hardlink` on each file. It was then extremely simple to create a file\_set from those 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: [January 22, 2023, 2:37am UTC](https://discourse.cmake.org/t/file-copy-header-set-or-file-set/7282/4 "2023-01-22T02:37:55Z")

</div>

Hardlinks could work (on platforms/filesystems that support it at least). Note that some editors do “write new file, rename to target file” when saving which will break hardlinks.

---

<div class="post-metadata">

### Author: ![ignus2](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ignus2/32/3075_2.png) [@ignus2](https://discourse.cmake.org/u/ignus2)
#### Post date: [January 23, 2023, 12:30am UTC](https://discourse.cmake.org/t/file-copy-header-set-or-file-set/7282/5 "2023-01-23T00:30:36Z")

</div>

Instead of a copy you can do a reference to the original, with a configure file something like:  
header\_template.in

```auto
// This file is generated by CMake. Do not edit.
#include "@HEADER_FILE_LOCATION@"

```

Then given headerpath among your sources:

```auto
get_filename_component(headername ${headerpath} NAME)
get_filename_component(HEADER_FILE_LOCATION ${headerpath} ABSOLUTE)
configure_file(header_template.in ${CMAKE_BINARY_DIR}/yoursubdir/${headername})

```
