# How to install export target with INSTALL\_INTERFACE

**URL:** <https://discourse.cmake.org/t/how-to-install-export-target-with-install-interface/5293>\
**Category:** Code\
**Tags:** os:windows\
**Created:** [March 25, 2022, 9:05am UTC](https://discourse.cmake.org/t/how-to-install-export-target-with-install-interface/5293 "2022-03-25T09:05:08Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![tooEarlyForThis](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/t/8c91f0/32.png) [@tooEarlyForThis](https://discourse.cmake.org/u/tooEarlyForThis)\
**Post date:** [March 25, 2022, 9:05am UTC](https://discourse.cmake.org/t/how-to-install-export-target-with-install-interface/5293/1 "2022-03-25T09:05:08Z")

</div>

Having worked with CMake for some time, it is now time to create my first exported library. I followed the guides in the documentation ([https://cmake.org/cmake/help/latest/guide/importing-exporting/index.html](https://cmake.org/cmake/help/latest/guide/importing-exporting/index.html) and others), but I ran into some troubles, which I hope you can help me resolve.

The project contains of several libraries, one of them should be published. The project file structure looks something like this:

```auto
myProject
 |- CMakeLists.txt
 |- myLib
 | |- CMakeLists.txt
 | |- FindMyLib.cmake
 | |- MyLib-config.cmake
 | |- include
 | | |- ... header files ...
 | |- src
 | | |- ... source files
 |- ... other libs, executables and tests

```

The CMakeLists.txt of myLib looks like this

```auto
include(GenerateExportHeader)
include(CMakePackageConfigHelpers)
# Library definition as used in myProject
add_library(myLib SHARED ${myLib_SOURCES})
target_link_libraries(myLib Qt5::Core Boost::headers)
target_include_directories(myLib 
    PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include;${CMAKE_CURRENT_BINARY_DIR}>
    INTERFACE $<INSTALL_INTERFACE:include>
)
generate_export_header(myLib
          EXPORT_MACRO_NAME MYLIB_SHARED_EXPORT
          EXPORT_FILE_NAME mylib_global.h
)
# For installation of the library
install(TARGETS myLib EXPORT myLibTargets
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)
install(DIRECTORY include/ DESTINATION ${MYLIB_INCLUDE_INSTALL_PATH})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mylib_global.h
  DESTINATION ${MYLIB_INCLUDE_INSTALL_PATH}/include
)
# Creating CMake package configuration files
set(ConfigPackageLocation ${MYLIB_LIB_INSTALL_PATH}/cmake/myLib)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/myLib-version.cmake
  VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}
  COMPATIBILITY SameMajorVersion
)
configure_package_config_file(MyLib-config.cmake.in MyLib-config.cmake
  INSTALL_DESTINATION ${MYLIB_LIB_INSTALL_PATH}
)
install(
  FILES
    ${CMAKE_CURRENT_BINARY_DIR}/MyLib-config.cmake
    ${CMAKE_CURRENT_BINARY_DIR}/MyLib-version.cmake
  DESTINATION ${ConfigPackageLocation}
)
export(TARGETS myLib NAMESPACE MyProject::
  FILE ${CMAKE_CURRENT_BINARY_DIR}/MyLibTargets.cmake
)
install(EXPORT MyLibTargets
  FILE MyLibTargets.cmake
  NAMESPACE MyProject::
  DESTINATION ${ConfigPackageLocation}
)

```

Without the package configuration part, the library builds and installs as expected into the wanted directory and is usable there (please forgive me if I made a typo when posting the reduced version here). I used PUBLIC for the include directories to build the library, because with INTERFACE, the directories were not used for building.  
Package-version file and package-config file are generated and installed as expected.

But, my issues start with the last two commands: the generated MyLibTargets.cmake file contains absolute paths to my source/build directory:

```auto
CMake Error in myLib/CMakeLists.txt:
  Target "myLib" INTERFACE_INCLUDE_DIRECTORIES property contains path:

    "C:/path/to/source/directory/myProject/myLib/"

  which is prefixed in the source directory.

```

According to the documentation, the use of `$<BUILD_INTERFACE:...>` and `$<INSTALL_INTERFACE:...>` should prevent exactly this issue. Looking into the generated MyLibTargets.cmake, I can see absolute paths for include directories as well as the libraries location (IMPORTED\_IMPLIB\_DEBUG in this case and IMPORTED\_LOCATION\_DEBUG).

Removing the `export(TARGETS...)` call gives a similar result. Still the `INTERFACE_INCLUDE_DIRECTORIES` property is set to the value I wanted to use for build, not the one for install. (I cleaned the build directory between when I commented the line; the generated MyLibTargets.cmake files are generated in different locations anyway).

In theory I can take the generated MyLibTargets.cmake file, correct the values and check it in into the repository. But I would like to use CMake’s generation to be compatible with future versions.

(Environment: Win10, CMake 3.21)

Any ideas?

---

<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:** [March 25, 2022, 10:19pm UTC](https://discourse.cmake.org/t/how-to-install-export-target-with-install-interface/5293/2 "2022-03-25T22:19:07Z")

</div>

I only scanned quickly, but one thing I noticed is you need to quote your generator expression to prevent the semicolon from splitting arguments. Try this instead:

```cmake
target_include_directories(myLib 
    PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include;${CMAKE_CURRENT_BINARY_DIR}>"
    INTERFACE $<INSTALL_INTERFACE:include>
)

```

---

<div class="post-metadata">

**Author:** ![tooEarlyForThis](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/t/8c91f0/32.png) [@tooEarlyForThis](https://discourse.cmake.org/u/tooEarlyForThis)\
**Post date:** [March 28, 2022, 7:14am UTC](https://discourse.cmake.org/t/how-to-install-export-target-with-install-interface/5293/3 "2022-03-28T07:14:01Z")

</div>

That actually did it. In some of the places I had the quotes already, but one was missing.

Thanks!
