我目前正在寻找在Linux上公开共享库位置的方法,以便任何单独安装的程序都可以轻松获取它。我想使这个位置可配置,以便它可以指向同一个库的不同可能安装。我能想到的类似案例的例子是Qt5和Java。
总而言之,我正在开发FreeRDS
,一个基于FreeRDP
的远程桌面服务堆栈。服务器端RDS感知应用程序链接到libwinpr-wtsapi,这是一个公开Microsoft Windows终端服务API接口的存根库,但没有实现它。这使应用程序可以链接到libwinpr-wtsapi,而无需直接链接到特定的RDS实现。在第一次调用任何WTSAPI函数时,实际的实现由libwinpr-wtsapi动态加载。但是,需要知道实现WTSAPI(此处为FreeRDS)的动态库的位置。
现在,我通过设置一个包含库的完整路径的环境变量来实现这一目标:
export WTSAPI_LIBRARY=/opt/freerds/lib/x86_64-linux-gnu/libfreerds-fdsapi.so
但是,这不太实际,因为需要使用WTSAPI
为每个程序设置此环境变量。在这种情况下,我在/opt/freerds
安装了FreeRDS。
我想我可以通过使用单个环境变量在系统上公开FreeRDS
的安装前缀来简化这一过程,类似于JAVA_HOME:
export FREERDS_HOME=/opt/freerds
然而,我需要知道正确的库子目录。同样重要的是要知道将来可能会提供32-bit
和64-bit
版本的库提供FreeRDS
WTSAPI
。这个库基本上与RPC
会话管理器一起执行FreeRDS
,所以这肯定是可能的。
假设我们已正确设置FREERDS_HOME
,或者FreeRDS
安装在系统的默认安装前缀中,哪些文件是“标准”以提供一些额外的安装配置信息?在这里,我想我可能有Qt5
qt.conf
等效的特定安装子目录,如64-bit
安装子目录,32-bit
安装子目录等。但是,我不知道我应该把该文件放在哪里。它应该在<prefix>/etc/freerds/freerds.conf
吗?
想法,有人吗?谢谢!
答案 0 :(得分:0)
environment-modules
,其目的正是通过简单的前端自定义环境(最终,shell别名/函数)来提供相同软件的许多不同版本 - 命令。
您可以找到所有需要的信息here。
答案 1 :(得分:0)
感谢多个答案,以下是我最终选择满足我需求的解决方案:
如前所述,同一系统上可能有多个FreeRDS安装,但其中只有一个同时运行。我们还可以假设FreeRDS应该在我们尝试与之交互之前运行。知道了这一点,我修改了FreeRDS,在/var/run/freerds.instance中用安装前缀和安装子目录编写一个简单的配置文件。这与拥有.pid文件非常相似,只是我们暴露了安装路径。
freerds.instance文件使用.ini格式,这在配置文件中相当常见。 libwinpr-wtsapi所要做的就是解析/var/run/freerds.instance来查找当前FreeRDS实例的安装前缀以及库子目录,这样我们就可以找到正确的libfreerds-fdsapi.so。
以下是示例freerds.instance文件的样子:
[FreeRDS]
prefix="/opt/freerds"
bindir="bin"
sbindir="sbin"
libdir="lib/x86_64-linux-gnu"
datarootdir="share"
localstatedir="var"
sysconfdir="etc"
我更喜欢这种解决方案,因为它几乎不需要特殊配置,设置环境变量等。无论如何,我们总能在系统上找到合适的FreeRDS安装。
答案 2 :(得分:0)
您可以向可执行文件添加$ORIGIN
rpath,使其相对于可执行文件所在的目录加载库。(请参阅“ld: Using -rpath,$ORIGIN inside a shared library (recursive)”)。这也可能适用于dlopen()
。
$ gcc ... -Wl,-rpath,'$ORIGIN/../lib/dir' -lsomething
我还发现你可以直接运行动态链接器以获得一些调试工具:
$ /lib/ld-linux.so.2
Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]
...
--list list all dependencies and how they are resolved
答案 3 :(得分:-1)
export LD_LIBRARY_PATH = / yourso.so