Очень странное поведение компоновщика
Это странно, потому что я смог получить ошибку ниже, чтобы уйти, удалив ссылку на 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
команды, я не получу ошибку. Тем не менее, мне интересно, знает ли кто-нибудь, почему устранение ссылки на нужную библиотеку исправит это. Как линкер знает, в какую библиотеку искать? Кроме того, есть ли способ запросить встроенный исполняемый файл и сказать: "В какой библиотеке вы решили ссылку на" пол "? очевидно, что-то происходит, я не понимаю, и это беспокоит меня...
Ответы
Ответ 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