5

私は mkbundle を使用しており、Isis2 を使用する小さなプログラム IdaTester の組み込みバージョンを作成しようとしています。そのシステムは、MonoPosixHelper に依存する Mono の機能を使用します。

私の問題は、mkbundle が依存関係を認識せず、~/bin/lib/libMonoPosixHelper.so に対して動的にリンクする必要がある実行可能ファイルになってしまい、この実行可能ファイルをシステムに移動すると問題が発生することです。 Monoがインストールされています。実際、バンドルには、静的にリンクする必要があるものの 1 つが欠けています。

私の実行可能ファイルは機能しますが、動的ライブラリが「適切な場所」にあるマシンでのみ実行することを確認した場合に限ります。これは、組み込み実行可能ファイルの目的を無効にします...私は、このプログラムを、どこにでも置いてバイナリとして起動できる一種のサーバーとして人々に渡すことができることを望んでいました。これが機能するためにライブラリをインストールする必要がある場合は明らかです、サーバーは完全にスタンドアロンではありません!

プログラムが依存する dll ファイルを mkbundle に強制的に含める方法はわかりましたが、MonoPosixHelper は dll として存在しません。これは Linux 専用のライブラリであり、共有ライブラリとしてのみ存在します。バンドルを静的に埋め込むように「強制」する方法を知っている人はいますか?

これが役立つ場合、私の小さなコンパイル スクリプトは次のとおりです。

mcs -debug+ IdaTester.cs Isis.cs -r:System.dll -r:Microsoft.CSharp.dll -r:Mono.Posix.dll
mkbundle --static -o IdaTester IdaTester.exe --deps

次に、IdaTester を実行します。これは、libMonoPosixHelper ライブラリが見つかるプラットフォームでは機能しますが、libMonoPosixHelper がインストールされていないプラットフォームで実行している場合、そのライブラリを動的にロードしようとすると実行時に失敗します...

4

2 に答える 2

3

libMonoPosixHelper.so をアプリケーションと共に配布し、dll マップを変更してこれを機能させる必要があります。

問題の背景 - ライブラリは実行時に読み込まれます

libMonoPosixHelper は静的にリンクされていませんが、次の例のように P/Invoke 呼び出しとして検索およびロードされます。

    [DllImport ("MonoPosixHelper")]
    static extern int zipClose (ZipHandle handle, string globalComment);

つまり、コンパイル時ではなく実行時にのみ要求されるため、事前にリンクすることはできません。

修正 - libMonoPosixHelper.so の配布

4 つのステップが必要です。

  1. プログラムを配布するディレクトリに libMonoPosixHelper をコピーします。
  2. ハードコーディングされた場所を避けるために、DllMap 構成ファイルを更新します。
  3. mkbundle で設定ファイルを埋め込む
  4. インストール マシンの LD_LIBRARY_PATH に libMonoPosixHelper.so を含むパスを追加します。

それぞれを実行するには:

1. libMonoPosixHelper を、プログラムを配布するディレクトリにコピーします。

libMonoPosixHelper は通常 lib フォルダーにあります。tarball を作成するフォルダーにコピーするだけです。

cp $MONO_ROOT/lib/libMonoPosixHelper.so ~/MY_PROGRAM/

2. DllMap 構成ファイルを更新して、ハードコードされた場所を回避します。

これは、ハード コーディングされたパスの問題を回避するための重要なビットです。パスを指定しない mkbundle を含む構成ファイルを埋め込む必要があります。これを行うには、最初に mono 構成ファイルを見つけ、それをローカル ディレクトリにコピーします。

cp $MONO_ROOT/etc/mono/config ~/MY_PROGRAM/config

次に、このファイルを変更して dll の特定のパスを削除し、お気に入りのエディターで開いて、特定のプレフィックスを避けるようにパスを変更する必要があります。

<dllmap dll="MonoPosixHelper" target="MACHINE_SPECIFIC/lib/libMonoPosixHelper.dylib" os="!windows" />

<dllmap dll="MonoPosixHelper" target="libMonoPosixHelper.dylib" os="!windows" />

3. mkbundle で設定ファイルを埋め込む

次のオプションを mkbundle コマンドに追加して、新しく編集した構成ファイルを埋め込みます。

   --config MY_PROGRAM/config

4. libMonoPosixHelper.so を含むパスを、インストール マシンの LD_LIBRARY_PATH に追加します。

これで、mkbundled 実行可能ファイル、libMonoPosixHelper.so、および配布用のその他のファイルを圧縮できます。解凍してマシン上で実行すると、dlopen は他の dll と同様に libMonoPosixHelper.so を探すようになりました。したがって、配布されたバージョンの libMonoPosixHelper を含むディレクトリを LD_LIBRARY_PATH 環境変数に追加するだけです。

于 2015-10-08T18:54:18.030 に答える
1

私が知る限り、利用できる最善の選択肢は、現在 MonoPosixHelper.so にあるのと同じメソッドを含む非共有の Mono ライブラリを構築するか、MonoPosixHelper.so のコピーをコンポーネントとして提供することです。サーバーと同じフォルダにインストールされています。どちらも理想的とは思えません。前者は Mono ディストリビューションに「手を伸ばす」ことを余儀なくされ、長期的なメンテナンスの問題が発生します。一方、後者は、より複雑なディストリビューションとインストール モードを強いられます。しかし、共有ライブラリを生成すると、そのバージョンのライブラリに対して静的にリンクすることはできないようです。Linux ローダーは、より多くの標準ライブラリを処理する方法で、そのようなものをライブラリとして扱いません。

対照的に、同じ .o ファイルから標準ライブラリを生成した場合、ローダーは喜んでそれに対して静的にリンクします。mxbundle は最終的に cc を実行し、標準の ld を使用するため、そのオプションが機能します。それが私の質問に対する答えだと思います。

于 2013-08-29T13:29:39.993 に答える