CMake和Dylib:符号定义

CMake and Dylib : symbol definitions

本文关键字:符号 定义 Dylib CMake      更新时间:2023-10-16

我在dylib的cmake配置上遇到了一些困难。

这是我的测试:

mylibfunc.cpp

#include <stdio.h>
static int count = 0;
extern "C"
{
    int mylibfunc()
    {
        count++;
        return count;
    }
}

基本测试.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: %ptFunction A: %pt Count: %dn", handleA, functionA, (*functionA)());
// Reload same library
void* handleB = dlopen("libmylib.dylib", RTLD_LAZY);
funcPtr functionB = (int(*)())dlsym(handleB, "mylibfunc");
fprintf(stderr, "Handle B: %ptFunction B: %pt Count: %dn", 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: %ptFunction C: %pt Count: %dn", 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  

-->每个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