# INTERFACE library not getting installed and no error reported

**URL:** https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185
**Category:** Usage
**Tags:** os:linux
**Created:** [November 17, 2020, 2:46am UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185 "2020-11-17T02:46:04Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [November 17, 2020, 2:46am UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/1 "2020-11-17T02:46:04Z")

</div>

After INTERFACE (header only library) is added with add\_library and setting of INTERFACE for BUILD\_INTERFACE and INSTALL\_INTERFACE with target\_include\_directories, followed by install(TARGETS EXPORT and install(EXPORTS (see details below), the INTERFACE library is not installed. There were generated and configuration and generation phases completed successfully. Then make install passed fine but INTERFACE library was not installed.  
It could be installed directly via install(DIRECTORY but that is not acceptable method. Attempts to get it installed as a dependent library to main mylib SHARED library also did not succeed.  
Could you please advise how this should be done.

EXPECTED RESULTS:  
${ARCHITECTURE}/myintlib/include DIR is created

ACTUAL RESULTS  
no ${ARCHITECTURE}/myintlib/include DIR is created

CODE FLOW:

```cmake
add_library(myintlib INTERFACE) 
target_include_directories(myintlib
    INTERFACE
        $<BUILD_INTERFACE:${IMPORTED_LOCATION_ROOT}/include>
        $<INSTALL_INTERFACE:${ARCHITECTURE}/myintlib/include>  
)

target_link_libraries(mylib ...
        myintlib
)

install(TARGETS myintlib 
    EXPORT ${proj_targets_export_name}         
    CONFIGURATIONS ${CMAKE_BUILD_TYPE}
    INCLUDES DESTINATION ${CMAKE_INSTALL_PREFIX}/myintlib/include
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

install(EXPORT ${proj_targets_export_name}
      DESTINATION "${CONFIG_INSTALL_DIR}"
      FILE ${proj_targets_export_filename}  
      COMPONENT ${PROJECT_NAME}_Development
)

```

Note: the `builtTargets` obtained as `get_directory_property(builtTargets BUILDSYSTEM_TARGETS)` lists `mintlib`

---

<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: [November 17, 2020, 1:13pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/2 "2020-11-17T13:13:04Z")

</div>

What are you expecting to happen vs. what you’re seeing? Is `myintlib` mentioned in the installed `-targets.cmake` file?

---

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [November 17, 2020, 3:37pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/3 "2020-11-17T15:37:24Z")

</div>

expected results- ${ARCHITECTURE}/myintlib/include DIR is created and this is not happening.  
Other non-INTERFACE (SHARED or STATIC) libraries (e.g. add\_library(xyzlib SHARED) and main mylib) are installed properly. The myTarget.cmake (proj\_targets\_export\_name) file does contain commands to import myintlib:

```auto
# Create imported target myintlib
 add_library(myintlib INTERFACE IMPORTED) , set_target_properties(myintlib PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/.../myintlib/;....myintlib/include"
)

```

and lists myintlib in INTERFACE\_LINK\_LIBRARIES property of mylib as normal

---

<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: [November 17, 2020, 4:25pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/4 "2020-11-17T16:25:06Z")

</div>

Hmm. I’ve not used `HEADERS DESTINATION` myself. Maybe this is an oversight?

Cc: @kyle.edwards @craig.scott

---

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [November 17, 2020, 4:35pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/5 "2020-11-17T16:35:40Z")

</div>

> [@ben.boeckel](#):
>
> HEADERS DESTINATION

What do you mean by that? Do you call “headers-only-library” as HEADERS? That would correspond to cmake INTERFACE library. So are you doubting that cmake 3.17 I use actually supports installation of INTERFACE library despite documentation indications?

---

<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: [November 17, 2020, 5:23pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/6 "2020-11-17T17:23:36Z")

</div>

I’ve used `INTERFACE` libraries, but I haven’t used `HEADERS DESTINATION` to install the headers. I’ve used `install(FILES)` for a while (mainly out of habit).

---

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [November 17, 2020, 5:30pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/7 "2020-11-17T17:30:48Z")

</div>

> [@ben.boeckel](#):
>
> HEADERS DESTINATION

I have not used “HEADERS DESTINATION” either so I assume you meant INCLUDES DESTINATION ${CMAKE\_INSTALL\_PREFIX}/myintlib/include. Or maybe you meant " PUBLIC\_HEADER DESTINATION …include" ? Then would not I need to use PUBLIC, not INTERFAC Ein the add\_library? The approach with install(FILES…) works but I want to use modern cmake approach with referencing only targets and setting their properties. So could you please check with Craig?

---

<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: [November 17, 2020, 6:04pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/8 "2020-11-17T18:04:43Z")

</div>

D’oh. Yes, `INCLUDES DESTINATION`. Sorry. Obviously I haven’t used this codepath myself much 🙂 .

---

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [November 17, 2020, 6:46pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/9 "2020-11-17T18:46:59Z")

</div>

NP, is theere a way to to contact other cmake developers on this? Thank you.

---

<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: [November 17, 2020, 7:03pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/10 "2020-11-17T19:03:15Z")

</div>

I’ve pinged them above. I don’t know their schedules though.

---

<div class="post-metadata">

### Author: ![friendlyanon](https://discourse.cmake.org/user_avatar/discourse.cmake.org/friendlyanon/32/970_2.png) [@friendlyanon](https://discourse.cmake.org/u/friendlyanon)
#### Post date: [November 23, 2020, 4:06pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/11 "2020-11-23T16:06:57Z")

</div>

You aren’t specifying an install rule to copy the include folder. You can take this project for a working example: [KonanM/tser](https://github.com/KonanM/tser/blob/fb477b1c2c5f1ce95b21875e51fab21944972998/CMakeLists.txt#L25-L56)

---

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [November 23, 2020, 6:11pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/12 "2020-11-23T18:11:31Z")

</div>

Thank you for looking into this, but the install rule for include folder is specified in the statement “INCLUDES DESTINATION” see lines above

> Blockquote

install(TARGETS myintlib  
…  
INCLUDES DESTINATION ${CMAKE\_INSTALL\_PREFIX}/myintlib/include

> Blockquote  
> The sample project you referring to uses the same statement, so the question is why the installation got blocked

---

<div class="post-metadata">

### Author: ![friendlyanon](https://discourse.cmake.org/user_avatar/discourse.cmake.org/friendlyanon/32/970_2.png) [@friendlyanon](https://discourse.cmake.org/u/friendlyanon)
#### Post date: [November 23, 2020, 10:44pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/13 "2020-11-23T22:44:51Z")

</div>

`INCLUDES DESTINATION` is a special form that populates the `INTERFACE_INCLUDE_DIRECTORIES` property of the target(s) in the generated targets file. Obviously, there has to be something where that path is pointing to. See lines 55 and 56.

---

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [November 24, 2020, 6:10pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/14 "2020-11-24T18:10:47Z")

</div>

> [@yisseamake](#):
>
> ${CMAKE\_INSTALL\_PREFIX}/myintlib/include

Yes it is and it is present as per my issue description and path ${CMAKE\_INSTALL\_PREFIX}/myintlib/include is a valid path. Again as I mentioned before when installing from the same path using install(DIRECTORY ) it gets installed fine.Your example [KonnaM/tser](https://github.com/KonanM/tser/blob/fb477b1c2c5f1ce95b21875e51fab21944972998/CMakeLists.txt#L25-L56) illustrate the problem as it uses ` install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/" DESTINATION "${tser_include_directory}")` direct install instead of modern cmake approach using targets only. install(TARGETS …), install(EXPORTS…) should be sufficient to install target with its INCLUDE directory. This works fine for non INTERFACE targets (SHARED or STATIC) and should be working without use of install(DIRECTORY). So could you please use your own example to investigate the issue? Thanks

---

<div class="post-metadata">

### Author: ![friendlyanon](https://discourse.cmake.org/user_avatar/discourse.cmake.org/friendlyanon/32/970_2.png) [@friendlyanon](https://discourse.cmake.org/u/friendlyanon)
#### Post date: [November 24, 2020, 8:50pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/15 "2020-11-24T20:50:57Z")

</div>

You seem to be mixing things up a lot. The repository in question **is** using modern CMake techniques.  
You might want to either sink your teeth into the documentation or buy Craig Scott’s book.

---

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [December 2, 2020, 5:25pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/16 "2020-12-02T17:25:25Z")

</div>

probably, I did buy Craigs book. Can you be more specific (reference to book chapter)? The issue is that i expected install(TARGETS target …) would install files that are associated with the target via its properties without the need to install(FILES …)for theses files

---

<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: [December 2, 2020, 10:15pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/17 "2020-12-02T22:15:51Z")

</div>

There’s two main ways to install headers. You can either attach details to a target and have them install as part of that target (which is what it sounds like you are expecting and wanting to do) or you can install them separately as ordinary files. There are pros and cons for either approach.

To attach headers to a target, you use the `PUBLIC_HEADER` and `PRIVATE_HEADER` target properties. Then when you install a target, you specify where you want these headers to be installed to.

```cmake
add_library(MyLibOrFramework SHARED
    foo.cpp
    foo.h
    foo_privateA.h
    nested/foo_privateB.h
)

set_target_properties(MyLibOrFramework PROPERTIES
    FRAMEWORK TRUE
    PUBLIC_HEADER foo.h
    PRIVATE_HEADER "foo_privateA.h;nested/foo_privateB.h"
)

install(TARGETS MyLibOrFramework
    FRAMEWORK # Apple framework case
        DESTINATION ...
    LIBRARY # Non-Apple case
        DESTINATION ...
    PUBLIC_HEADER
        DESTINATION include/MyProj # (A)
    PRIVATE_HEADER
        DESTINATION include/MyProj/private... # (B)
 )

```

Specify at `(A)` where public headers should be installed (relative to the install base directory) and at `(B)` the location for private headers. I made them different in this case, but they could be the same location. It would be up to you to ensure that your public headers can find any private headers they need.

The main reason for the separation of public and private headers comes from Apple framework structure, which has distinct standard locations for both. On other platforms, there usually isn’t such a distinction made.

Since you asked for references in my Professional CMake book, the above example is combining and slightly modifying examples from _Section 23.3.3: Headers_ (which talks about Apple frameworks) and _Section 26.2.3 Apple-specific Targets_ (which shows how to install those headers on non-Apple platforms).

A limitation of specifying public and private headers via target properties is that it assumes your headers have a flat directory structure. You can’t use this method if your headers need to preserve some kind of directory structure, or more specifically that some headers need to go in different directories to others (apart from the public/private separation). For example, you couldn’t reproduce the following public headers:

```auto
include/MyProj/coolthings.h
include/MyProj/Algorithms/specialsauce.h

```

In this case, you have to use the other method for installing headers, which is to manually do it via `install(FILES)` or `install(DIRECTORY)`. Then you have complete control over where headers are installed to and can specify whatever directory structure you want. Both the CMake docs and the Professional CMake book include an example like the following for one way to do that, but you can use whatever way fits your needs:

```cmake
install(DIRECTORY src/
    DESTINATION include/MyProj
    FILES_MATCHING
    PATTERN *.h
)

```

Personally, unless I’m working specifically on an Apple framework target, I tend to use the manual form because of the need to control the directory structure. For an Apple-only project though, the target property form would probably make more sense.

---

<div class="post-metadata">

### Author: ![yisseamake](https://discourse.cmake.org/user_avatar/discourse.cmake.org/yisseamake/32/897_2.png) [@yisseamake](https://discourse.cmake.org/u/yisseamake)
#### Post date: [December 2, 2020, 11:10pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/18 "2020-12-02T23:10:57Z")

</div>

Yes, Great that is exactly what I meant - installing headers without use of install(FILES or DIRECTORIES, thank you. So now you could see why I am reporting cmake issue. While all works fine per your example, when SHARED is replaced by INTERFACE the headers are not being installed. Such limitation for INTERFACE libraries was not documented . So despite calling install(TARGETS we had to use install(FILES or DIRECTORIES. So first could you please confirm that cmake shall supports installing INTERFACE libraries or point to any limitation int the book or documentation?  
Secondly, why the limitation of flat include directory exists? cmake is able to configure build with INTERFACE library with non-flat include structure and installation with EXPORT merely exports build tree to install path. cmake could have installed to directory specified by PUBLIC\_HEADERS with all its subdirectories as a default. So why cmake is having problem with this install ?

---

<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: [December 2, 2020, 11:41pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/19 "2020-12-02T23:41:35Z")

</div>

An INTERFACE library was originally only intended as a way of collecting usage requirements, not collecting files to be installed along with the target. Before CMake 3.19, attaching files to an interface library was only meaningful for making files show up in IDEs. There was never an expectation that those files would be installed. Now that CMake 3.19 allows sources to be attached to interface libraries, this might be less clear-cut. @brad.king I’m wondering if it makes sense for interface libraries to now honour the `PUBLIC_HEADERS` and `PRIVATE_HEADERS` target properties and install destinations?

Regarding why the flat directory structure limitation, consider how would you specify the location of every header otherwise? There is only one destination that can be specified in an `install(TARGETS)` call for each of public or private headers, but you can have arbitrarily many headers with an arbitrarily complex directory structure. There are subsets of scenarios that may be tractable (e.g. preserve structure below some specific directory), but they have deficiencies that don’t support general flexibility (e.g. what if headers are not all under a common base point with the directory structure you want when installed?).

---

<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: [December 3, 2020, 2:55pm UTC](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185/20 "2020-12-03T14:55:49Z")

</div>

> [@craig.scott](#):
>
> (e.g. what if headers are not all under a common base point with the directory structure you want when installed?).

These kinds of corner cases always come to mind when I realize install logic tends to flatten things in CMake. However, I think just raising an error for anything not under `${CMAKE_CURRENT_SOURCE_DIR}`, `${CMAKE_CURRENT_BINARY_DIR}`, or any other potential “ROOT\_PATHS” arguments would be a hard error.

So we could have something like:

```cmake
install(FILES
  ${header_list}
  PRESERVE_HIERARCHY
  ROOT_PATHS # current source and binary are implicit, up for discussion though
    ${some_other_prefix})

```

[Next page](https://discourse.cmake.org/t/interface-library-not-getting-installed-and-no-error-reported/2185.md?page=2)
