Проблемы со связыванием статической библиотеки (без ссылки на основную или без ссылки)
У меня есть код, который я повторно использую для различных встроенных проектов, поэтому я решил создать библиотеку. Библиотека построена на другой, гораздо более обширной статической библиотеке (libopencm3)
У меня есть только один (пока) файл c, скомпилированный в один объектный файл, который затем архивируется.
Я не уверен, должен ли я связывать объектные файлы в библиотеке с libopencm3, или это должно быть сделано, когда я связываю свое приложение позже. Я предполагал первое, но компоновщик жалуется, что main() не определен (на него ссылаются в 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'
Так что вместо этого не связывайте вещи.
%.o: %.c
@#printf " CC $(subst $(shell pwd)/,,$(@))\n"
$(Q)$(CC) $(CFLAGS) -o $@ -c $<
libdatmos.a: $(BINARIES:=.o) Makefile
$(Q)$(AR) rcs $@ $(BINARIES:=.o)
И попробуйте связать все, когда я создаю свою программу (lsm303.bin). Но когда я это делаю, похоже, что libopencm3 не связан с моей статической библиотекой.
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'
.
.
Любое понимание этого? Должен ли я связывать свою библиотеку при ее создании?
1 ответ
Вот мои обобщенные утверждения:
- При упаковке скомпилированных объектных файлов в статическую библиотеку проблем с зависимостями не возникнет, поскольку компоновщик еще не задействован.
- Вы должны сделать ссылку на все библиотеки, зависящие от других библиотек, непосредственно используемых вашей программой на этапе компоновки
- При связывании со статическими библиотеками вы должны упорядочивать их в соответствии с зависимостями. Если A полагается на B, то A идет перед B. (СОВЕТ: если A полагается на B, а B также полагается на A, используйте -lA -lB -lA)
Ссылки на другие связанные вопросы:
- Порядок связывания статических библиотек GCC: почему порядок, в котором связаны библиотеки, иногда вызывает ошибки в GCC? (см. ответ 150+, а не тот, на котором вопросник помечен правильно)
- Рекурсивная зависимость: как бороться с рекурсивными зависимостями между статическими библиотеками с помощью компоновщика binutils? (Оба ответа полезны)