Очень странное поведение компоновщика - PullRequest
45 голосов
/ 30 марта 2012

Это странно, потому что я смог убрать указанную ниже ошибку, удалив ссылку на 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 'floor@@GLIBC_2.2.5'
/usr/bin/ld: note: 'floor@@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,не получить ошибку.Тем не менее, мне интересно, если кто-нибудь знает, почему удаление ссылки на необходимую библиотеку может исправить это.Как компоновщик узнает, какую библиотеку искать?Кроме того, есть ли способ запросить встроенный исполняемый файл и сказать «в какой библиотеке вы указали ссылку на« floor »?очевидно, что-то происходит, чего я не понимаю, и это беспокоит меня ...

Ответы [ 8 ]

83 голосов
/ 23 апреля 2012

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

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

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

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

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

8 голосов
/ 25 апреля 2013

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

6 голосов
/ 30 марта 2012

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

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

и использовать -lm

3 голосов
/ 30 марта 2012

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

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

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

2 голосов
/ 20 мая 2013

Просто чтобы добавить в список ответов, 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

1 голос
/ 04 июня 2013

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

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

 g++ -Wl,--copy-dt-needed-entries [options] [libraries] [object files] -o executable-file
1 голос
/ 30 марта 2012

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

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

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

0 голосов
/ 25 февраля 2016

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

administrator@administrator-Veriton-M200-H81:~/ishan$ gcc polyscanline1.cpp -lglut -lGLU -lGL -lm
...