[CMake] third party library dependencies

Marcel Loose loose at astron.nl
Mon Dec 21 09:20:24 EST 2009


On Mon, 2009-12-21 at 14:43 +0100, Michael Wild wrote:
> On 21. Dec, 2009, at 14:16 , Marcel Loose wrote:
> 
> > On Mon, 2009-12-21 at 13:32 +0100, Michael Wild wrote:
> >> On 21. Dec, 2009, at 12:17 , Marcel Loose wrote:
> >> 
> >>> On Fri, 2009-12-18 at 08:54 -0800, Jed Brown wrote:
> >>>> On Fri, 18 Dec 2009 10:19:05 +0100, "Marcel Loose" <loose at astron.nl> wrote:
> >>>>> Hi Roman,
> >>>>> 
> >>>>> Not in a portable way. I'm not too familiar with Windows, but on Linux
> >>>>> you can do this when libA is a shared library that has its dependency on
> >>>>> libB linked in (e.g. ldd libA.so will tell you this). When linking in
> >>>>> static libraries you're out of luck. 
> >>>> 
> >>>> With shared libraries, you need not and *should not* explicitly link
> >>>> recursive dependencies.  If you have both static and shared libraries,
> >>>> the output of ldd could be used to find the recursive deps needed to
> >>>> link statically.  This sucks and the logic to determine whether to put
> >>>> recursive deps in FOO_LIBRARIES ends up going in FindFoo.cmake which is
> >>>> insane.  FWIW, pkg-config has Libs.private for this purpose.
> >>>> 
> >>>> Finally, it would be nice to easily associate a symbol with a call to
> >>>> find_library.  That is, suppose libA links to libB and libC, but libA
> >>>> never exposes libB or libC to users.  To do the right thing (without
> >>>> abusing ldd), FindA.cmake needs to try linking with just -lA (which will
> >>>> work with all shared libs), then try with -lA -lB and -lA -lC before
> >>>> falling back to -lA -lB -lC (which is required when all libs are
> >>>> static).  A better way which does not have exponential complexity would
> >>>> be to declare that the symbol "B_Foo" belongs with a libB and "C_Bar"
> >>>> belongs with a libC.  So when linking with -lA fails, libB would be
> >>>> added exactly when B_Foo is undefined.
> >>>> 
> >>>> Jed
> >>> 
> >>> Hi Jed,
> >>> 
> >>> Why do you consider explicit linking of recursive dependencies a bad
> >>> thing? It's superfluous, I agree, but there's no harm in it, right?
> >>> 
> >>> Best regards,
> >>> Marcel Loose.
> >>> 
> >> 
> >> It's called overlinking and can be a real problem for package maintainers. See e.g. here for an explanation: http://wiki.mandriva.com/en/Overlinking
> >> 
> >> Michael
> >> 
> > 
> > OK, I see.
> > 
> > This raises another question, which was already alluded to in this
> > thread, and may have been asked before on this list:
> > 
> > Is there a way to write FindXXX.cmake macros in such a way that they
> > will always return the correct list of libraries to link against? I.e.,
> > a short list of direct dependencies when linking against shared
> > libraries, and a long complete list of recursive dependencies when
> > linking against static libraries.
> > 
> > Best regards,
> > Marcel Loose.
> 
> I honestly don't know. I wouldn't even know how to reliably differentiate between static and dynamic libraries. AFAIK some platforms use the same naming scheme, e.g. Windows uses .lib for both, static libraries and import libraries. AIX distinguishes between shared objects (really, only an object file with shared code) and shared libraries. The former either uses .o or .so (who had THIS great idea), while shared libraries use .a as do static libraries. Very confusing: http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=/com.ibm.vacpp7a.doc/getstart/overview/port_aix_obj_lib.htm
> 
> Perhaps we need some new IF(STATIC_LIBRARY <filename>) command? But then that would probably require a database with file detection magic (such as Unix file(1) command uses)
> 
> Michael

Hi Michael, and others,

Upon (re)reading the Mandriva page you were referring to, I was
thinking: maybe this issue can be solved more or less the same way as
pkg-config does: i.e. by defining private dependencies. This could be an
extra option to target_link_libraries. Something like:

  target_link_libraries(mylib public1 public2 PRIVATE private1 private2)

This would tell CMake that mylib directly depends on public1 and public2
and should *only* link in these two libraries when these are shared
object libraries; otherwise private1 and private2 would also need to be
added on the link line.

The big hurdle to take, of course, is to detect in a
platform-independent way whether the given library is shared or static.
However, a lot of this knowledge is already available in the diverse
Modules/Platform macros, so my feeling is that this should be feasible.

Best regards,
Marcel Loose.





More information about the CMake mailing list