我正在编译Linux库(对于Android,使用NDK&#g; g ++,但我敢打赌我的问题对于任何Linux系统都有意义)。在将这些库提供给合作伙伴时,我需要使用版本号标记它们。 我还必须能够以编程方式访问版本号(例如,在"关于"对话框或GetVersion
功能中显示它。)
我首先使用无版本标记(版本0.0
)编译库,并且在我将测试发送给合作伙伴之前完成测试时需要将此版本更改为真实版本。我知道修改源代码并重新编译会更容易,但我们不想这样做(因为如果我们重新编译代码,我们应该再测试一下,我们觉得它不会出错,请参阅注释到这篇文章,最后因为我们的开发环境以这种方式工作:我们为Windows二进制文件执行此过程:我们设置了0.0
资源版本字符串(.rc),我们稍后使用verpatch更改它。 。我们希望在运送Linux二进制文件时使用相同类型的过程。)
这里最好的策略是什么? 总而言之,要求是:
0.0
或其他任何内容)如果您的答案是"重命名.so",请提供3的解决方案:如何在运行时检索版本名称(即:文件名)。
我在考虑一些解决方案,但不知道它们是否可以工作以及如何实现它们。
string
或3 int
),并且有办法在以后的二进制文件中更改它吗?使用二进制sed ......?请注意,我们使用QtCreator来编译Android .so文件,但它们可能不依赖于Qt。因此,使用Qt资源并不是一个理想的解决方案。
答案 0 :(得分:2)
恐怕你从最后开始解决问题了。首先,SONAME在链接时作为链接器的参数提供,因此在开始时,您需要找到一种从源获取版本并传递给链接器的方法。一种可能的解决方案 - 使用ident
实用程序并在二进制文件中提供版本字符串,例如:
const char version[] = "$Revision:1.2$"
此字符串应以二进制形式显示,ident
实用程序将检测它。或者您可以使用grep
或类似的东西直接解析源文件。如果存在冲突的可能性,则添加额外的标记,以后可以使用它来检测此字符串,例如:
const char version[] = "VERSION_1.2_VERSION"
因此,您可以从源文件或.o文件中检测版本号,然后将其传递给链接器。这应该有用。
对于版本为0.0的调试版本很容易 - 只是在构建调试时避免检测,并且无条件地使用0.0作为版本。
对于第三方构建系统,我建议使用cmake
,但这只是我个人的偏好。解决方案也可以在标准Makefile中轻松实现。我不确定qmake
。
答案 1 :(得分:2)
与Slava的讨论让我意识到任何const char*
实际上都可以在二进制文件中看到,然后可以很容易地修补到其他任何内容。
所以这是解决我自己问题的好方法:
const char version[] = "VERSIONSTRING:00000.00000.00000.00000";
的定义(我们需要它足够长,因为我们以后可以安全地修改二进制文件内容但不能扩展它......)GetVersion
函数,用于清除上面的version
变量(删除VERSIONSTRING:
和无用的0
)。它将返回:
0.0
为version
VERSIONSTRING:00000.00000.00000.00000
如果2.3
为version
VERSIONSTRING:00002.00003.00000.00000
如果2.3.40
为version
VERSIONSTRING:00002.00003.00040.00000
mylib.so
GetVersion
),它返回0.0
,毫不奇怪std::fstream
std::ios_base::binary
)VERSIONSTRING:00000.00000.00000.00000
VERSIONSTRING
,以使其更加单一......)VERSIONSTRING:00002.00003.00040.00000
2.3.40
mylib.so
)2.3
2.3
!没有重新编译也没有链接,你修补了二进制版本!