Я сталкиваюсь с некоторыми трудностями при настройке cmake для dylib.
Вот мой тест:
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
—> У каждой библиотеки есть свой статический счетчик, работающий нормально.
Тест 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
—> Каждая библиотека разделяла один и тот же счетчик, чего я не хочу ….
Что я должен изменить в свойствах cmake или xcode?
Я постараюсь дать вам максимально полный ответ, но есть несколько моментов, которые я не совсем понимаю, так что …
Во-первых, разница между библиотеками, созданными «вручную», и библиотеками, созданными CMake. Идентификатор первого — это относительный путь, а для последующего — абсолютный. otool
:
otool -D libmylib.dylib
Это будет /something/libmylib.dylib
для CMake построен и libmylib.dylib
для ручной сборки.
Конечно, когда вы копируете dylib, идентификатор остается прежним.
Итак, похоже, что по какой-то причине (да, это та часть, которую я не совсем понимаю) при использовании абсолютных путей динамический загрузчик понимает, что оба файла dylib одинаковы, поскольку имеют одинаковый идентификатор, а не когда идентификатор относительно.
Итак, если вы хотите решить вашу проблему, вы должны обновить идентификатор скопированной библиотеки. Это можно сделать с install_name_tool
:
install_name_tool -id "libmylib_copy.dylib" libmylib_copy.dylib
Других решений пока нет …