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