CMake и Dylib: определения символов

Я сталкиваюсь с некоторыми трудностями при настройке 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?

1 ответ

Решение

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

Во-первых, разница между библиотеками, созданными "вручную", и библиотеками, созданными 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
Другие вопросы по тегам