【发布时间】:2016-09-27 23:35:40
【问题描述】:
我正在编译 Linux 库(对于 Android,使用 NDK 的 g++,但我敢打赌我的问题对任何 Linux 系统都有意义)。在将这些库交付给合作伙伴时,我需要用版本号标记它们。 我还必须能够以编程方式访问版本号(例如在“关于”对话框或GetVersion 函数中显示它)。
我首先使用未版本化标志(版本0.0)编译库,并且需要在完成测试后将此版本更改为真实版本,然后再将其发送给合作伙伴。我知道修改源代码并重新编译会更容易,但我们不想这样做(因为如果重新编译代码,我们应该再次测试所有内容,我们觉得它更不容易出错,请参阅 cmets发布,最后因为我们的开发环境是这样工作的:我们为 Windows 二进制文件执行此过程:我们设置了一个 0.0 资源版本字符串 (.rc),然后我们使用 verpatch 更改它...我们想在发布 Linux 二进制文件时使用相同类型的进程)。
这里最好的策略是什么? 总而言之,要求是:
- 使用“未设置”版本(
0.0或其他任何内容)编译二进制文件 - 能够将此“未设置”版本修改为特定版本,而无需重新编译二进制文件(理想情况下,运行第 3 方工具命令,就像我们在 Windows 下使用 verpatch 一样)
- 能够让库代码在运行时检索其版本信息
如果您的答案是“重命名.so”,那么请提供解决方案3.:如何在运行时检索版本名称(即:文件名)。
我正在考虑一些解决方案,但不知道它们是否可行以及如何实现它们。
- 代码中有一个版本变量(一个
string或3 个int),并且以后有办法在二进制文件中更改它吗?使用二进制 sed...? - 资源中有一个版本变量,并且以后可以在二进制文件中更改它吗? (就像我们对 win32/win64 所做的那样)
- 使用专用于此的 .so 字段(如 SONAME),并拥有允许更改它的工具...并使其可从 C++ 代码访问。
- 重命名 lib + 更改 SONAME(没有找到如何实现)...并找到从 C++ 代码中检索它的方法。
- ...
请注意,我们使用 QtCreator 来编译 Android .so 文件,但它们可能不依赖于 Qt。所以使用 Qt 资源并不是一个理想的解决方案。
【问题讨论】:
-
您担心使用交换的一个版本字符串重新编译完全相同的代码可能会破坏事情并需要进行新的测试,但是对于涉及破解自己的脚本将更改的字符串修补到二进制?这……很有趣。
-
您的发言完全有道理。实际上我们曾经这样做过:更改代码中的版本号(例如更改为 3.2)并重新编译。我们是一个小型结构,人们同时进行开发和集成......然后,这样做的开发人员经常忘记将版本字符串重置为 0.0,然后当它们绝对不是 3.2 版本时,您会得到标记为 3.2 的开发二进制文件......那就是为什么在编译后标记二进制文件对我们来说似乎更安全(这就是我们最终在 Windows 下工作的方式)。
-
我的评论仍然适用 :-) 为什么不从根本上解决您的问题,并更改您的构建环境以将任何调试构建的版本号更改回 0.0?最简单的方法是使用版本号的预处理器定义。该解决方案的巧妙之处在于它可以很容易地被采用来包括例如调试版本的版本字符串中的修订 ID。
-
您的问题不准确,更改 SONAME 不需要(重新)编译,只需(重新)链接已编译的对象。因此,您无需更改任何源代码即可更改 SONAME 并使用正确的 SONAME 重新创建共享库。
-
是的,这是非常糟糕的设计,没有提供删除版本信息的方法。
标签: c++ linux g++ shared-libraries versioning