How to use `export` command together with `target_include_directories`?

tl;dr: How am I supposed to export the include search-path containing a target’s public headers when using the export command?


I thought about trying to use the export command for a library target mylib in order to not have to install the library before using it.

export( TARGETS mylib myotherObjectLib FILE mylib-config.cmake )

In general, this works, however…


As libraries very often have some public header files, containing the public API of the library, I thought it would be useful to set the include search-directory (and thereby export it as well):

target_include_directories( mylib INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include" )

However, this results in CMake complaining:

CMake Error in CMakeLists.txt:
  Target "mylib" INTERFACE_INCLUDE_DIRECTORIES property contains path:

    "/home/user/workspace/source/include"

  which is prefixed in the source directory.

OK… then I maybe try the build-directory instead:

target_include_directories( mylib INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/include" )

However, this again results in a CMake error:

CMake Error in CMakeLists.txt:
  Target "mylib" INTERFACE_INCLUDE_DIRECTORIES property contains path:

    "/home/user/workspace/build/include"

  which is prefixed in the build directory.

Uhhm… skipping the variable prefix maybe?

target_include_directories( mylib INTERFACE "include" )

CMake:

CMake Error in CMakeLists.txt:
  Target "mylib" INTERFACE_INCLUDE_DIRECTORIES property contains path:

    "/home/user/workspace/source/include"

  which is prefixed in the source directory.

:confused: :question: … How about I use some other absolute path neither prefixed with the source or build directory?

target_include_directories( mylib INTERFACE "/tmp/installed/include" )

CMake: “Yes, I like that.”

:eyes: :face_with_spiral_eyes:
Whaaat? I thought the idea behind export was that there is no need for the library to be “installed” outside the build-directory?

On a side-note: As expected, the private build-dependency from mylib to the OBJECT target myotherObjectLib is also exported (which is expected because CMake told me I have to do so), but interestingly its include search path, which is prefixed with the source directory, is exported just fine in the resulting mylib-config.cmake.

You should wrap build-tree paths in $<BUILD_INTERFACE>. The install is complaining that it’s going to generate paths to the source tree and will end up breaking the install tree once it is relocated to another machine.