Search code examples
cmakeincludeinstallationinclude-path

Do I really need to specify install-interface includes dependencies?


In a package of mine, I currently have:

include(GNUInstallDirs)
target_include_directories(
    mylib
    PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> # ***
)

and also:

install(
  TARGETS mylib
  EXPORT mylib
  RUNTIME DESTINATION  "${CMAKE_INSTALL_BINDIR}"
  ARCHIVE DESTINATION  "${CMAKE_INSTALL_LIBDIR}"
  LIBRARY DESTINATION  "${CMAKE_INSTALL_LIBDIR}"
  INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" 
)

install(
  EXPORT mylib
  FILE "mylib-config.cmake"
  NAMESPACE mylib::
  DESTINATION "lib/cmake/mylib" )

and I notice that in the installed config.cmake file, I see the include directory twice:

set_target_properties(mylib::mylib PROPERTIES
  # etc. etc.
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include;${_IMPORT_PREFIX}/include"
)

So, as an experiment, I dropped the line marked *** above - and the config file now has the include directory only once.

So, is doing this safe? That is, Do I really not need to specify install-interface include directories if I install a target with the INCLUDES parameter? Or - am I missing something?


Solution

  • Documentation clearly states that both target_include_directories command with non-PRIVATE keyword and INCLUDES DESTINATION clause for install command populates INTERFACE_INCLUDE_DIRECTORIES property.

    It is up to you which method to use.

    Note, that same target can be installed several times. target_include_directories affects on all installations, but INCLUDES DESTINATION affects only on a specific installation.


    Documentation for INCLUDES DESTINATION clause:

    This option specifies a list of directories which will be added to the INTERFACE_INCLUDE_DIRECTORIES target property of the <targets> when exported by the install(EXPORT) command. If a relative path is specified, it is treated as relative to the $<INSTALL_PREFIX>.

    Documentation for target_include_directories:

    PUBLIC and INTERFACE items will populate the INTERFACE_INCLUDE_DIRECTORIES property of <target>.