gcc - это - unresolved symbol c




linker woes-неопределенная ссылка (4)

Думаю, вам нужно добавить путь, где компоновщик может найти библиотеку. В gcc / ld вы можете сделать это с помощью -L и libraray с -l.

-Ldir, --library-path = dir

Искать каталог каталога перед стандартными каталогами поиска (эта опция должна предшествовать опции -l, которая выполняет поиск в этом каталоге).

-larch, --library = архив

Включите архивный файл в список файлов для ссылки.

Ответ на ответы - нет файла .a библиотеки, только .h и .c в библиотеке, поэтому -l не является approriate

Тогда вам, возможно, придется сначала создать либрару?

gcc -c mylib.c -o mylib.o
ar  rcs libmylib.a      mylib.o

У меня возникла проблема с моим компилятором, говорящим, что есть «неопределенная ссылка» на функцию, которую я хочу использовать в библиотеке. Позвольте мне поделиться некоторой информацией по проблеме:

  • Я скрещиваю компиляцию с gcc для C.
  • Я вызываю библиотечную функцию, доступ к которой осуществляется через включенный заголовок, который включает в себя другой заголовок, который содержит прототип.
  • Я включил каталог заголовков, используя -I, и я уверен, что он найден.
  • Сначала я создаю файлы .o, а затем свяжу их в отдельной команде.

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

Некоторые предложения были бы замечательными, а может быть, и объяснением того, как компоновщик делает свою работу.

Благодаря!

Ответ на ответы

  • в библиотеке нет файла .a, только .h и .c, поэтому -l не подходит
  • мое понимание файла библиотеки заключается в том, что это всего лишь коллекция заголовков и исходных файлов, но, может быть, это коллекция файлов .o, созданных из источника ?!
  • нет созданного объекта объекта библиотеки, может быть, должно быть? Да, кажется, я не понимаю разницы между включениями и библиотеками ... я буду работать над этим :-)

Спасибо за все ответы! Я много узнал о библиотеках. Я бы хотел отложить все ответы как принятый ответ :-)


Заголовки предоставляют декларации функций и определения функций. Чтобы позволить компоновщику найти реализацию функции (и избавиться от неопределенной ссылки), вам нужно попросить драйвер компилятора (gcc) связать конкретную библиотеку, в которой находится эта функция, используя флаг -l. Например, -lm свяжет математическую библиотеку. На странице руководства функции обычно указывается, какая библиотека, если таковая имеется, должна быть указана для поиска функции.

Если компоновщик не может найти указанную библиотеку, вы можете добавить путь поиска библиотеки, используя ключ -L (например, -L / usr / local / lib). Вы также можете постоянно влиять на путь библиотеки через переменную среды LIBRARY_PATH.

Ниже приведены некоторые дополнительные сведения, которые помогут вам отладить вашу проблему. По соглашению имена файлов библиотеки имеют префикс lib и (в их статической форме) имеют расширение .a. Таким образом, статически связанная версия математической библиотеки по умолчанию для системы (та, которую вы связываете с -lm) обычно находится в /usr/lib/libm.a. Чтобы узнать, какие символы заданы в данной библиотеке, вы можете запускать nm --defined-only в файле библиотеки. В моей системе запуск команды на libm.a дает мне вывод, как показано ниже.

e_atan2.o:
00000000 T atan2

e_asinf.o:
00000000 T asinf

e_asin.o:
00000000 T asin

Чтобы увидеть путь библиотеки, который использует ваш компилятор, и какие библиотеки он загружает по умолчанию, вы можете вызвать gcc с опцией -v. Снова в моей системе это дает следующий результат.

GNU assembler version 2.15 [FreeBSD] 2004-05-23 (i386-obrien-freebsd) 
using BFD version 2.15 [FreeBSD] 2004-05-23
/usr/bin/ld -V -dynamic-linker /libexec/ld-elf.so.1 /usr/lib/crt1.o 
/usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /var/tmp//ccIxJczl.o -lgcc -lc 
-lgcc /usr/lib/crtend.o /usr/lib/crtn.o

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

Создает ли ваш процесс сборки библиотечный файл .c?

Почему вы называете это «библиотекой», если это на самом деле только исходный код?


Я боюсь, что вы смешали концепцию библиотеки и заголовка. Допустим, у вас есть библиотека libmylib.a которая содержит функцию myfunc() и соответствующий заголовок mylib.h который определяет его прототип. В исходном файле myapp.c вы включаете заголовок либо напрямую, либо включаете другой заголовок, который включает его. Например:

/* myapp.h
** Here I will include and define my stuff
*/
...
#include "mylib.h"
...

ваш исходный файл выглядит так:

/* myapp.c
** Here is my real code
*/
...
#include "myapp.h"
...
/* Here I can use the function */
myfunc(3,"XYZ");

Теперь вы можете скомпилировать его для получения myapp.o :

gcc -c -I../mylib/includes myapp.c

Обратите внимание, что -I просто сообщает gcc, где находятся файлы заголовков, они не имеют ничего общего с самой библиотекой!

Теперь вы можете связать свое приложение с реальной библиотекой:

gcc -o myapp -L../mylib/libs myapp.o -lmylib

Обратите внимание, что ключ -L указывает gcc, где находится библиотека, и -l сообщает ему, чтобы связать ваш код с библиотекой.

Если вы не сделаете этот последний шаг, вы можете столкнуться с проблемой, которую вы описали.

Могут быть и другие более сложные случаи, но из вашего вопроса я надеюсь, что этого будет достаточно, чтобы решить вашу проблему.





linker