That has been supported since CMake 3.15. It was added by CMake MR 3181.
The first-class INTERFACE library support in CMake 3.19 was added by CMake MR 5078, and includes a test for PUBLIC_HEADER
installation here and here.
That has been supported since CMake 3.15. It was added by CMake MR 3181.
The first-class INTERFACE library support in CMake 3.19 was added by CMake MR 5078, and includes a test for PUBLIC_HEADER
installation here and here.
So this example demonstrates that cmake supports INTERFACE library installation in the same way as STATIC or SHARED library installation of its headers via install(TARGETS headergenâŚ) without use of install(FILESâŚ) is supported. However there is only one header file in headergen (and it is generated by cmake so it knows all its properties). So could you please advise on the following:
Should cmake support INTERFACE library install via install(TARGETS ⌠PUBLIC_HEADER DESTINATION installIncludeDir) without direct FILES/DIRECTORIES install for libraries that have their header files under a) a Directory with sub-directories or b) a list of directories or c) a list of files. It seems documentation does not preclude such possibilities by using plurals âthese headersâ or âheader filesâ. I assume in case of a) this would result in installation of library inlcude directory under installIncludeDir.
Could PUBLIC_HEADER be set to include all INTERFACE library files (cases above) not by explicit set_property(TARGET headergen PROPERTY PUBLIC_HEADER..publicHdrDir)
or set_target_property listing all INTERFACE library files, but via other target properties since cmake gets all INTERFACE library files passed within the add_library or via INTERFACE_INCLUDE_DIRECTORIES and settings of "$<BUILD_INTERFACE:...." and "$<INSTALL_INTERFACE: ..."
?
Does @brad.king example require 3.19 as minimum or 3.17 would support the above functionality? Why is the condition âif they have sourcesâ? Which Sources? I assume interface library is a collection of source code /header files under 1 directory in simple case.
In @brad.king example, why the headeronly INTERFACE library headeronly_headers installed directly via FILES but not via TARGETS? `install(TARGETS headeronlyâŚ) ?
Thanks, Iâd forgotten about those MRs adding support for this for interface libs.
Yes, although I might be misinterpreting what you mean in (a) and (b). The PUBLIC_HEADER target property accepts a list of files, you cannot put directory names in there (if it does work, thatâs by chance and isnât meant to be supported). All of the files, regardless of their source directory structure, will be installed into a single directory which you specify in the install(TARGETS)
command.
No, CMake has no way to know whether the source files added to the interface library via add_library()
or target_sources()
should go in PUBLIC_HEADER
or PRIVATE_HEADER
. A potential enhancement might be to have PUBLIC_HEADER
and PRIVATE_HEADER
support generator expressions. That would then allow you to at least do something like the following if it made sense for your particular project:
set_target_properties(SomeTarget PROPERTIES
# Not currently supported, this property doesn't yet support generator expressions.
PUBLIC_HEADER "$<TARGET_PROPERTY:SOURCES>"
)
CMake 3.15 provides the minimum capabilities you need for using PUBLIC_HEADER
and PRIVATE_HEADER
to install headers when installing an interface library using install(TARGETS)
. The other CMake 3.19 links Brad provided relate to adding files as sources to an interface target and that target then showing up as a target in the build system. Your use case doesnât seem to need that.
As for âWhy the condition âif they have sourcesâ? Which Sources?â, this refers to whether any sources have been added to the interface library via add_library()
or target_sources()
. If every interface library was added as a build system target regardless of whether it had any such sources or not, there may be lots of targets showing up in IDEs, etc. that the user really isnât interested in. But if an interface library has sources attached to it, then there may be some build rules associated with it (to generate the sources) and that means it is a genuine target that will build something. Or the sources might just be attached to make them show up in an IDE and again, that means you want it to show as a build system target so the sources have a target to sit under.
Why cant cmake use INTERFACE_INCLUDE_DIRECTORIES property which give list of of dirs set by target_include_directories and other commands?
How would that help determine whether public.h
should be installed and private.h
should not?
Well, files maching header extensions (there are âonlyâ a dozen in use these days) at least . Currently it seems that PRIVATE_HEADER
only applies to FRAMEWORK
targets. Expanding its semantics would require a code change (and my gut says a policy as well).
but cmake man page reads âOn non-Apple platforms these headers may be installed using the PRIVATE_HEADER
option to the install(TARGETS)
command.â
Also recall that only INTERFACE library are having issue with not being installed, so which mechanism is used for installing export SHARED or STATIC libs? What sis preventing from using it as cmake creates all build files for the build with INTERFACE library?
Any updates @ben.boeckel
I can agree that INTERFACE
libraries not installing their INTERFACE_INCLUDE_DIRECTORIES
automagically is very confusing. Even more so for a chain of interface libraries depending on one another, some of which can be imported. Not only I need to manually copy destination directory, I also need to find all dependencies and copy their headers too. When dependencies are conditional it makes it even harder.
@ben.boeckel , reading about FILE_SET it feels like it is something which can help here, but I do not yet understand how
@yisseamake , I have tested new FILE_SET feature and it seems to be doing exactly what you wanted. It both populates INTERFACE_INCLUDE_DIRECTORIES with BUILD_INTERFACE-like value and installs them on install(TARGETS ... )
Great. Thank you Maxim @redbaron, which version will it be available ? I am still on 3.17 and upgrade validation of our projects with newer version goes painfully slow
File sets are a new feature added in CMake 3.23.0