1

RPM ライブラリ (具体的には librpmio.so) にもリンクする必要がある場合、Lua (バージョン 5.2) を使用するプログラムを動作させるのにかなりの時間を費やしています。これは、Lua も使用する複数の共有ライブラリを持つ大規模なアプリケーションの一部です。

根本的な問題は、使用している librpmio.so のバージョン (4.4.X) に Lua インタープリターが組み込まれており、Lua コードに含まれるグローバル シンボルを隠していないことです。Lua の rpmio バージョンは、使用している Lua (5.2.x) よりも古い (5.0.2) ため、完全に互換性があるわけではありません。

これまでのところ、独自の Lua コードと RPM API 呼び出しの両方を機能させることができませんでした。lua_pushlstring() のような Lua API は、ロードされたモジュールのチェーンで最初に現れる liblua.so または librpmio.so にバインドします。リンカ コマンド ラインで -llua を先に指定すると、すべてのコードは正常に動作しますが、RPM API の呼び出しは最終的にクラッシュします。-lrpmio が私たちのコードよりも早い場合、一部の Lua 呼び出しが最終的に librpmio の Lua のコピーを使用するため、コードがクラッシュします。

liblua.so のシンボルをバージョン管理して、次のようなバージョン スクリプトを使用してビルドしようとしました。

LUA_5.2 {
    global:
            lua_*;
            luaL_*;

    local: *;
};

しかし、librpmio.so はバージョン管理されていないシンボルを使用し、上記のバージョン スクリプトはシンボルの LUA_5.2 バージョンと「デフォルト」バージョンを作成するため、それだけでは不十分でした。実行時バインディングは librpmio.so よりも liblua.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'

最後の行に注意してください。これは、liblua に対する librpmio 内の lua_pushlstring のバインディングを解決しています。

librpmio.so に-Bsymbolicフラグを設定することでこれを解決できますが、これは私たちが管理していないシステム ライブラリであり、他にどのような問題が発生するかは誰にもわかりません。liblua.so 内の各 Lua シンボルのデフォルト バージョンの作成を排除できれば問題を回避できると思いますが、バージョン スクリプトからそれを行う方法を理解できませんでした。GNUバージョンのスクリプト__asm__ドキュメントは、ディレクティブを介してそれを行う方法のみを示しています。

次のような一連の行を含むファイルを作成し、それを Lua のビルドにリンクする以外のアイデアはありますか?

__asm__(".symver lua_pushlstring,lua_pushlstring@LUA_5.2");
4

1 に答える 1

1

検索で私の質問に出くわした人のために、Lua ソースのコピーに多くの変更を加えずに問題を解決できた唯一の方法は、すべての RPM ライブラリを動的にロードすることでした。

__asm__バージョン管理されていないシンボルと一致させずにすべての Lua シンボルをバージョン管理する手法では、シンボルが定義されているソース モジュールにディレクティブを配置する必要があります__asm__。これは、多数の Lua ファイルへのパッチを意味します。

12 ~ 15 個の RPM API しか必要ないため、私が思いついた解決策は、librpmio、librpm、および librpmdb (後者は RPM <= 4.5 にのみ存在する) 共有ライブラリを dlopen() で動的にロードすることです。dlopen() を呼び出すとき、フラグに RTLD_NOW|RTLD_LOCAL|RTLD_DEEPBIND を指定します。これにより、RPM ライブラリ内の Lua (およびその他の) シンボルが内部的に解決されます。

dlsym() を使用して、使用する RPM API のアドレスを取得する必要がありますが、少なくともこれにより、librpmio の Lua が新しい Lua と衝突するのを防ぐことができます。

于 2013-02-27T13:19:10.487 に答える