Для связывания требуется связать две статические библиотеки, которые зависят друг от друга: неопределенная ссылка
Я знаю, это уже спрашивали миллион раз... К сожалению.
Но я работаю над сборкой металла для процессоров 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 (где таких вызовов много).