Для связывания требуется связать две статические библиотеки, которые зависят друг от друга: неопределенная ссылка

Я знаю, это уже спрашивали миллион раз... К сожалению.

Но я работаю над сборкой металла для процессоров ARM Cortex M4. Так что нет общих библиотек, только статические. При связывании моей программы с gcc выдает следующую ошибку:

$ arm-none-eabi-gcc -Wall lots_of_code.o libFW.a
arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/fpu/libg.a(lib_a-exit.o):
In function `exit':
exit.c:(.text.exit+0x16): undefined reference to `_exit'
collect2: error: ld returned 1 exit status

libFW.a - это созданная мною библиотека, содержащая файл syscalls.o, обеспечивающий _exit():

$ arm-none-eabi-nm -s libFW.a | grep _exit
_exit in syscalls.o
00000018 T _exit

Мне кажется, что gcc пытается связать libg.a и lots_of_code.o, но пока не знает о _exit (). Но странная вещь заключается в следующем: он работает правильно при прямой ссылке на syscalls.o:

$ arm-none-eabi-gcc -Wall lots_of_code.o syscalls.o libFW.a

Что может вызвать это?

1 ответ

Когда вы принудительно связываете объектный файл, указывая его в командной строке ссылки, он встраивается в программу независимо от того, предоставляет ли он необходимые символы или нет. Когда вы связываете его из библиотеки, он будет включен в программу только в том случае, если он удовлетворяет хотя бы одному из неопределенных символов во время чтения библиотеки.

Это плохая идея иметь круговые зависимости между статическими библиотеками. Обходной путь - дважды связать библиотеки. Также обычно плохая идея заменить системные функции, такие как exit() с вашим собственным воплощением этого. Похоже, что библиотека C поднимает exit() какие звонки _exit() но по какой-то причине нет _exit() в библиотеках, связанных после этого. Это все немного странно, прямо скажем. Почему вы думаете, что ваш syscalls.o лучше, чем средства, предоставляемые компилятором (O/S)? Если вам нужно принудительно связать ваши системные вызовы, вам нужно иметь ссылки на один из символов, определенных в syscalls.o перед тем, как связать основную библиотеку C (где таких вызовов много).

Другие вопросы по тегам