在我正在进行的项目中,我们提供了动态加载附加功能的可能性。为此,我们使用 dlopen。
为了找到这个库,我们有一些我们称之为模块路径的东西。我们有一个默认路径,共享库所在的位置(其中很多已发货)。
目前我们有两个默认路径:我们首先在构建目录中查找共享库,然后在安装目录中查找。这是因为它也应该可以在不安装的情况下运行应用程序(因此在这种情况下,它需要首先在构建目录中查找)。
现在问题来了,如果用户从源代码构建应用程序并使用 make install 安装它,则默认情况下会加载她构建目录中的库。这将导致崩溃。因此,它仅在用户随后删除或重命名构建目录时才有效。
没有问题:是否有技巧(通过 C++ 或构建系统)知道应用程序是否已安装。问题是,该功能是在共享库中实现的,搜索模块的实现方式也必须适用于链接到我们库的其他应用程序(因此我们不能依赖可执行文件的路径)。我们使用 CMake 作为构建系统。
为了使情况更加困难,该解决方案必须在 Windows、Linux 和 Mac OS X 上运行。
编辑:
我进一步调查,问题更复杂。这是这种情况:
- 有一个小的可执行文件
- 此外,还有一个“主”库 main.so
- 然后有一个动态加载的库 lib.so
- lib.so 链接到 main.so
问题是,lib.so 在其 rpath 的构建目录中具有 main.so 的绝对路径。感谢@MSalters 的提示,我现在能够进行破解以确保加载正确版本的 lib.so(安装目录中的那个),但是由于它在 rpath 中有构建路径,因此它加载了错误的 main .so (所以实际上内存中有两个 main.so 副本——这把事情搞砸了)。
有没有办法从库中删除对构建路径的引用?我尝试了与 rpath 相关的所有 cmake 选项但没有成功