我在dylib的cmake配置上遇到了一些困难.
这是我的测试:
mylibfunc.cpp
#include <stdio.h>
static int count = 0;
extern "C"
{
int mylibfunc()
{
count++;
return count;
}
}
basictest.cpp
#include <stdio.h>
#include <dlfcn.h>
#include <mach-o/dyld.h>
typedef int (*funcPtr)();
int main()
{
// Load first library
void* handleA = dlopen("libmylib.dylib", RTLD_LAZY);
funcPtr functionA = (int(*)())dlsym(handleA, "mylibfunc");
fprintf(stderr, "Handle A: %p\tFunction A: %p\t Count: %d\n", handleA, functionA, (*functionA)());
// Reload same library
void* handleB = dlopen("libmylib.dylib", RTLD_LAZY);
funcPtr functionB = (int(*)())dlsym(handleB, "mylibfunc");
fprintf(stderr, "Handle B: %p\tFunction B: %p\t Count: %d\n", handleB, functionB, (*functionB)());
// Load copy of first library (just rename)
void* handleC = dlopen("libmylib_copy.dylib", RTLD_LAZY);
funcPtr functionC = (int(*)())dlsym(handleC, "mylibfunc");
fprintf(stderr, "Handle C: %p\tFunction C: %p\t Count: %d\n", handleC, functionC, (*functionC)());
return 0;
}
CMakeLists:
cmake_minimum_required(VERSION 2.8.11)
SET(src_dir mylibfunc.cpp)
add_library(mylib SHARED ${src_dir})
target_link_libraries(mylib ${EXTRA_LIBS})
在命令行上测试1:
clang++ -dynamiclib mylibfunc.cpp -o libmylib.dylib
cp libmylib.dylib libmylib_copy.dylib
clang++ basictest.cpp -o basictest
./basictest
输出:
Handle A: 0x7fba614039b0 Function A: 0x10f7a5f50 Count: 1
Handle B: 0x7fba614039b0 Function B: 0x10f7a5f50 Count: 2
Handle C: 0x7fba61403de0 Function C: 0x10f7d8f50 Count: 1
– >每个lib都有自己的静态计数,工作正常.
测试2使用cmake:
cmake -G"Xcode"
open Project.xcodeproj and build project on xcode 4
cp libmylib.dylib libmylib_copy.dylib
clang++ basictest.cpp -o basictest
./basictest
输出:
Handle A: 0x7ff5424039b0 Function A: 0x104a63f50 Count: 1
Handle B: 0x7ff5424039b0 Function B: 0x104a63f50 Count: 2
Handle C: 0x7ff5424039b0 Function C: 0x104a63f50 Count: 3
– >每个lib共享同一个计数器,这不是我想要的….
我应该在cmake或xcode属性中更改什么?
最佳答案 我会尽量给你一个完整的答案,但有几点我不确定完全理解,所以…
首先,“手动”构建的库与CMake构建的库之间存在差异.前者的标识符是相对路径,当它是后者的绝对路径时,你可以看到otool:
otool -D libmylib.dylib
这将是用于构建CMake的/something/libmylib.dylib和用于构建的手册的libmylib.dylib.
当然,复制dylib时,标识符保持不变.
因此,在使用绝对路径时,似乎由于某种原因(是的,这是我不太了解的部分),动态加载器理解dylib文件是相同的,因为它们具有相同的id,而不是id是相对的.
因此,如果要解决问题,则应更新复制库的标识符.这可以使用install_name_tool完成:
install_name_tool -id "libmylib_copy.dylib" libmylib_copy.dylib