我正在编译Linux库(对于Android,使用NDK的g ++,但是我敢打赌,我的问题对于任何Linux系统都是有意义的)。 将这些库提供给合作伙伴时,我需要用一个版本号来标记它们。 我还必须能够以编程方式访问版本号 (例如,在“关于”对话框或GetVersion
函数中显示它)。
我首先编译带有未版本标志(版本为0.0
)的库,并且在完成testing之后,需要将此版本更改为真正的版本,然后将其发送给合作伙伴。 我知道修改源代码和重新编译会更容易,但是我们不想这样做(因为如果我们重新编译代码,我们应该再次testing所有东西,我们觉得这样做不太容易出错,请参阅这个注释最后是因为我们的开发环境是这样工作的:我们为Windows二进制文件执行这个过程:我们设置一个0.0
版本的资源版本string(.rc),之后我们使用verpatch进行更改 …我们希望使用相同的运送Linux二进制文件时的过程)。
这里最好的策略是什么? 总而言之,要求是:
0.0
或其他) 如果你的答案是“重命名.so”,那么请提供3的解决scheme:如何在运行时检索版本名称(即:文件名)。
我正在考虑一些解决scheme,但不知道他们是否可以工作以及如何实现这些解决scheme。
string
或3个int
),并且有办法在以后的二进制文件中更改它? 使用二进制sed …? 请注意,我们使用QtCreator编译Android .so文件,但它们可能不依赖于Qt。 所以使用Qt资源不是一个理想的解决scheme。
恐怕你从最后开始解决你的问题。 首先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
。
与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
,使其更独特…) 2.3.40
其修补到VERSIONSTRING:00002.00003.00040.00000
2.3.40
mylib.so
(例如请求版本2.3
) 2.3
! 没有重新编译也没有链接,你修补了二进制版本!