2017-07-20 25 views
2

我开发了一个C程序,需要一些动态库,最值得注意的是libmysqlclient.so,我打算在某些远程主机上运行。看起来好像我有以下分配选项:在linux下发布一个带库依赖的c程序的选项

  1. 编译程序静态。
  2. 在远程主机上安装所需的依赖关系
  3. 分配程序的依赖关系。

第一个选项是有问题的,因为我在运行时需要glibc-version(因为我现在使用glibc和libnss)。

我不确定第二个选择:是否有一种机制,检查安装的库版本是否足以让程序运行(在libxyz.so.VERSION旁边)。我可以在启动时检查ABI兼容性吗?

关于最后一个选项:我是否将所有共享库与二进制文件分发,或者只是可能未安装的共享库(例如libmysqlclient,而不是libm)。

除了这个,我可能会遇到ABI兼容性问题,如果我使用一个不同的二进制编译器,然后依赖建立与(例如二进制clang,库gcc)?

+0

构建指定正确依赖关系的包('.deb','.rpm'),因此包管理器将自动安装它们。 –

回答

3

版本检查是特定于发行版的。通常,您可以使用目标分发的打包工具将应用程序打包在.deb.rpm文件中,然后将其发送给用户。这意味着您必须为每个受支持的发布版本构建一次应用程序,但实际上没有办法解决这个问题,因为不同版本的libmysqlclient版本略有不同。这些分发构建工具自动生成一些依赖版本信息,而在其他情况下,需要一些手动帮助。

作为一个起点,最好查看一下分布式打包,寻找依赖于MySQL/MariaDB客户端库的东西并复制它。 Debian中的inspircd可能就是一个很好的例子。

通过构建您想要支持的最旧的分发版本,可以减少需要创建和测试的构建量。但有些注意事项适用;分布在它们提供的向后兼容性程度上有所不同。

分配程序的依赖关系是非常成问题的,因为流行的库如libmysqlclient也由基本操作系统提供,如果您使用LD_LIBRARY_PATH来注入自己的版本,这可能会无意中扩展到其他程序(例如,你从自己的程序启动的那些)。即使您使用DT_RUNPATH(通过-rpath链接器选项),后面的风险仍然存在,尽管它有所减少。

另一种选择是静态链接特定于应用程序的支持库,并动态链接基本操作系统库。 (这是一些软件集合所做的)。但是,libmysqlclient似乎并不是一个很好的选择,因为可能会期望它的功能集与发行版相同(关于TLS库和可用的配置选项) ,并与静态链接,这是很难实现的。

+0

您可以在'$ ORIGIN'中使用'rpath'让您的应用程序首先在相对应用程序目录的路径中查找库,这是分发所有依赖项的一个选项,结果应该安装在/ opt下面的某处。 - 但我总是更喜欢发行套餐格式的套餐。 –

+0

如果您从操作系统中执行任何操作,包括名称服务开关('getpwnam'和朋友)执行的隐式'dlopen',这仍然会导致问题。当然,后者不应该使用'libmysqlclient',但你永远不会知道...... –

+0

好吧,只要你不分配任何你需要的东西,而不是你的'dlopen()',你应该没问题,是一些实际使用它的Linux软件包。正如我所说,我不太喜欢这个解决方案,它只是为了完整。 –

相关问题