I stumbled into this property while looking at generated export sets and I’m curious what it is used for exactly.

@ben.boeckel helpfully pointed me at commit 2cff26fa52cf9043f00d1efaaf31ab93e2db22e8 added by @brad.king in the C++ Slack, and he suggested that I ask about this here. (Slack)

My understanding of transitive dependency propagation prior to this was that I only needed to find_dependency private dependencies in the install interface when the project was built with BUILD_SHARED_LIBS=0. From the linked commit and the discussion on Slack it looks like I have to always find_dependency everything to be truly cross-platform in my install interfaces.

This helps CMake generate -rpath-link flags to tell the linker where to find runtime dependencies of a shared library.

I see. So this isn’t just a Darwin thing. Would I be correct to assume then that adding find_dependency in the install interface should be unconditional for dependencies that were found using find_package during build and linked to PRIVATEly? If we consider a 100% cross-platform scenario that is and just let CMake do the thing it’s good at.

Yes, though in many cases the -rpath-link flag (or equivalent on another platform, if any) is not actually needed because the dependency’s libraries are installed in directories that the linker searches anyway. Many projects don’t bother. The code here just ignores entries of IMPORTED_LINK_DEPENDENT_LIBRARIES that cannot be found.


For completeness’ sake, here is an SO answer describing the importance of -rpath-link: linker - What's the difference between `-rpath-link` and `-L`? - Stack Overflow

It’s also more correct to unconditionally find_dependency private dependencies whose targets you depend on.

I recently hit upon a related problem in that I had (manually) created my imported library targets A and B and needed target_link_libraries(A PRIVATE B) to work because my executable was failing to link without a computed -rpath-link. But of course, it doesn’t work currently because A is an imported target. It would have helped if it just populated IMPORTED_LINK_DEPENDENT_LIBRARIES instead of failing. Instead, I had to write my own wrapper to do this manually instead.

It would be nice if there was a warning when imported targets have dependencies in IMPORTED_LINK_DEPENDENT_LIBRARIES but the targets do not exist.
But that’s tracked in