# Using file sets for both public and private headers

**URL:** <https://discourse.cmake.org/t/using-file-sets-for-both-public-and-private-headers/10725>\
**Category:** Code\
**Created:** [April 23, 2024, 2:25pm UTC](https://discourse.cmake.org/t/using-file-sets-for-both-public-and-private-headers/10725 "2024-04-23T14:25:23Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![gracicot](https://discourse.cmake.org/user_avatar/discourse.cmake.org/gracicot/32/4525_2.png) [@gracicot](https://discourse.cmake.org/u/gracicot)\
**Post date:** [April 23, 2024, 2:25pm UTC](https://discourse.cmake.org/t/using-file-sets-for-both-public-and-private-headers/10725/1 "2024-04-23T14:25:23Z")

</div>

Hi! I tried using file sets for my project and I’m not sure how to proceed. I have public headers that I have inside `include/`, and some private headers in `src/`. I tried using file sets to describe both like so:

```auto
target_sources(mylib1
PRIVATE
  src/a.cpp
  src/b.cpp

PRIVATE FILE_SET HEADERS
  BASE_DIRS src
  FILES
    src/a_impl.hpp
    src/b_impl.hpp

PUBLIC FILE_SET HEADERS
  BASE_DIRS include
  FILES
    include/mylib1/a.hpp
    include/mylib1/b.hpp
)

```

However, doing so generates an error:

```auto
target_sources Scope PUBLIC for file set "HEADERS" does not match original
  scope PRIVATE

```

What would be the proper way to do this? I’m planning to install those private headers alongside modules and modules partitions.

---

<div class="post-metadata">

**Author:** ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)\
**Post date:** [April 23, 2024, 2:35pm UTC](https://discourse.cmake.org/t/using-file-sets-for-both-public-and-private-headers/10725/2 "2024-04-23T14:35:56Z")

</div>

a `FILE_SET` can have only **one** scope type (i.e. `PRIVATE`, `PUBLIC` or `INTERFACE`). You have to give unique names to your different file sets. Try the following:

```cmake
target_sources(mylib1
PRIVATE
  src/a.cpp
  src/b.cpp

PRIVATE FILE_SET private_headers TYPE HEADERS
  BASE_DIRS src
  FILES
    src/a_impl.hpp
    src/b_impl.hpp

PUBLIC FILE_SET public_headers TYPE HEADERS
  BASE_DIRS include
  FILES
    include/mylib1/a.hpp
    include/mylib1/b.hpp
)

```

---

<div class="post-metadata">

**Author:** ![gracicot](https://discourse.cmake.org/user_avatar/discourse.cmake.org/gracicot/32/4525_2.png) [@gracicot](https://discourse.cmake.org/u/gracicot)\
**Post date:** [April 23, 2024, 2:41pm UTC](https://discourse.cmake.org/t/using-file-sets-for-both-public-and-private-headers/10725/3 "2024-04-23T14:41:25Z")

</div>

It seems to work pretty well! To make them installable I have to put both file sets public, and install the two of them in (possibly) separate folder to let module units include them, but not make them visible in interface.
