[CMake] Multiple exports for a target installation

Craig Scott craig.scott at crascit.com
Sat Jun 22 03:18:14 EDT 2019


On Tue, Jun 18, 2019 at 10:29 AM Shoaib Meenai <smeenai at fb.com> wrote:

> Thank you!
>
>
>
> When you say having an export set that the other exports then depend on,
> do you mean the COMPONENT option of the install(EXPORT) signature, or
> something else? (Sadly the project I’m working with is still on CMake
> 3.4.3, whose documentation says something very different for the COMPONENT
> option than the latest version, but I’ll cross that bridge when I get to
> it.)
>

As far as components and export sets are concerned, the behavior isn't much
different between CMake 3.4 and 3.14. Think of it like this:

   - The config file for a package (i.e. its <packageName>Config.cmake
   file) may refer to one or more export sets. It can do this in a way that
   some or all of the export sets are optional, pulling them in if present,
   silently continuing if not. It depends on the way the project wants to
   define and use its export sets. For most projects, they will require all
   export sets they refer to to be present. The optional components of a
   find_package() call might map to optional export sets (just one example of
   how optional export sets might be used).
   - An export set defines targets. That set of targets can span across one
   or more components. The export set requires all of those components to be
   installed/present or it is considered ill-formed (or put another way, the
   installation is incomplete). The install(TARGETS ... EXPORT ...) command
   determines what targets are in which export set. The install(EXPORT ...)
   command defines what component the actual export file is part of (further
   discussion on this below).
   - A component can include targets, files and custom scripts to be
   invoked when installing that component from a build tree. Targets and files
   can technically be part of multiple components, but this would be
   relatively uncommon and may complicate the export picture. A component may
   depend on one or more other components, e.g. a Development component may
   require a Runtime component, such as Development headers requiring the
   Runtime shared library.

If a project decides to split up its exports across multiple export sets,
there can be dependencies between them. For example, a project might define
export set Algo which has components Fast and Accurate, and export set Apps
which has components Gui and CLI. The project's <packageName>Config.cmake
file requires the Algo export set to be present but the Apps export set is
optional and only pulled in if present. In this scenario, one might have
the Fast and Accurate components installed, but not the Gui or CLI
components. The Algo export set represents the mandatory parts of the
package that will always be needed. The Gui and CLI components might not be
installed if, for example, someone just wants to build against the
libraries provided by the Fast and Accurate components (i.e. they are
writing their own apps rather than wanting to use the apps that are
provided by the Gui and CLI components).

What can be a bit confusing is that the exported file itself is also part
of a component. That exported file might or might not need to be installed,
depending on whether the project is being distributed as purely runtime
components or whether other projects might be building against it and
therefore expect headers, package config files, etc. The exported file
(which is installed by install(EXPORT ...) ) is only needed for the latter,
so it is usually part of a Development component or something similarly
named (hopefully named something project-specific rather than just a
generic "Development"!). The <packageName>Config.cmake file is also part of
a component, and may be part of the same component that the export file is
in.

The above is how I think about packages, export sets and components. You
could have more complicated arrangements and have some overlap between
export sets, but I'd generally try to avoid that if possible. It's simpler
if you can structure things with clear and unambiguous dependencies without
cycles or overlaps. It's already quite involved even without those things!

HTH



>
>
> *From: *Craig Scott <craig.scott at crascit.com>
> *Date: *Saturday, June 15, 2019 at 10:43 PM
> *To: *Shoaib Meenai <smeenai at fb.com>
> *Cc: *"cmake at cmake.org" <cmake at cmake.org>
> *Subject: *Re: [CMake] Multiple exports for a target installation
>
>
>
>
>
>
>
> On Sat, Jun 15, 2019 at 9:03 PM Shoaib Meenai <smeenai at fb.com> wrote:
>
> Is it possible to associate a target with multiple exports? For example,
> if I'm building a project where I want to create multiple export sets, but
> there's some overlap in targets between those sets. I tried passing
> multiple EXPORT options to the install(TARGETS) signature but I just got an
> error: install TARGETS given unknown argument "EXPORT".
>
>
> Typically, you'd want your export sets to not be overlapping and to
> contain no cyclic dependencies. If you have a target in multiple export
> sets, it suggests that you probably should factor out that target to a
> separate export set that other exports then depend on. That said, if you
> have a scenario that legitimately requires a target in multiple export
> sets, then you would need to use multiple install() commands to achieve
> this, specifying a different export set for each one.
>

-- 
Craig Scott
Melbourne, Australia
https://crascit.com

Get the hand-book for every CMake user: Professional CMake: A Practical
Guide <https://crascit.com/professional-cmake/>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20190622/5fe40dde/attachment-0001.html>


More information about the CMake mailing list