私の目標は単純です。root以外のユーザーとして、依存関係をできるだけ少なくして、任意のアーキテクチャでnixパッケージマネージャーをブートストラップするプログラムを作成したいと思います。今のところ、私がしたことは次のとおりです。ホストに、優れたArchを備えたミニマリストのAlpineバージョンをダウンロードします。それから私はそれを解凍し、それに「chroot」(実際にはproot)します。次に、ビルドのすべてのdepを(chrootに)インストールし、適切なオプションを使用してビルドしてから、ホスト上のファイルをコピーして戻します。
しかし、重要な問題があります。各システムには、「インタープリターファイル」(file
を実行したときに取得するもの)が異なる場所にあるようです。私のデビアンでは、/lib64/ld-linux-x86-64.so.2
にあります。しかし、アルパインでは/lib/ld-musl-x86_64.so.1
にあります。したがって、実行すると、File does not exists
のようなエラーが発生します(明らかに存在します)。
だからここに私の質問があります:インタープリターがすべての(または少なくともほとんどの)Linuxディストリビューションで確実に見つかるように、ツール(nixなど)をコンパイルするにはどうすればよいですか?それが不可能な場合は、どういうわけかシステムにchroot/prootして、ホストインタープリターを使用して、ホスト上のファイルをコピーして戻すと、インタープリターが適切なものになるようにできますか?
ありがとうございました!
この種の問題に対処するには3つの方法があります。
nix
を静的に構築できます。そうすれば、実行時にダイナミックリンカーを必要とせず、ほとんどどこでも機能します。 (これは、ライブラリの互換性の問題にもうまく対処します。)
nix
をターゲットlibcごとに1回、数回ビルドできます—現実的には、LinuxではGNU libcとmusl(多分 Dietlibcも)。ターゲット環境のlibcに応じて適切に使用できるバイナリを提供します。AlpineLinuxについてはわかりませんが、これはたとえばDebianで可能です。デフォルトのコンパイラを使用してビルドし、GNU libc、およびmusl-dev
パッケージをインストールし、musl-gcc
を使用してビルドしてmuslをターゲットにします。
doビルドすることを決定したバイナリの依存関係を指定し、それらをターゲット環境にインストールできます。たとえば、Alpine上に構築されたmuslベースのバイナリは、そこにmusl
パッケージをインストールすると、Debian派生物で実行しやすくなります。