ELF: linking: Почему я получаю неопределенные ссылки в файлах .so - PullRequest
7 голосов
/ 15 апреля 2010

Я пытаюсь создать программу для wxWidgets и получаю ошибку компоновщика.Я хотел бы действительно понять, что это значит.Ошибка:

/usr/lib/libwx_baseu-2.8.so: undefined reference to `std::ctype<char>::_M_widen_init() const@GLIBCXX_3.4.11'

Я не понимаю, почему ошибка на libwx_baseu-2.8.so.Я думал, что для .so файлов разрешены все символы, в отличие от .o файлов, которые все еще нуждаются в связывании.

Когда я ldd .so, я получаю разрешение всех связанных библиотекздесь нет проблем:

$ ldd /usr/lib/libwx_baseu-2.8.so
 linux-gate.so.1 =>  (0x00476000)
 libz.so.1 => /lib/libz.so.1 (0x00d9c000)
 libdl.so.2 => /lib/libdl.so.2 (0x002a8000)
 libm.so.6 => /lib/libm.so.6 (0x00759000)
 libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x002ad000)
 libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x0068d000)
 libpthread.so.0 => /lib/libpthread.so.0 (0x006f0000)
 libc.so.6 => /lib/libc.so.6 (0x00477000)
 /lib/ld-linux.so.2 (0x007f6000)

Означает ли это, что файл .so был скомпилирован неправильно (в данном случае это ошибка в моем дистрибутиве) или это означает, что отсутствуют библиотекив командной строке компоновщика для моей конкретной программы?

Кроме того, вы знаете, как я могу получить список неопределенных символов в файле ELF.Я попытался readelf -s, но не могу найти пропущенный символ.

Спасибо.

Милдред

Ответы [ 4 ]

8 голосов
/ 15 апреля 2010

I thought that .so files had all its symbols resolved, contrary to .o files that still need linking.

Общие библиотеки могут быть неполными, это нормально.

do you know how I can get a list on undefined symbols in an ELF file

Используйте

nm -C -u libwx_baseu-2.8.so

4 голосов
/ 17 апреля 2010

Когда вы связываете общую библиотеку с другими общими библиотеками (например, ссылка libwx_baseu-2.8.so против libstdc++.so), компоновщик записывает версионные символы, используемые libwx_baseu и предоставляемые libstdc++.

Если во время выполнения вы используете другую копию libstdc++ (такую, которая не содержит одинаковые версионные символы), вы получаете (динамическую) ошибку, и программа вообще не запускается (это предпочтительнее для «загадочного» падения позже).

Но здесь происходит то, что вы пытаетесь связать исполняемый файл, что означает (статический) компоновщик хочет найти все символы, которые потребуются во время выполнения. Опять же, вы связываете исполняемый файл с другим (более старым) libstdc++.so, поэтому связывание завершается неудачей.

Существует две обычных основных причины:
- либо вы связали libwx_baseu-2.8.so в другой системе (с более новой версией GCC) и скопировали ее в текущую систему, либо
- вы связали libwx_baseu-2.8.so с новым GCC в той же системе, но теперь пытаетесь связать исполняемый файл со старым GCC.

3 голосов
/ 15 апреля 2010

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

Вы должны связать в своей программе все общие библиотеки, на которые вы ссылаетесь в вашем .so

Если .so связан с некоторыми статическими библиотеками - в программе не требуется ссылаться на них, если все необходимые символы находятся в .so

Вы можете использовать команду nm linux для просмотра символов в объектном файле, библиотеке или двоичном файле

Редактировать
Ваша конкретная проблема может быть описана здесь: http://old.nabble.com/-Bug-49433--gcc4.4,-NEW:-gcc4.4-misses-std::endl-implementation-at--O2%2B-td22836171.html

1 голос
/ 22 марта 2012

Попробуйте: положить -fno-inline в ваших флагах в Makefile. В основном у g ++ 4.4 есть проблемы без него. Попробуйте поставить его ИЛИ удалить опцию -O. Это решило ту же проблему, что и я.

...