2

Makefile.PL を介して Linux ホストで DBD::Pg をビルドしようとしています。私の要件は、perl に対しては動的にリンクできる必要があるが、libpq.so に対しては静的にリンクできる必要があるというものです (すべてのボックスで利用できるわけではないため)。

これを行う簡単な方法はありますか?Makefile.PL の LIBS ディレクティブのリンク オプションを変更しようとしましたが、MakeMaker は私のオプションを無視します。

4

2 に答える 2

2

IMO 要件を誤って指定しました。

すべてのシステムで使用できるとは限らないという理由だけで、に静的にリンクする必要はありませlibpqん。

代わりに一般的にすべきことは、動的にリンクしlibqLD_LIBRARY_PATHてラッパースクリプトに設定するか、リンクを使用して見つけられるrpathようにすることです。libpq

ただし、静的リンクか動的リンクかにかかわらず、他のモジュールがlibpqを同じ Perl にロードするlibpqと、同じ実行可能ファイル (boom) にリンクされた 2 つの互換性のない が取得されるかlibpq、コンパイルされたもの以外を使用するモジュールの 1 つが取得されることに注意してください。反対(ブームも)。rpath リンクを使用する場合、ld.soがリンク スコープを認識しているため問題を回避できる可能性がありますが、設定LD_LIBRARY_PATHによって問題が発生することはほぼ確実です。

rpathでの使用を検討することをお勧めします$ORIGIN

于 2013-01-15T03:08:05.130 に答える
2

残念ながら、の静的リンクを試みてもlibpq、問題全体を解決することはできません。

libpqlibcそれ自体は( )に依存する可能性がありますglibc。それを静的にリンクし、他のモジュールを動的にリンクする場合は、 の 2 つのコピーがあることを意味しますlibc。1 つは内部libpqに、もう 1 つは Perl 自体によって参照され、動的にロードされます。これは非常に危険な状況です。特に、プロシージャが使用してメモリを割り当てmalloc、ポインタを呼び出し元に戻す場合はそうです。の 1 つのコピーから malloc によって割り当てられたメモリlibcfree、別のコピーによって ed である場合、プログラム (および Perl) は間違いなくクラッシュします。

つまり、静的にしたい場合は、最後までやり遂げる必要があります。すべてを 100% 静的にコンパイルする必要があるためlibc、アプリケーションで使用される のコピーは 1 つだけです。そして、その逆です。あなたが動的であれば、 のコピーを 1 つしか使用しないように、すべてが動的でなければなりませんlibc。これらのルールは、ライブラリが from を使用しない場合libc( さえも使用しない場合sprintf) にのみ適用されません。

静的コンパイルに成功して動作する場合でもlibpq(あまり可能性は高くありません)、DBIがインストールされていない場合はどうなりますか? DBI がデフォルトで存在しない Linux ボックスを十分に見てきました。では、DBI も静的にコンパイルしますか? が存在しない場合Perl(Linux ではありそうにないため)、または非常に古い場合はどうなりますか?

適切な解決策は、ネイティブ OS パッケージ マネージャーを使用してインストールすることです。

sudo apt-get install libdbd-pg-perl   # Ubuntu/Debian
sudo yum install perl-DBD-Pg          # Redhat/Fedora

問題のホストにルートがない場合は、使用を検討する必要がありperlbrewます-独自のPerlをホームディレクトリにインストールします。これにより、独自の のコピーをコンパイルし、動的にlibpq提供される Perl とリンクできるはずです。perlbrew

于 2013-01-15T05:07:55.913 に答える