0

I want to pull all symbols from a static library (libyaml-cpp) into a shared one that I'm building (libLHAPDF), to avoid an explicit dependency for users of the latter. (It's not my favourite way to do things, but the difficulty of installing the prerequisite was a regular negative feedback about the package.) So I try to build the relevant bit of my shared library with an automake rule like this:

libLHAPDFInfo_la_LDFLAGS = $(AM_LDFLAGS) \
  $(srcdir)/yamlcpp/yaml-cpp/libyaml-cpp.a

I specifically want something like this rather than

libLHAPDFInfo_la_LDFLAGS = -L$(srcdir)/yamlcpp/yaml-cpp -lyaml-cpp \
  $(AM_LDFLAGS) 

because there could be a shared lib version of libyaml-cpp installed elsewhere on the system, and I don't want to use it. (The odd flag ordering in that latter case is an attempt to make sure that -lyaml-cpp finds the one built in the srcdir... and yes it really is srcdir and not builddir in this case!)

However, the first version gives a warning that I'd rather not have:

*** Warning: Linking the shared library libLHAPDFInfo.la against the
*** static library ./yamlcpp/yaml-cpp/libyaml-cpp.a is not portable!

and more importantly it doesn't actually work: if I run nm on the generated library I see undefined symbols:

$ nm src/.libs/libLHAPDFInfo.a | grep YAML
U _ZN11LHAPDF_YAML4NodeC1Ev
U _ZN11LHAPDF_YAML4NodeD1Ev
...

(Details: libLHAPDFInfo.a is a noinst_LTLIBRARIES entry used as an intermediate to building the final shared lib. So this doesn't even work when linking one static lib against another. And to avoid symbol clashes, the bundled version is slightly hacked to rename the YAML namespace to LHAPDF_YAML: that doesn't change anything, but I thought I'd mention it just in case those symbol names seem strange to you.)

If I use the second form of the link flags (the -lyaml-cpp way), I get all the LHAPDF_YAML symbols in libLHAPDFInfo.a and thereafter into the shared library. And there is no longer any warning about non-portability of the static library linking (which was built with -fPIC, so it is valid to do this). But if a shared libyaml-cpp is also found on the system, it gets used regardless of the -L/-l flag ordering -- which I don't want.

Any suggestions of how I can make sure that the version of the library at a particular path will be used, while getting the symbols correctly copied across and avoiding libtool warnings?

EDIT: Having said that I could get symbols copied from libyaml-cpp.a into libLHAPDFInfo.a via the -lyaml-cpp flag, after more iterations I could no longer get this approach to show the expected symbols via nm. Looking at the ar/ranlib commands executed by libtool when making libLHAPDFInfo.a, the -l arguments seem to get completely dropped. So I don't know how it ever worked... as far as I can tell it's just not a mode that libtool supports, not that that is documented. In the end I renamed libyaml-cpp to liblhapdf-yaml-cpp.a as part of the build (since no lib with that name should be found accidentally), and linked that into the final shared libLHAPDF.so rather than the static convenience lib. Not as neat as I'd have liked -- I was hoping to isolate all the yaml-cpp dependency handling into the build of one convenience lib, and relying on file copies to disambiguate library lookup is unsatisfying -- but it works.

andybuckley
  • 1,114
  • 2
  • 11
  • 24
  • >But if a shared libyaml-cpp is also found on the system, it gets used regardless of the -L/-l flag ordering – ldav1s Dec 21 '13 at 19:01
  • @ldav1s Did something go missing from your comment? Or do you mean that that *is* the libtool behaviour: any reference for that? In the end I worked around the problem by inserting a native make rule to rename the bundled static lib to a guaranteed unique name, and linked it into the final shared lib rather than the static convenience lib. But it would have been nice to a) use the abs path to the bundled static lib, and b) pull its symbols into the convenience lib. – andybuckley Dec 27 '13 at 10:44
  • something went missing. [According to this answer](http://stackoverflow.com/questions/5817269/does-the-order-of-l-and-l-options-in-the-gnu-linker-matter) paths inserted by `-L` are searched before any default directories, so some variation of your second definition of `libLHAPDFInfo_la_LDFLAGS` should work. – ldav1s Dec 27 '13 at 21:29
  • Aha, thanks for explaining! The one found accidentally on the system could be in the AM_LDFLAGS, but point taken. Anyway, -l arguments in LDFLAGS seem to get ignored by libtool when building static libs (at least for convenience libs), so something else had to be done. – andybuckley Dec 29 '13 at 10:41
  • A convenience lib is not a final linking step [by definition](http://www.gnu.org/software/automake/manual/html_node/Libtool-Convenience-Libraries.html), so it's not surprising that `-l` arguments are dropped there. – ldav1s Dec 29 '13 at 23:24

0 Answers0