2

I have a shared object library (a python extension in C++) which includes several other archives, from a shared code base, which were wrapped in -Wl,whole-archive arhive1.a archive2.a ... -Wl,no-whole-archive in our former home-baked version of makefiles. Each archive was contained in its own subdirectory and was built as part of the ultimate goal of this python extension. I'm porting our build environment to using autoconf and automake.

In the Makefile.am relevant to the python extension, I have this (with extraneous stuff cut away):

pyexc_LTLIBRARIES = pyextension.la
ARCHIVE1_PATH = ../Path/to/.libs/   # built from another Makefile.am
ARCHIVE2_PATH = ../Path2/to/.libs/

pyextension_la_SOURCES = ...

pyextension_la_LDFLAGS = -lz -lrt -module ...
pyextension_la_LIBADD = $(ARCHIVE1_PATH)/archive1.a $(ARCHIVE2_PATH)/archive2.a
pyextension_la_CXXFLAGS = -std=c++0x -fPIC

All of this stuff comes out on the command line but it's not being packed correctly because when I import my pyextension module, I get undefined symbol errors from the archives that it's looking for. Originally, I had something like this for pyextension_LDFLAGS:

pyextension_la_LDFLAGS = -Wl,whole-archive $(ARCHIVE1_PATH)/archive1.a $(ARCHIVE2_PATH)/archive2.a -Wl,no-whole-archive -lz -lrt -module 

However, much to my surprise, when the final Makefile is processed by make, after running ./configure the options -Wl,whole-archive and -Wl,no-whole-archive appear in the command line but with nothing in between them(??) and the archive files listed elsewhere. So, I thought I should try the route of pyextension_la_LIBADD with the archives and the magic would work.

I'm not sure where to go from here. By the way, these other archive libraries will be installed with the rest as part of our deployment, but during build, they obviously aren't installed yet. So, any pointers on how to make this happen are much appreciated. I'm still an automake and autoconf neophyte.

Andrew Falanga
  • 2,274
  • 4
  • 26
  • 51
  • You shouldn't put _any_ libraries or options that control how specific libraries are linked in `LDFLAGS`: not `-lz -lrt` etc. either. `LDFLAGS` is _only_ for options that control the entire linker. The canonical example of an option that belongs in `LDFLAGS` is the `-L` option. All `-l` options, all options that depend on the order of flags, etc. belong in `LIBADD`. Also, I would assume that you need `-Wl,--whole-archive`, not `-Wl,whole-archive`, right? Or does the front-end add the `--` for you? – MadScientist Mar 03 '15 at 20:44
  • Remember that the linker is _highly_ sensitive to option ordering on the command line. It would be helpful if you posted a cut/paste of the link line for your shared library, so we could see it. – MadScientist Mar 03 '15 at 20:45
  • doh, I know that but, as I said, I'm a neophyte and forgot. I have changed to this `pyextension_la_LIBADD = -lz ...`. I tried to add my `-Wl,--whole-archive` there but received "shame on you" message from libtool that options like that should go in `_LDFLAGS`. So, I moved it back there , once again, I see nothing between `-Wl,--whole-archive -Wl,--no-whole-archive` even though I've placed them there in `Makefile.am`. – Andrew Falanga Mar 03 '15 at 22:21
  • Are you sure the message was from libtool? In any event, these flags _must not_ appear in `LDFLAGS`. Period. It won't work to put them there, regardless of libtool (or automake) says. They must appear in `LIBADD`. The tools will just have to suck it up. – MadScientist Mar 03 '15 at 22:44
  • So it would seem I'm at something of a catch 22 impasse. LDFLAGS isn't where this should list my archives, but these archive must be listed between the `--whole-archive` and `--no-whole-archive` options. However, automake has a conniption and says that I shouldn't use `-Wl,...` in _LIBADD. So, how exactly am I supposed to get this to work? – Andrew Falanga Mar 04 '15 at 17:37
  • Well, "has a conniption" and "shame on you message" isn't very specific. Are these warnings? Or does automake fail and refuse to generate a Makefile.in file? If it's just a warning you can just ignore it. Or, you can use automake options to turn off all checks: https://www.gnu.org/software/automake/manual/html_node/Options-generalities.html ; https://www.gnu.org/software/automake/manual/html_node/List-of-Automake-options.html ; https://www.gnu.org/software/automake/manual/html_node/automake-Invocation.html – MadScientist Mar 04 '15 at 17:58
  • I just changed to `AM_INIT_AUTOMAKE([foreign subdir-objects])` (I had `-Wall` and `-Werror` also). Still it won't make a Makefile.in. Stackoverflow recommended a chat. How exactly do we set that up? I did get the help and, for the first time, now know where the chat is. I couldn't find a room for automake though. – Andrew Falanga Mar 04 '15 at 20:21
  • Explicitly disable all warnings by adding `-Wnone`. If that doesn't help, I have no idea, so chatting with me won't help. In that case you should contact the automake folks by emailing the automake@gnu.org mailing list: autotools are old-school and use mailing lists for communication. To subscribe see https://lists.gnu.org/mailman/listinfo/automake/ – MadScientist Mar 04 '15 at 20:44

1 Answers1

0

You may be helped by the same thing that helped me here:

-Wl,--whole-archive,$(ARCHIVE1_PATH)/archive1.a,$(ARCHIVE2_PATH)/archive2.a,--no-whole-archive

Specifying multiple arguments with commas to one -Wl option will make Automake consider them to be a single unit, and won't move them around. The downside is that Automake will not figure out that those object files are dependencies of your library, so you may have to specify _DEPENDENCIES as well.

Community
  • 1
  • 1
ptomato
  • 56,175
  • 13
  • 112
  • 165