5

ユーザーが自分でコンパイルする必要がないように、オープンソース プロジェクトのバイナリをコンパイルしようとしています。

1 つの 32 ビット ubuntu マシン「A」で作成された一部のバイナリが、32 ビット マシン「B」では機能せず、欠落している .so ファイルに関するエラーが報告されていることに気付きました。

ただし、マシン「B」で最初からコンパイルすると、すべてのエラーがなくなります。

ターゲット マシンでコードをコンパイルすると、これらのエラーがなくなる理由はありますか? 「./configure」と「make」のみを実行し、「make-install」は実行しなかったため、これらの .so ファイルをグローバルに利用できるようにしたわけではありません。

コンパイラが、システム ライブラリにない .so ファイルがあることを検出し、この場合、スタティック ライブラリを実行可能ファイルにリンクしている可能性がありますか?

i386 パッケージがすべての x86 マシンで実行されるように、Ubuntu はどのようにパッケージをコンパイルしますか?

4

4 に答える 4

6

この問題は「バイナリ互換性」と呼ばれていると思います (これらの問題に特化したスタック オーバーフローに関するタグがあります)。マシン上でバイナリをリンクすると、周囲の環境がバイナリに影響を与え、別のマシンで実行された後でも、コンパイルされた環境と同様の環境を見つけようとします。

この場合の異なる環境への耐性は、バイナリ互換性と呼ばれます。

それはどのように機能しますか?

ここで重要な点は、異なるマシンでリンカーに同じオプションを指定したとしても、異なるバイナリが得られる可能性があるということです。たとえば、共有ライブラリに対してバイナリをリンクすると-lfoo、ビルドするマシンにある の正確なバージョンfoo(たとえば、libfoo.so.5) がバイナリにハードコードされます。machineBで実行すると、 のみが含まれる可能性があり、不足しているso ファイルlibfoo.so.4が必要なため、バイナリは実行を拒否します。libfoo.so.5それが再コンパイルが役立つ理由であり、再コンパイルなしでは機能しません。

Ubuntu パッケージ (およびその他のディストリビューションのパッケージ) は、すべて同じ環境で (相互に) コンパイルされます。それが彼らがうまくインストールする理由です。また、ディストリビューション ベンダーは、次の各バージョンが以前のバージョンと下位互換性があることを確認しています。

私は何をすべきか?

ソフトウェアをさまざまなディストリビューションと互換性を持たせたい場合、思ったより簡単です。最初に、可能な限り古いディストリビューションでアプリケーションをコンパイルしてみてください。前に述べたように、最新のディストリビューションは通常下位互換性があるため、ソフトウェアはおそらく新しいディストリビューションで問題なく実行できます。

結果のパッケージをより徹底的にチェックし、互換性に関するアドバイスを得るには、無料のLinux アプリケーション チェッカーツールを使用できます。Linux ソフトをパッケージ化するための一般的なヒントにも興味があるかもしれません。

于 2011-02-10T22:04:19.550 に答える
3

マシン上でコードをコンパイルする場合、このマシン上でプログラムを実行すると、欠落しているライブラリに関するエラーはほとんど発生しません。configure の実行中に、必要なすべてのライブラリが検出され (これが configure や autotools などが存在する主な理由です)、-lsomelib や -I/some/include/patch などの適切なフラグが makefile に書き込まれ、コンパイラとリンカーに渡されます。 .

その実行可能ファイルを別のマシンにコピーすると、そのマシンにはライブラリのバージョンが間違っているか、まったくない可能性があるため、実行されない可能性があります。

configure スクリプトは、明示的に指示しない限り、通常は静的バイナリをビルドしません。

Ubuntu packages will not run on all x86 machines. But the package manager does a dependency resolution to make sure there are no wrong libraries or libraries missing, and refuses to install a package otherwise. If you force the install regardless of missing dependencies you might run in the same problems with missing libs again.

If you want to make sure that your package is able to on any machine, just link it static.

If it is sufficient to have it run on a specific distro (e. g. Ubuntu), you can create a package by yourself. This requires some more effort.

于 2011-02-10T21:42:49.257 に答える
2

Ermineのようなプロジェクトを使用して、動的にリンクされたネイティブ バイナリのディストリビューションを作成し、共有ライブラリを含めることができます。

それ以外では、コードを静的にコンパイルできます。これには、依存関係ツリー全体のソース コードを取得してコンパイルし、コードをビルドするときにそれらのコンパイル済みバイナリを参照する必要があります。他の共有ライブラリ (.so ファイル) に対して静的バイナリをコンパイルすることはできません。これは、特に依存関係に独自の依存関係がある場合は、非常に苦痛になる可能性があります。

于 2011-02-10T21:14:57.160 に答える
0

エラーが発生しやすいLD_LIBRARY_PATHアプローチ (ユーザーの操作も必要) または静的リンク (GPL によって常に可能または禁止されているとは限りません) の代わりに、相対パスをライブラリ検索パスとして使用することができます (DOS 時代から Windows で標準で提供されています)。$ORIGINリンカーでフラグを使用します。

完全なアプローチは、このブログ(アーカイブ版) でうまく説明されています。

于 2012-01-10T12:41:39.470 に答える