Search code examples
clinkerstatic-librarieslibopencm3

Static library linking issues (no reference to main, or no reference)


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?


Solution

  • 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: