1

When trying to solve the question posted here: __start_section and __stop_section symbols missing when linking to library I've determined it would be best if I could get my C autotools project to compile a list of objects without generating a library (or I can ignore the library as long as the intermediate objects are present). Here is my current Makefile.am:

AM_CFLAGS = -I$(top_srcdir)/drivers/include
lib_LIBRARIES = libdriver.a
libdriver_a_SOURCES = $(STATIC_DRIVER_FILES)
STATIC_DRIVER_FILES = src/driver.c

if FLASH_SIM
STATIC_DRIVER_FILES += flash/flash_sim.c
endif

if UART_SIM
STATIC_DRIVER_FILES += uart/uart_sim.c
endif

This works fine and creates libdriver.a. What I need is a variable STATIC_DRIVER_OBJS that contains a list of all the compiled objects I can link to from the main application. The question posted above explains why I can't just link the the library directly.

Community
  • 1
  • 1
an0n
  • 61
  • 1
  • 7
  • I don't understand why what you've got (`libdriver.a`) won't work. A `.a` library should be just a collection of `.o` files. – ldav1s Jan 03 '14 at 01:07
  • libdriver.a contains 2 objects. driver.c and flash_sim.c. flash_sim.c defines a bunch of static fns which are exposed via a data struct that is put in a custom ELF section. driver.c then enumerates the custom section by using the symbol __start_custom_section which get defined by the linker at link time. For whatever reason if I link directly to the object file ie: flash_sim.o the linker will create these symbols to point to that section. However if I link to the library these symbols do not get created (presumably because the struct in that section is never directly referenced). – an0n Jan 03 '14 at 01:18
  • It's very similar to how linux module init happens except they link directly to the object files (maybe for this reason). If I can get a list of object files relative to the top srcdir I should be able to accomplish the same thing using autotools. Examining the Makefile directly it looks like what I need is available in libdriver_a_OBJECTS but it isn't exported and is using relative paths... – an0n Jan 03 '14 at 01:28
  • OK, that kind of makes sense. So `libdriver.a` is being clobbered by `ar`... – ldav1s Jan 03 '14 at 01:31
  • Yep, and since I'm a complete noob using autotools I can't figure out how to export a variable containing all the object files so they can be linked by another makefile. – an0n Jan 03 '14 at 02:00

2 Answers2

0

You could try something like:

whizbang_SOURCES = ... # the main executable
whizbang_LDADD = $(libdriver_a_OBJECTS) ...

I'd do it more like:

noinst_LTLIBRARIES = libdriver.la
...
libdriver_la_SOURCES = src/driver.c

if FLASH_SIM
libdriver_la_SOURCES += flash/flash_sim.c
endif
if UART_SIM
libdriver_la_SOURCES += uart/uart_sim.c
endif

...
whizbang_LDADD = $(libdriver_la_OBJECTS) ...

Just so you don't have to worry about dealing with libdriver.a (no installation).

ldav1s
  • 15,885
  • 2
  • 53
  • 56
  • That's what I hope to accomplish. There are 2 problems I run into: 1. The whizbang_LDADD statement is in another Makefile.am in the directory structure and $(libdriver_a_OBJECTS) doesn't appear to be visible from there (I see a .NOEXPORT at the end of the generated makefile). 2. Since it's in another spot in the directory structure I need to figure out a way to append $(top_srcdir)/subdir/ to each of the objects. Thanks for you help! – an0n Jan 03 '14 at 17:36
  • The noinst and using libtool is a good tip. So many nice features in autotools which is why I really want to make this work. – an0n Jan 03 '14 at 17:42
0

I ended up accomplishing this using ldav1s's answer above and converting my project to use non-recursive make. As a side effect it appears to compile faster too. Here is the guide I used to convert it to non-recursive make: https://www.flameeyes.eu/autotools-mythbuster/automake/nonrecursive.html. It's nice to only have to maintain one Makefile.am.

an0n
  • 61
  • 1
  • 7