我试图在mac osx上创建一个.so。 .so和.dylib类型之间似乎有distinction。
$ file some_real.so
some_real.so: Mach-O 64-bit bundle x86_64
dynamiclib flag会按预期生成dylib
$ g++ -dynamiclib -o libgtest-1.7.0.dylib [my .o files]
$ file libgtest-1.7.0.dylib
libgtest-1.7.0.dylib: Mach-O 64-bit dynamically linked shared library x86_64
#### ^^^ as expected
共享标志没有给出我想要的东西
$ g++ -shared -o libgtest-1.7.0.so [my .o files]
$ file libgtest-1.7.0.so
libgtest-1.7.0.dylib: Mach-O 64-bit dynamically linked shared library x86_64
#### ^^^ not as expected; wanted bundle x86_64
这个stackoverflow answer谈了一下,并提到了-fPIC标志。我将它添加到命令行,它仍然生成一个dynlib
$ g++ -shared -fPIC -o libgtest-1.7.0.so [my .o files]
$ file libgtest-1.7.0.so
libgtest-1.7.0.dylib: Mach-O 64-bit dynamically linked shared library x86_64
#### ^^^ not as expected; wanted bundle x86_64
(为什么:我需要此输出为.so / MH_BUNDLE类型,因为我试图针对已经采用.so格式的内容创建一些谷歌测试,并且链接器拒绝链接gtest .dylib和我的.so。)
答案 0 :(得分:6)
如果您要制作文件包,请在制作文件时使用-bundle
代替-dynamiclib
。
bundle和dylib之间最明显的区别是你可以在编译时链接到dylib。
e.g。 g++ -o testfile testcode.c -lmylib
将链接到libmylib.dylib
,而如果您尝试链接捆绑包,则会获得:
ld: can't link with bundle (MH_BUNDLE) only dylibs (MH_DYLIB) file 'test.bundle' for architecture x86_64
这是最大的区别 - 您无法动态链接捆绑包,而是必须dlopen
或使用Object File Image Functions。我不再使用仅限OS X的功能 - 它们已被弃用,您可以从dl*
函数获得所需的所有功能。
至于构建每个,我会举一个例子:
目标文件test.o
,制作一个dylib:
g++ -dynamiclib -o test.dylib test.o
制作一个包:
g++ -bundle -o test.bundle test.o
在运行时链接捆绑&得到一个符号:
void *v = dlopen("test.bundle", RTLD_LOCAL);
// declare func_ptr as a pointer to a fn taking void, returning an int
int (*func_ptr)(void);
func_ptr = (int (*)(void))dlsym(v, "symbol");
使用旧例程链接一个包(严重的是,不要这样做):
#include <mach-o/dyld.h>
int rc;
NSObjectFileImage img;
NSModule handle;
NSSymbol sym;
rc = NSCreateObjectFileImageFromFile("test.bundle", &img);
if (rc != NSObjectFileImageSuccess) {
fprintf(stderr, "Could not load libanswer.bundle.\n");
exit(-1);
}
/* Get a handle for the bundle. */
handle = NSLinkModule(img, "test.bundle", FALSE);
/* Look up the get_answer function. */
sym = NSLookupSymbolInModule(handle, "_get_answer");
if (sym == NULL)
{
fprintf(stderr, "Could not find symbol: _get_answer.\n");
exit(-2);
}
int (*func_ptr)(void);
func_ptr = NSAddressOfSymbol(sym);
如果您正在使用clang进行编译,那么您将收到一些警告,例如:
warning: 'NSCreateObjectFileImageFromFile' is deprecated: first deprecated in OS X 10.5
即。请不要使用这些功能。