Подтвердить что ты не робот

Очень странное поведение компоновщика

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

gcc -o example example.o -Wl -L/home/kensey/cdev/lib -L/usr/lib/x86_64-linux-gnu   -lmysqlclient -lpthread -lz -L/usr/lib/x86_64-linux-gnu -lm -lrt -ldl -lcdev -L/home/kensey/www.tools/gplot-lib -lgplot -L/home/kensey/www.tools/gd1_3ret -lgd -lxml2 -lcurl
/usr/bin/ld: /home/kensey/www.tools/gplot-lib/libgplot.a(set.o): undefined reference to symbol '[email protected]@GLIBC_2.2.5'
/usr/bin/ld: note: '[email protected]@GLIBC_2.2.5' is defined in DSO /usr/lib/x86_64-linux-gnu/libm.so so try adding it to the linker command line
/usr/lib/x86_64-linux-gnu/libm.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status

Итак, если я удалю часть -lm команды, я не получу ошибку. Тем не менее, мне интересно, знает ли кто-нибудь, почему устранение ссылки на нужную библиотеку исправит это. Как линкер знает, в какую библиотеку искать? Кроме того, есть ли способ запросить встроенный исполняемый файл и сказать: "В какой библиотеке вы решили ссылку на" пол "? очевидно, что-то происходит, я не понимаю, и это беспокоит меня...

4b9b3361

Ответ 1

Объяснение того, что происходит очень просто:

  • Ваш libgplot.a зависит от libm.so, но порядок -lm и -lgplot на линии ссылки неверен. Порядок библиотек в линии ссылок вопрос. В общем случае системные библиотеки (-lpthread, -lm, -lrt, -ldl) должны следовать за всем остальным в линии ссылок.

  • Когда вы удаляете -lm из линии ссылок, libm.so.6 по-прежнему втягивается в ссылку другой библиотекой, которая появляется позже в линии ссылок (libgd, libxml2 или libcurl) потому что эта библиотека зависит от libm.so.6. Но теперь libm.so.6 находится в правильном месте на линии связи, и поэтому все работает.

если я положил -lm в конце ссылки, указав ее как последнюю библиотеку, я не получаю ошибку.

Это подтверждает выше объяснение.

Ответ 2

Я решил ту же проблему с export LDFLAGS="$LDFLAGS -lm"

Ответ 3

Возможно, ваши пути поиска в библиотеке (/usr/local/lib/или/usr/lib/,...) не содержат 64-битную libm, поэтому gcc не может найти ее, если вы укажете флаг l. Если вы укажете только каталог, на котором он похож, он может найти правильный. Поэтому вы можете попробовать:

LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu

и используйте -lm

Ответ 4

Трудно сказать. Поскольку в командной строке есть настраиваемые библиотечные каталоги, возможно, что -lm связывает несовместимую альтернативную версию. Без -lm компоновщик мог бы вытащить другую версию, потому что ему нужна одна из библиотек, которые вы связываете.

Чтобы убедиться, что strace оба вызова и видят, где libm.so происходит в обоих случаях.

Кстати, -Wl переключатель ничего не делает, а -L/usr/lib/x86_64-linux-gnu упоминается дважды.

Ответ 5

Просто добавьте в список ответов http://fedoraproject.org/wiki/UnderstandingDSOLinkChange Это информативно. Это не относится к вопросу, заданному выше, но объяснение относится к сообщению об ошибке /usr/bin/ld: note: 'some_reference' is defined in DSO some.so so try adding it to the linker command line

Ответ 6

Одно объяснение может быть:

Возможно, существует слабо связанная функция foo, определенная вне libm, которая заменена сильно связанной версией foo, определенной внутри libm, и именно эта сильно связанная версия вызывает функцию undefined.

Это объясняет, как добавление библиотеки может вызвать ошибку функции undefined.

Ответ 7

Я столкнулся с подобной проблемой; Я помню, что порядок библиотек не имел значения (по крайней мере, в тех случаях, когда я работал) в прошлом для gcc. В этот вопрос здесь кто-то заметил, что поведение, похоже, изменилось между 4.4 и 4.5.

В моем случае я избавился от сообщения об ошибке, выполнив ссылку:

 g++ -Wl,--copy-dt-needed-entries [options] [libraries] [object files] -o executable-file

Ответ 8

Используйте это:

[email protected]:~/ishan$ gcc polyscanline1.cpp -lglut -lGLU -lGL -lm