2013-12-21 3 views
1

Я знаю, что уже было задано миллион раз ... К сожалению.Связывание требует связывания двух статических libs, которые зависят друг от друга: undefined reference

Но, однако, я работаю над металлическими сборками для процессоров 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 является Lib я создал, содержащий файл с именем 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 

Что могло привести к этому?

+0

Вы играли с разными флагами, такими как '-nostdlib',' -nostartfiles' или '-ffreestanding'? – auselen

ответ

1

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

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

+0

Как я уже сказал, это металлическая сборка. Таким образом, нет ОС, и она предназначена для реализации '_exit' себя, чтобы указать поведение, когда программа заканчивается. Обычно это делается бесконечным nop-loop ... И тут все становится довольно сложно. На данный момент я избегаю этой проблемы с помощью переключателя '-u _exit', так что gcc просто больше не жалуется, но это не то решение, которое я ищу. Разве вы не можете дать мне командную строку, которую я мог бы легко попробовать? –

+0

OK; что объясняет, что такое «металлическая конструкция»; Я не работаю во встроенном пространстве, и этот термин не вызывал никаких тревожных звонков (но, я думаю, это должно было быть сделано). Вкратце, вы не в моем опыте. Но похоже, что связывание 'syscalls.o' является самым простым способом. В отсутствие неотразимой необходимости делать что-то другое, вот что я сделал бы. В противном случае вам необходимо просмотреть (возможно, опцию '-v' для вашего GCC), что такое командная строка, и выяснить, как автоматически включить' syscalls.o'. –

 Смежные вопросы

  • Нет связанных вопросов^_^