# add\_library() for header-only c++ target... again

**URL:** https://discourse.cmake.org/t/add-library-for-header-only-c-target-again/9363
**Category:** Usage
**Created:** [November 4, 2023, 2:04pm UTC](https://discourse.cmake.org/t/add-library-for-header-only-c-target-again/9363 "2023-11-04T14:04:29Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![DanilShe](https://discourse.cmake.org/user_avatar/discourse.cmake.org/danilshe/32/3984_2.png) [@DanilShe](https://discourse.cmake.org/u/DanilShe)
#### Post date: [November 4, 2023, 2:04pm UTC](https://discourse.cmake.org/t/add-library-for-header-only-c-target-again/9363/1 "2023-11-04T14:04:29Z")

</div>

Hello!

I’m trying to make a header-only target in my c++ project.

Environment: MSVC 2019, CMake 3.20 bundled with MSVC, c++ 20, WIndows 10

Here is a sample structure of my project:

```auto
/proj/common/CMakeLists.txt
/proj/common/Common.h
/proj/src/main.cpp
/proj/dll/CMakeLists.txt
/proj/dll/dll.cpp
/proj/CMakeLists.txt

```

Both main.cpp and dll.cpp use Common.h: #include \<Common.h\>.  
/proj/common/CMakeLists.txt contents are like said in most examples:

```auto
add_library(common_headers INTERFACE)

target_include_directories(common_headers 
    INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> 
              $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

```

Now, when I’m referring common\_headers target in /proj/CMakeLists.txt like this:

```auto
add_executable( main WIN32 src/main.cpp)
target_link_libraries(main common_headers dll)

```

everything compiling fine. No erros.  
But, when I try to reference the targets a different way (pointet by a CMake docs btw):

```auto
add_executable( main WIN32 src/main.cpp)
target_link_libraries(main 
   INTERFACE common_headers 
   PRIVATE dll
)

```

I get a compiler error in main.cpp “Unknown header Common.h”  
Could someone please explain finally a correct way of doing a header-only targets in CMake? Because literally half of an examples on this topic I found in google does not work in my case.

---

<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: [November 4, 2023, 3:08pm UTC](https://discourse.cmake.org/t/add-library-for-header-only-c-target-again/9363/2 "2023-11-04T15:08:51Z")

</div>

You specified the wrong keyword for the compilation of target main.  
The `INTERFACE` keyword means that consumers of the `main` target will be allowed to use the `common_headers` target, but it is not available for the `main` target itself. To ensure the `main` target can use the `common_headers` target, the keyword `PRIVATE` or `PUBLIC` must be used (`PUBLIC` is a synthetic way to specify the target for both `PRIVATE` and `INTERFACE`).

In your case, I think you can use `PRIVATE` keyword for both targets:

```cmake
add_executable( main WIN32 src/main.cpp)
target_link_libraries(main PRIVATE common_headers dll)

```

---

<div class="post-metadata">

### Author: ![DanilShe](https://discourse.cmake.org/user_avatar/discourse.cmake.org/danilshe/32/3984_2.png) [@DanilShe](https://discourse.cmake.org/u/DanilShe)
#### Post date: [November 5, 2023, 3:33pm UTC](https://discourse.cmake.org/t/add-library-for-header-only-c-target-again/9363/3 "2023-11-05T15:33:35Z")

</div>

Thank you!

The usage specifics of these keywords was not obvious for me.
