using `install()` with EXPORT and COMPONENT

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

using `install()` with EXPORT and COMPONENT

Stefan Seefeld

Hello,

I'm working on a library project that will be packaged in multiple components. A "runtime" component will contain the (shared) library, an a "dev" component the associated headers (and perhaps other development-only artefacts).

I have successfully used the `install()` command to install these two sets of artefacts, i.e. calling `install(... COMPONENT runtime)`, as well as `install(... COMPONENT dev)`.

However, I'm now looking into calling `install(TARGETS ... EXPORT ...)`. The documentation explains how the list of installed headerfiles can actually be inferred from the target itself (if the target_include_directories have been appropriately set). However, I can't call that function more than once on the same target, and thus I seem to have no way to split the installation into multiple components.

Does anyone know what I'm missing ? What is the suggested way to package a project into the usual "runtime" and "dev" components ?

Many thanks,

Stefan
-- 

      ...ich hab' noch einen Koffer in Berlin...

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: using `install()` with EXPORT and COMPONENT

Craig Scott-3


On Sun, Sep 29, 2019 at 6:38 AM Stefan Seefeld <[hidden email]> wrote:

Hello,

I'm working on a library project that will be packaged in multiple components. A "runtime" component will contain the (shared) library, an a "dev" component the associated headers (and perhaps other development-only artefacts).

I have successfully used the `install()` command to install these two sets of artefacts, i.e. calling `install(... COMPONENT runtime)`, as well as `install(... COMPONENT dev)`.

However, I'm now looking into calling `install(TARGETS ... EXPORT ...)`. The documentation explains how the list of installed headerfiles can actually be inferred from the target itself (if the target_include_directories have been appropriately set). However, I can't call that function more than once on the same target, and thus I seem to have no way to split the installation into multiple components.

Does anyone know what I'm missing ? What is the suggested way to package a project into the usual "runtime" and "dev" components ?


If all of your headers should be installed to a single directory, then you can list the headers in the target's PUBLIC_HEADER or PRIVATE_HEADER target property, then make sure you add those destinations in the install(TARGETS ...) command. For example:

include(GNUInstallDirs)
install(TARGETS myLib
    EXPORT SomeProj_Targets
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
            COMPONENT SomeProj_Runtime
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
            COMPONENT          SomeProj_Runtime
            NAMELINK_COMPONENT SomeProj_Development   # Requires CMake 3.12
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
            COMPONENT SomeProj_Development
    PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
            COMPONENT SomeProj_Development
    INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

If you need to install headers into more than one directory (i.e. your headers have some sort of directory hierarchy), then the above doesn't work because it flattens all of the headers into a single location. Instead, you have to use install(FILES ...) to install the headers directly for such cases. Also, the target_include_directories() command has nothing to do with what header files get installed. Rather, it only controls the header search paths attached to a target.

FYI, part of my CppCon talk "Deep CMake For Library Authors" from a couple of weeks ago has a fair amount of overlap with this topic (specifically install components and destinations). I'm waiting for the YouTube clip to be made available and then I'll be posting a blog article on my website with links and the slides. When it goes up, you'll be able to find it at https://crascit.com (hopefully sometime this week, but depends how quickly the production people get the video done).


--
Craig Scott
Melbourne, Australia

Get the hand-book for every CMake user: Professional CMake: A Practical Guide
Consulting services (CMake, C++, build/release processes): https://crascit.com/services

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

.signature.png (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: using `install()` with EXPORT and COMPONENT

Stefan Seefeld

Hi Craig,

thanks for the detailed explanation !

On 2019-09-29 5:13 a.m., Craig Scott wrote:

If all of your headers should be installed to a single directory, then you can list the headers in the target's PUBLIC_HEADER or PRIVATE_HEADER target property, then make sure you add those destinations in the install(TARGETS ...) command. For example:

include(GNUInstallDirs)
install(TARGETS myLib
    EXPORT SomeProj_Targets
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
            COMPONENT SomeProj_Runtime
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
            COMPONENT          SomeProj_Runtime
            NAMELINK_COMPONENT SomeProj_Development   # Requires CMake 3.12
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
            COMPONENT SomeProj_Development
    PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
            COMPONENT SomeProj_Development
    INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

I hadn't noticed one can have multiple 'COMPONENT' sections in a single `install` call. The CMake documentation could be a bit more clear about that.


If you need to install headers into more than one directory (i.e. your headers have some sort of directory hierarchy), then the above doesn't work because it flattens all of the headers into a single location. Instead, you have to use install(FILES ...) to install the headers directly for such cases. Also, the target_include_directories() command has nothing to do with what header files get installed. Rather, it only controls the header search paths attached to a target.

Right, true.

FYI, part of my CppCon talk "Deep CMake For Library Authors" from a couple of weeks ago has a fair amount of overlap with this topic (specifically install components and destinations). I'm waiting for the YouTube clip to be made available and then I'll be posting a blog article on my website with links and the slides. When it goes up, you'll be able to find it at https://crascit.com (hopefully sometime this week, but depends how quickly the production people get the video done).

Great, looking forward to reading the slides.

Many thanks !

Stefan
-- 

      ...ich hab' noch einen Koffer in Berlin...

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: using `install()` with EXPORT and COMPONENT

Craig Scott-3


On Mon, Sep 30, 2019 at 4:09 AM Stefan Seefeld <[hidden email]> wrote:

Hi Craig,

thanks for the detailed explanation !

On 2019-09-29 5:13 a.m., Craig Scott wrote:

If all of your headers should be installed to a single directory, then you can list the headers in the target's PUBLIC_HEADER or PRIVATE_HEADER target property, then make sure you add those destinations in the install(TARGETS ...) command. For example:

include(GNUInstallDirs)
install(TARGETS myLib
    EXPORT SomeProj_Targets
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
            COMPONENT SomeProj_Runtime
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
            COMPONENT          SomeProj_Runtime
            NAMELINK_COMPONENT SomeProj_Development   # Requires CMake 3.12
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
            COMPONENT SomeProj_Development
    PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
            COMPONENT SomeProj_Development
    INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

I hadn't noticed one can have multiple 'COMPONENT' sections in a single `install` call. The CMake documentation could be a bit more clear about that.


If you need to install headers into more than one directory (i.e. your headers have some sort of directory hierarchy), then the above doesn't work because it flattens all of the headers into a single location. Instead, you have to use install(FILES ...) to install the headers directly for such cases. Also, the target_include_directories() command has nothing to do with what header files get installed. Rather, it only controls the header search paths attached to a target.

Right, true.

FYI, part of my CppCon talk "Deep CMake For Library Authors" from a couple of weeks ago has a fair amount of overlap with this topic (specifically install components and destinations). I'm waiting for the YouTube clip to be made available and then I'll be posting a blog article on my website with links and the slides. When it goes up, you'll be able to find it at https://crascit.com (hopefully sometime this week, but depends how quickly the production people get the video done).

Great, looking forward to reading the slides.


The CppCon talk and slides are now available. You can find them here:


--
Craig Scott
Melbourne, Australia

Get the hand-book for every CMake user: Professional CMake: A Practical Guide
Consulting services (CMake, C++, build/release processes): https://crascit.com/services

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake