如果我还必须链接到 RPM 库(特别是 librpmio.so),我会花时间让一个使用 Lua(5.2 版)的程序运行。这是一个包含多个共享库的大型应用程序的一部分,这些共享库也使用 Lua。
根本问题是我们使用的 librpmio.so 版本 (4.4.X) 中嵌入了 Lua 解释器,它没有隐藏 Lua 代码中包含的全局符号。Lua 的 rpmio 版本 (5.0.2) 比我们使用的 Lua (5.2.x) 旧,因此它们不能完全互换。
到目前为止,我还不能让我们自己的Lua 代码和 RPM API 调用工作。像 lua_pushlstring() 这样的 Lua API 将绑定到 liblua.so 或 librpmio.so 中首先出现在加载模块链中的任何一个。如果我早先在链接器命令行上指定 -llua,那么我们所有的代码都可以正常工作,但对 RPM API 的调用最终会崩溃。如果 -lrpmio 早于我们的代码最终会崩溃,因为某些 Lua 调用最终会使用 librpmio 的 Lua 副本。
我尝试对 liblua.中的符号进行版本控制,以便我们使用如下版本脚本构建:
LUA_5.2 {
global:
lua_*;
luaL_*;
local: *;
};
然而这还不够,因为 librpmio.so 使用未版本化的符号,并且上面的版本脚本创建了符号的 LUA_5.2 版本以及“默认”版本。运行时绑定似乎更喜欢 liblua.so 中的未版本化符号而不是 librpmio.so,即使前者在链中更早:
19075: symbol=lua_pushlstring; lookup in file=output/Linux64/bin/myapp [0]
19075: symbol=lua_pushlstring; lookup in file=/home/output/Linux64/lib/lib1.so [0]
19075: symbol=lua_pushlstring; lookup in file=/home/output/Linux64/lib/lib2.so [0]
19075: symbol=lua_pushlstring; lookup in file=/home/output/Linux64/lib/lib3.so [0]
19075: symbol=lua_pushlstring; lookup in file=/home/lib/libwx_base-2.8.so.0 [0]
19075: symbol=lua_pushlstring; lookup in file=/home/lib/libsqlite.so [0]
19075: symbol=lua_pushlstring; lookup in file=/home/lib/libssl.so.0.9.8 [0]
19075: symbol=lua_pushlstring; lookup in file=/home/lib/libcrypto.so.0.9.8 [0]
19075: symbol=lua_pushlstring; lookup in file=/lib64/libacl.so.1 [0]
19075: symbol=lua_pushlstring; lookup in file=/usr/lib64/librpm-4.4.so [0]
19075: symbol=lua_pushlstring; lookup in file=/home/lib/liblua.so [0]
19075: binding file /usr/lib64/librpmio-4.4.so [0] to /home/lib/liblua.so [0]: normal symbol `lua_pushlstring'
请注意最后一行 - 它正在解析 librpmio 中的 lua_pushlstring 与我的 liblua 的绑定。
我可以通过在 librpmio.so 上设置-Bsymbolic标志来解决这个问题,但这是一个我们无法控制的系统库,谁知道可能会导致什么其他问题。如果我可以消除在 liblua.so 中创建每个 Lua 符号的默认版本,我想我可能能够解决这个问题,但我无法从版本脚本中弄清楚如何做到这一点。GNU版本的脚本__asm__
文档只展示了如何通过指令来做到这一点。
除了创建一个包含如下几行的文件并将其与我的 Lua 构建链接之外,还有其他人有什么想法吗?
__asm__(".symver lua_pushlstring,lua_pushlstring@LUA_5.2");