forexample/package-example

Missing include dir

Flamefire opened this issue · 6 comments

The examples are missing the include folder for the installed library

ruslo commented

What do you mean exactly?

Headers installed, see foo/Bar.hpp for example:

Ah sorry. When you install a target and then import that target via find_package it does not have its include directory property set because you don't set it in the CMakeLists:

"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/Source>"

You need to use INSTALL_INTERFACE generator expression to have it set for the installed target. In general: Where you use BUILD_INTERFACE you usually need the INSTALL_INTERFACE for the same.

You can try it: Install it into a random directory, e.g. /tmp/foo, add this to CMAKE_PREFIX_PATH then try to build against this with standard find_package and target_link_libraries where any source references a header from the installation. Or just check the generated target configs: No header path anywhere.

Side note:

# * header can be included by: `#include <BAR_EXPORT.h>`
is wrong: Should be #include <foo/BAR_EXPORT.h>

ruslo commented

When you install a target and then import that target via find_package it does not have its include directory property set

It's set here:

is wrong: Should be #include <foo/BAR_EXPORT.h>

Feel free to send pull request with fix, it's just an old comment

Intresting. So may I assume the INSTALL_INTERFACE for includes is superfluous and/or superseded by the INSTALL DESTINATION for the install(TARGETS command?

ruslo commented
INCLUDES DESTINATION

    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>.
$<INSTALL_INTERFACE:...>

    Content of ... when the property is exported using install(EXPORT), and empty otherwise.
The INTERFACE, PUBLIC and PRIVATE keywords are required to specify the scope of
the following arguments. PRIVATE and PUBLIC items will populate the
INCLUDE_DIRECTORIES property of <target>. PUBLIC and INTERFACE items will
populate the INTERFACE_INCLUDE_DIRECTORIES property of <target>.

I have not much to add :)

Ah I see the difference: INCLUDES DESTINATION will add it to ALL targets which may not be what is wanted. INSTALL_INTERFACE is more fine-grained.