Pregunta

I'm encountering some difficulties on cmake configuration for dylib.

Here is my test:

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})

Test 1 on command line:

clang++ -dynamiclib mylibfunc.cpp -o libmylib.dylib
cp libmylib.dylib libmylib_copy.dylib
clang++ basictest.cpp -o basictest
./basictest

Output:

Handle A: 0x7fba614039b0    Function A: 0x10f7a5f50  Count: 1 
Handle B: 0x7fba614039b0    Function B: 0x10f7a5f50  Count: 2 
Handle C: 0x7fba61403de0    Function C: 0x10f7d8f50  Count: 1 

--> Each lib has its own static count, working fine.

Test 2 With 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  

Output:

Handle A: 0x7ff5424039b0    Function A: 0x104a63f50  Count: 1  
Handle B: 0x7ff5424039b0    Function B: 0x104a63f50  Count: 2  
Handle C: 0x7ff5424039b0    Function C: 0x104a63f50  Count: 3  

--> Each lib shared the same counter, which is not what I want....

What should I change in cmake or xcode properties ?

¿Fue útil?

Solución

I'll try to give you an answer as complete as possible, but there's a few point I'm not sure to fully understand, so...

First, the difference between the libraries built "manually" and those built by CMake. The identifier of the former is a relative path when it's an absolute one for the later, you can see that with otool:

otool -D libmylib.dylib

That'll be /something/libmylib.dylib for the CMake built and libmylib.dylib for the manual built. Of course, when you copy the dylib, the identifier stay the same.

So, it appears that for some reason (yeah, that's the part I don't really understand) when using absolute paths, the dynamic loader understand that both the dylib files are the same because they have the same id, and not when the id is relative.

So, if you want to fix your problem, you should update the identifier of the copied library. That can be done with install_name_tool:

install_name_tool -id "libmylib_copy.dylib" libmylib_copy.dylib
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top