"Неопределенный символ _memset" - PullRequest
2 голосов
/ 10 августа 2011

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

/usr/ccs/bin/ld -o q -e start_master -dn -z defs -M ../../../mapfile.q {list of object files}

Я получаю следующую ошибку:

Undefined                       first referenced 
 symbol                             in file
_memset                             reconf.o

Интересно то, что на memset нет ссылки в reconf.c, и я также выполнил grep'ed весь каталог, но в других файлах также нет ссылки на _memset. Поэтому мне интересно, почему я получаю это сообщение об ошибке от компоновщика, хотя нигде в моем исходном коде _memset фактически не используется. У кого-нибудь есть идея, что здесь может происходить?

Большое спасибо, эта ошибка сводит нас с ума!

EDIT:

Я попытался добавить путь к библиотеке memset, связал его с -lc и запустил в подробном режиме:

/usr/ccs/bin/ld -o q -e start_master -dn -z defs -z verbose -L/usr/lib -M ../../../mapfile.q {list of object files} -lc

Тогда я получаю следующую ошибку: ld: fatal: library -lc: не найден ld: fatal: Ошибки обработки файлов. Нет выходных данных, записанных в q

И это, хотя libc.so явно находится в / usr / lib ...

Заблуждение

РЕДАКТИРОВАТЬ II:

Проведя еще несколько исследований, кажется, что в Solaris 10 статическое связывание исчезает, как вы можете прочитать здесь:

http://blogs.oracle.com/rie/entry/static_linking_where_did_it

Вероятно, это моя проблема. Кто-нибудь знает, как я мог бы переписать мою команду компоновщика для обхода этой проблемы?

Большое спасибо!

Ответы [ 3 ]

2 голосов
/ 10 августа 2011

Возможно, вы сделали:

struct S v = { 0 };

или

struct S v;
v = (some const-variable).

или

uint8_t b[100] = { 0 };

.

Некоторые компиляторы неявно выставляют встроенные- в memset (или memcpy) для таких вещей.Тогда встроенный memset называется _memset (в вашем случае).Когда вы ссылаетесь, и ваш libc (или то, что обеспечивает стандартную функцию в вашем случае) не обеспечивает его, вы получаете эту ошибку ссылки.

1 голос
/ 10 августа 2011

Предполагая, что вы находитесь в Solaris, вы найдете memset в библиотеке libc.so:

/usr/lib-> nm libc.so | grep memset
[7122]  |    201876|     104|FUNC |GLOB |0    |9      |_memset

Просто добавьте -lc в командную строку

0 голосов
/ 10 августа 2011

Memset - это библиотечная функция из стандартной библиотеки C. Если вы не используете gcc для компоновки (которая по умолчанию связывает ваши файлы со стандартными библиотеками), вы должны явно связать свой прогром с libc.

С другой стороны, возможно, вы не используете libc. В этом случае вызов memset может быть сгенерирован gcc.

С man gcc:

-nodefaultlibs

Не используйте стандартные системные библиотеки при компоновке. Только указанные вами библиотеки будут переданы компоновщику, а параметры, указывающие связывание системных библиотек, такие как -static-libgcc или -shared-libgcc, будут игнорироваться. Стандартные файлы запуска используются нормально, если не используется -nostartfiles. Компилятор может генерировать вызовы к memcmp, memset, memcpy и memmove. Эти записи обычно разрешаются записями в libc. Эти точки входа должны предоставляться через какой-то другой механизм, если указана эта опция.

В этом случае просто напишите memset (это тривиальный процесс) и передайте его компоновщику.

...