0

I have some code that I reuse for different embedded projects so I decided to create a library. The library is built on another, much more extensive static library (libopencm3)

I just have one (for now) c file compiled to one object file that is then archived.

I'm not sure if I should be linking the object files in the library with libopencm3, or if that should be done when I link my application later. I assumed the former, but the linker complains that main() is not defined (it's referenced in libopencm3):

arm-none-eabi-gcc -Os -g -Wall -Wextra -Wimplicit-function-declaration -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes -Wundef -Wshadow -I/usr/src/libopencm3/include -I../include -fno-common -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -MD -DSTM32F4 --static -lc -lnosys -L/usr/src/libopencm3/lib -L/usr/src/libopencm3/lib/stm32/f4 -Tstm32f4-discovery.ld -nostartfiles -Wl,--gc-sections -mthumb -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -lopencm3_stm32f4 -o i2c.o i2c.c

/usr/src/libopencm3/lib/libopencm3_stm32f4.a(vector.o): In function `reset_handler':
/usr/src/libopencm3/lib/stm32/f4/../../cm3/vector.c:89: undefined reference to `main'

So Instead don't link things.

%.o: %.c
    @#printf "  CC      $(subst $(shell pwd)/,,$(@))\n"
    $(Q)$(CC) $(CFLAGS) -o $@ -c $<

libdatmos.a: $(BINARIES:=.o) Makefile
    $(Q)$(AR) rcs $@ $(BINARIES:=.o)

And try linking everything when I build my program (lsm303.bin). But when I do, it looks like libopencm3 is not linked to my static library.

arm-none-eabi-gcc -o lsm303.elf lsm303.o -lopencm3_stm32f4 -ldatmos --static -lc -lnosys -L/usr/src/libopencm3/lib -L/usr/src/libopencm3/lib/stm32/f4 -L../util/lib/ -Tstm32f4-discovery.ld -nostartfiles -Wl,--gc-sections -mthumb -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16

../util/lib//libdatmos.a(i2c.o): In function `i2c_setup':
/home/subsidence/stm32f4/util/lib/i2c.c:19: undefined reference to `i2c_reset'
/home/subsidence/stm32f4/util/lib/i2c.c:20: undefined reference to `i2c_peripheral_disable'
/home/subsidence/stm32f4/util/lib/i2c.c:22: undefined reference to `i2c_set_clock_frequency'
.
.

Any insight on this? Should I be linking my library when I build it?

Sam Protsenko
  • 14,045
  • 4
  • 59
  • 75
Yakubs
  • 161
  • 2
  • 11
  • Static libraries are just simple archives of compiled objects, and so when you build a static library, there will be no linking process as making a shared library or an executable will do. Without linking, the compiler will not check for symbol reference and so even though your static library make use of libopencm3, libopencm3 will not get packed into your library. And to make all short, when you compile a program using your static library, you should link to both your library and libopencm3. But of course, you can unarchive libopencm3.a and pack it into your own library. – TwilightSun Jan 07 '14 at 01:17
  • Thanks TwilightSun for answering my question regarding linking the static library at build time. But I'm actually trying to link everything in the final stages there. It's not working for some reason. – Yakubs Jan 07 '14 at 02:24
  • Try reversing **-lopencm3_stm32f4 -ldatmos** to **-ldatamos -lopencm3_stm32f4**. This answer to an interesting question may help you understand why :http://stackoverflow.com/a/409470/1579514. I'll organize these to an answer. – TwilightSun Jan 07 '14 at 03:43

1 Answers1

0

These are my summarized statements:

  • You won't get dependencies issues when packing compiled object files to static library because the the linker is not involved yet.
  • You do have to link to all the libraries depended by other libraries directly used by your program in the linking phase
  • When linking to static libraries, you should order them according to dependency. If A rely on B, then A goes before B. (TIP: if A rely on B while B also rely on A, use -lA -lB -lA)

Links to other related questions:

Community
  • 1
  • 1
TwilightSun
  • 2,275
  • 2
  • 18
  • 27