Использование общей библиотеки, связанной с другими общими библиотеками

Я скомпилировал на OSX общую библиотеку с некоторыми внешними зависимостями (увеличение, OpenGL):

g++ -dynamiclib -undefined suppress -flat_namespace -o "libMY_LIB.dylib" ./windowbase.o -lGL -lGLU -lGLUT -lboost_system -lboost_thread

Нет ошибок, file libMY_LIB.dylib результаты в Mach-O 64-bit dynamically linked shared library x86_64, а также otool -L libMY_LIB.dylib выходы:

libPixelsGL.dylib (compatibility version 0.0.0, current version 0.0.0)
/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/GLUT.framework/Versions/A/GLUT (compatibility version 1.0.0, current version 1.0.0)
libboost_system.dylib (compatibility version 0.0.0, current version 0.0.0)
libboost_thread.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

Теперь я пытаюсь связать исполняемый файл с libMY_LIB.dylib, используя только функции в MY_LIB.h (и скомпилировано в lib):

g++ -L"/path/to/MY_LIB" -o "Program" ./main.o -lMY_LIB

но это не удается, печать:

Undefined symbols for architecture x86_64:
"boost::system::system_category()", referenced from:
__static_initialization_and_destruction_0(int, int)in main.o
boost::mutex::mutex()in main.o
boost::mutex::lock()    in main.o
boost::mutex::unlock()    in main.o
"boost::system::generic_category()", referenced from:
__static_initialization_and_destruction_0(int, int)in main.o
"boost::thread::detach()", referenced from:
boost::thread::~thread()in main.o
ld: symbol(s) not found for architecture x86_64

Некоторое объяснение и / или помощь?

Спасибо!

Я пытался связать библиотеку без -undefined suppress -flat_namespace флаги и исполняемый файл с ними, и последний работал. Может ли кто-нибудь сказать мне, почему? Может быть увеличение libs у меня были собраны с этими флагами?

Обновленное спасибо!

2

Решение

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

Ваше сообщение об ошибке вызывает main.o содержит ссылки на boost::system::system_category(), boost::system::generic_category(), а также boost::thread::detach(), Поэтому при связывании main.o в исполняемом двоичном файле вам нужно связать с библиотекой, которая предоставляет эти символы, в этом случае путем передачи -lboost_system -lboost_thread,


Что касается -undefined suppress -flat_namespace: эти параметры влияют на обнаружение пропущенных символов во время сборки. В общем, вы должны избегать использования этих флагов, если у вас нет особых потребностей. Причина, по которой ваш основной исполняемый файл с этими флагами «работает», заключается в том, что вы попросили компоновщика не генерировать ошибки для пропущенных символов. Так как эти символы не знают, они ничего не делают для того, чтобы библиотека, предоставляющая их, загружалась в адресное пространство вашего приложения во время выполнения. Вам повезло, так как символы предоставлены библиотеками, которые libMY_LIB.dylib также ссылки на.

Для иллюстрации рассмотрим простую тестовую библиотеку, liba.dylib, который экспортирует функцию a:

$ cat a.c
int a(void)
{
return 1;
}
$ cc -dynamiclib -o liba.dylib a.c
$

И простое приложение, которое использует эту функцию:

$ cat main.c
#include <stdio.h>

extern int a(void);

int main(int argc, char **argv)
{
fprintf(stderr, "a: %d\n", a());
return 0;
}

Теперь давайте рассмотрим три подхода к привязке этой библиотеки к нашему приложению.

1) без указания библиотеки вообще

$ cc -o main main.c
Undefined symbols for architecture x86_64:
"_a", referenced from:
_main in main-JmKbTd.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Это тот случай, о котором вы изначально сообщали в своем вопросе

2) Указание -undefined suppress -flat_namespace

$ cc -undefined suppress -flat_namespace -o main main.c
$

Это успешно создало исполняемый файл, но когда мы запускаем двоичный файл:

$ ./main
dyld: lazy symbol binding failed: Symbol not found: _a
Referenced from: /tmp/./main
Expected in: flat namespace

dyld: Symbol not found: _a
Referenced from: /tmp/./main
Expected in: flat namespace

Trace/BPT trap: 5

В этом случае загрузчик во время выполнения не знает, что ему нужно загрузить liba.dylib найти функцию a:

$ otool -L main
main:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.0.0)
$ nm -m main | grep _a
(undefined) external _a
$

3) Правильно указать библиотеку

$ cc -L. -la -o main main.c
$ ./main
a: 1
$

И вы можете видеть, что двоичный main знает как загрузить liba.dylib и что это liba.dylib которая обеспечивает функцию a тот main использует:

$ otool -L main
main:
liba.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.0.0)
$ nm -m main | grep _a
(undefined) external _a (from liba)
$

Таким образом, я рекомендую прекратить прохождение -undefined suppress -flat_namespace вообще при создании ваших библиотек и двоичных файлов, а также чтобы каждый компонент связывался с необходимыми библиотеками для символов, которые он использует.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]