Makefile.PL を介して Linux ホストで DBD::Pg をビルドしようとしています。私の要件は、perl に対しては動的にリンクできる必要があるが、libpq.so に対しては静的にリンクできる必要があるというものです (すべてのボックスで利用できるわけではないため)。
これを行う簡単な方法はありますか?Makefile.PL の LIBS ディレクティブのリンク オプションを変更しようとしましたが、MakeMaker は私のオプションを無視します。
Makefile.PL を介して Linux ホストで DBD::Pg をビルドしようとしています。私の要件は、perl に対しては動的にリンクできる必要があるが、libpq.so に対しては静的にリンクできる必要があるというものです (すべてのボックスで利用できるわけではないため)。
これを行う簡単な方法はありますか?Makefile.PL の LIBS ディレクティブのリンク オプションを変更しようとしましたが、MakeMaker は私のオプションを無視します。
IMO 要件を誤って指定しました。
すべてのシステムで使用できるとは限らないという理由だけで、に静的にリンクする必要はありませlibpq
ん。
代わりに一般的にすべきことは、動的にリンクしlibq
LD_LIBRARY_PATH
てラッパースクリプトに設定するか、リンクを使用して見つけられるrpath
ようにすることです。libpq
ただし、静的リンクか動的リンクかにかかわらず、他のモジュールがlibpq
を同じ Perl にロードするlibpq
と、同じ実行可能ファイル (boom) にリンクされた 2 つの互換性のない が取得されるかlibpq
、コンパイルされたもの以外を使用するモジュールの 1 つが取得されることに注意してください。反対(ブームも)。rpath リンクを使用する場合、ld.so
がリンク スコープを認識しているため問題を回避できる可能性がありますが、設定LD_LIBRARY_PATH
によって問題が発生することはほぼ確実です。
rpath
での使用を検討することをお勧めします$ORIGIN
。
残念ながら、の静的リンクを試みてもlibpq
、問題全体を解決することはできません。
libpq
libc
それ自体は( )に依存する可能性がありますglibc
。それを静的にリンクし、他のモジュールを動的にリンクする場合は、 の 2 つのコピーがあることを意味しますlibc
。1 つは内部libpq
に、もう 1 つは Perl 自体によって参照され、動的にロードされます。これは非常に危険な状況です。特に、プロシージャが使用してメモリを割り当てmalloc
、ポインタを呼び出し元に戻す場合はそうです。の 1 つのコピーから malloc によって割り当てられたメモリlibc
がfree
、別のコピーによって 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