# INTERFACE IMPORTED header-only library not recognized by target\_include\_directories

**URL:** https://discourse.cmake.org/t/interface-imported-header-only-library-not-recognized-by-target-include-directories/15785
**Category:** Code
**Created:** [August 13, 2026, 6:42am UTC](https://discourse.cmake.org/t/interface-imported-header-only-library-not-recognized-by-target-include-directories/15785 "2026-08-13T06:42:24Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![MarkCallow](https://discourse.cmake.org/user_avatar/discourse.cmake.org/markcallow/32/4823_2.png) [@MarkCallow](https://discourse.cmake.org/u/MarkCallow)
#### Post date: [August 13, 2026, 6:42am UTC](https://discourse.cmake.org/t/interface-imported-header-only-library-not-recognized-by-target-include-directories/15785/1 "2026-08-13T06:42:25Z")

</div>

I am creating an INTERFACE IMPORTED header-only library whose name, `Vulkan::Headers`, I add in a `target_include_directories` command but `target_include_directories` is treating it as a relative path name. Here are the details. I have two CMake files (edited to the essentials for brevity).

`vulkanhaders.cmake`

```cmake
if(DEFINED ENV{VULKAN_SDK})
    find_path(DFDUtils_Vulkan_INCLUDE_DIR
    NAMES
        vulkan/vulkan.h
    HINTS
        $ENV{VULKAN_SDK}/include
    REQUIRED
    )
else()
    message(FATAL_ERROR "VULKAN_SDK not defined")
endif()

if(NOT TARGET Vulkan::Headers)
    add_library(Vulkan::Headers INTERFACE IMPORTED)
    set_target_properties(Vulkan::Headers
    PROPERTIES
        INTERFACE_INCLUDE_DIRECTORIES "${DFDUtils_Vulkan_INCLUDE_DIR}"
    )
endif()

```

`CMakeLists.txt`

```cmake
cmake_minimum_required(VERSION 3.23)
project(dfdutils C)

include(GNUInstallDirs) # Must be after project.
include(CMakePrintHelpers)

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)

include(vulkanheaders.cmake)

set(DFDUTILS_LINK_TYPE STATIC)
if(DFDUTILS_EMBED)
    set(DFDUTILS_LINK_TYPE OBJECT)
endif()

#
# --- DFD Utils library ---
#
add_library(dfdutils ${DFDUTILS_LINK_TYPE}
    createdfd.c
    colourspaces.c
    dfd.h
    interpretdfd.c
    KHR/khr_df.h
    printdfd.c
    queries.c
    vk2dfd.c
    dfd2vk.c
)

get_target_property(vulkan_headers Vulkan::Headers INTERFACE_INCLUDE_DIRECTORIES)
cmake_print_variables(vulkan_headers DFDUtils_Vulkan_INCLUDE_DIR)
target_include_directories(dfdutils
PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}
INTERFACE
    Vulkan::Headers)

get_target_property(include_dirs dfdutils INCLUDE_DIRECTORIES)
cmake_print_variables(include_dirs)
get_target_property(interface_include_dirs dfdutils INTERFACE_INCLUDE_DIRECTORIES)
cmake_print_variables(interface_include_dirs)

# Remainder of file removed.

```

Here is the output of config showing the values of the variables being printed

```auto
vulkan_headers="/Users/mark/VulkanSDK/1.4.357.0/macOS/include" ; DFDUtils_Vulkan_INCLUDE_DIR="/Users/mark/VulkanSDK/1.4.357.0/macOS/include"
include_dirs="/Users/mark/Projects/khronos/github/dfdutils;/Users/mark/Projects/khronos/github/dfdutils/Vulkan::Headers"
interface_include_dirs="/Users/mark/Projects/khronos/github/dfdutils;/Users/mark/Projects/khronos/github/dfdutils/Vulkan::Headers"
Configuring done (0.1s)

```

As you can see, `target_include_directories` doesn’t recognize `Vulkan::Headers` as a library, thinks it is a relative path and prepends `${CMAKE_CURRENT_SOURCE_DIR}` to it.

I can’t see what I am doing wrong, probably something stupid so I am looking for help. The documentation for `target_include_directories` does not show this usage but I have seen it in practice many times and use it myself in other projects such as when adding SDL3::Headers, which is created by a config file for finding SDL3. As far as I can see the way I am creating the INTERFACE IMPORT library is the same as used in various config and find modules that I have looked at.

---

<div class="post-metadata">

### Author: ![retif](https://discourse.cmake.org/user_avatar/discourse.cmake.org/retif/32/1776_2.png) [@retif](https://discourse.cmake.org/u/retif)
#### Post date: [August 13, 2026, 7:50am UTC](https://discourse.cmake.org/t/interface-imported-header-only-library-not-recognized-by-target-include-directories/15785/2 "2026-08-13T07:50:21Z")

</div>

I might have misunderstood your intention, but from what I see here, you are probably confusing `target_include_directories()` with `target_link_libraries()`, meaning that you need to link to the target:

```diff
 target_include_directories(dfdutils
 PUBLIC
     ${CMAKE_CURRENT_SOURCE_DIR}
-INTERFACE
- Vulkan::Headers)
+)
+
+target_link_libraries(dfdutils
+ PRIVATE
+ Vulkan::Headers
+)

```

---

<div class="post-metadata">

### Author: ![MarkCallow](https://discourse.cmake.org/user_avatar/discourse.cmake.org/markcallow/32/4823_2.png) [@MarkCallow](https://discourse.cmake.org/u/MarkCallow)
#### Post date: [August 13, 2026, 10:03am UTC](https://discourse.cmake.org/t/interface-imported-header-only-library-not-recognized-by-target-include-directories/15785/3 "2026-08-13T10:03:33Z")

</div>

Ahh! I tried that first but with `INTERFACE` and it did not work. With either `PRIVATE` or `PUBLIC` the include directory appears in System Headers in the Xcode project and the build works. Thank you for the hint @retif. Now I have to look at the places in my other projects where I am passing, e.g. SDL3::Headers, to `target_include_directories`to see if I should remove them.

---

<div class="post-metadata">

### Author: ![ferdnyc](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ferdnyc/32/267_2.png) [@ferdnyc](https://discourse.cmake.org/u/ferdnyc)
#### Post date: [August 25, 2026, 6:20am UTC](https://discourse.cmake.org/t/interface-imported-header-only-library-not-recognized-by-target-include-directories/15785/4 "2026-08-25T06:20:28Z")

</div>

Yeah, you almost never want to use `INTERFACE` when _consuming_ a target, as it will be stored as a “pass-along” dependency that doesn’t apply to the _current_ target, but only others that consume it.

What I mean is:

```cmake
# If you have a library target
add_library(mylib ${mylib_SOURCES})

# And you give it any INTERFACE properties
target_link_libraries(mylib INTERFACE
  SomeImported::Dependency
)
target_include_directories(mylib INTERFACE
  ${SOME_INCLUDE_PATH}
)

```

…Then that dependency target, or that include path, will NOT be used when _building_ `mylib`, but only when `mylib` is linked to some other target with `target_link_libraries(... [PUBLIC|PRIVATE] mylib)`. (`PUBLIC` basically means “`PRIVATE` + `INTERFACE`”, meaning the dependency will be used _both_ when building the current target _and_ when it’s used by other targets.)
