How to collect and export usage-requirements of dependencies?

Hi everyone,

I am currently writing a CMakeLists.txt and am trying to export a single target from it that shall carry all its usage-requirements, even the indirectly inherited ones, without the need to also export its (built) dependencies.
Is there some elegant way to achieve that?

As examples are always easier to understand, my CMakeLists.txt looks pretty much like this:


# Carries include-search path for own headers and Boost headers.
add_library( some_interface INTERFACE )
target_include_directories( some_interface INTERFACE include )
target_link_libraries( some_objects INTERFACE Boost::headers )
install( DIRECTORY include/ TYPE INCLUDE )

# Object-files for MyLib with public dependency to INTERFACE lib.
add_library( some_objects OBJECTS )
target_sources( some_objects PRIVATE a.cpp b.cpp )
target_link_libraries( some_objects PUBLIC some_interface )

# Object-files for MyLib with private dependency to some Boost lib.
add_library( some_other_objects OBJECTS )
target_sources( some_other_objects PRIVATE c.cpp dcpp )
target_link_libraries( some_other_objects PRIVATE Boost::regex )

# The shared library that shall be exported.
add_library( MyLib SHARED)
target_link_libraries( MyLib

install( TARGETS MyLib
  EXPORT MyLib-ExportSet
install( EXPORT MyLib-ExportSet
  DESTINATION lib/cmake

I hope the example is understandable.
Currently, when trying to install it fails with an error which says that some_objects and some_other_objects are required but not in any export-set.

What I now want is to build MyLib and export it so that it can be used as IMPORTED library target later and still carries the required usage-requirements, although the other targets are not exported. (You can see these other targets as implementation details that should not be of any interest to the user of my exported target.) In particular that means, MyLib should carry the dependency to Boost::headers and to the include search path for the installed headers but not to some_objects, some_other_objects or some_interface.

So, in other words: From the (non-IMPORTED) targets that I defined in my CMakeLists.txt I only want MyLib exported with all its (inherited) usage-requirements.

Does anyone know some elegant way to collect these usage-requirements and to apply them to MyLib.
Or does anyone have an idea how such a feature could look like when implemented as new feature for CMake itself?

Thanks in advance for any pointers.

I don’t think there’s an elegant and future-proof way to do this. You can manually copy all of the usage requirements down using generator expressions, but if a new usage requirement is added, you’ll need to also add that one in the future.

For now, you’ll just have to export all of your targets. You can use EXPORT_NAME to mangle them to something users wouldn’t necessarily think to use directly. Only documenting the supported target should also help.

You will need to find_package all IMPORTED targets again in your -config.cmake file (since they may live somewhere else once the project is installed).