web-dev-qa-db-ja.com

Linuxで非ルートとして別の(新しい)glibc / gcc / ...スタックを維持するにはどうすればよいですか

私たちの計算クラスターは、古いカーネル(2.6.18)と、もちろん古いライブラリとバイナリを備えた、非常に古いバージョンのCentOSを実行します。すべてを更新するには、すべてのノードで多くの作業が必要になるため、これはオプションではありません。

C++11を必要とするプログラムをコンパイルして使用しようとしています。そのため、gcc(またはclang)の新しいバージョンを使用しています。私はシステムをいじりたくないので、ローカルディレクトリツリーの非rootユーザーとしてこれを実行したいと思います。

問題は、gccには、マシンに存在するものよりも新しいglibcが必要であることです。したがって、おそらく here で説明されているように、ローカルのlib/ツリーでglibcの別の新しいバージョンを維持する必要があります。

私が失われた場所は、ローカルライブラリのパスをすべての必要なバイナリ、つまりgccg++などに「ハードコード」する方法ですか。 LD_LIBRARY_PATHをローカルのlib/ツリーに設定すると、すべてのシステムバイナリ(ELF file OS ABI invalid)が機能しなくなります。これは、新しいlibm.so/libc.soを使用したくないためです。編集済み。

まとめると、古いシステムと並行して、新しいローカルの開発スタック(glibcgccなどを含む)をrootとしていじらずに維持する適切な方法は何ですか?

副次的な質問として:LD_LIBRARY_PATHの設定は、glibcを分離する場合、SE全体で解決策として投稿されます。私にとって、システムバイナリ(lsなど)を実行しようとすると、上記のエラーが発生します。どうして?私は何か間違ったことをしましたか、これは意図された動作ですか?

10
janoliver

基本的に3つのオプションがあります。

  1. ライブラリを囲むラッパーを使用すると、LD_LIBRARY_PATH適切に実行してから、目的のライブラリを実行します。

    #!/bin/sh
    export LD_LIBRARY_PATH="path/goes/here"
    exec "$@"
    
  2. とのリンク -rpath-Wl,rpath)は、ダイナミックリンカーの検索パスをバイナリに追加します( SO answer も参照してください-ラッパーについても言及しています)。

  3. これを読むのは好きではありません:更新yourクラスター(「your」に重点を置いていることに注意してください)。それはいつか行われなければならないので、なぜ今日ではないでしょう。 「オプションではない」は、ほとんどの場合少し強いです。他のユーザーもおそらく同じ問題を抱えています。

問題のある古いバイナリについて-バイナリには、優先される動的リンカーが埋め込まれています。そして、古いダイナミックリンカは新しいABIを理解しません。次のようにバイナリを呼び出してみてください:path/to/your/ld-linux-<Arch>.so binary

GCCのビルド:GCCのビルド環境でいつでもCFLAGSをエクスポートしてみることができますが、確実に伝搬されます。さまざまなディストリビューションのビルドスクリプトを使用すると、いくつかの手掛かりが得られる場合があります(たとえば、openSUSEの場合は 。specファイル の1880行目を見てください)。

10
peterph