ファイルが可搬化されたバイナリ

GROMACS (主に) は、再配置可能なバイナリの概念を実装しており、つまり、初期に CMAKE_INSTALL_PREFIX (または CPack によるバイナリパッケージング) にインストールした後、インストールツリー全体を別のフォルダに移動しても、GROMACS は追加の変更なしで引き続き動作します。このページでは、この仕組みの実装方法と、実装における既知の制限について説明しています。この情報は、コードを理解したり変更したりする必要がある開発者にとって特に役立ちますが、GROMACS のインストールまたはパッケージングを行う人々にも役立ちます。

関連する機能として、このコードに関連するすべての箇所で、実行可能ファイルがビルドツリーから直接実行できる状態である必要があるという点を考慮する必要があります。この場合、開発を容易にするために、データファイルもソースツリーから参照するようにする必要があります。

共有ライブラリの検索

GROMACS が動的リンクでビルドされている場合、実行可能ファイルを relocatable にするための最初のステップは、実行時に libgromacs を見つけられるようにすることです。 相对 RPATH をサポートするプラットフォームでは、これを使用して GROMACS の実行可能ファイルが libgromacs を同じインストールプレフィックスから見つけられるようにします。 これにより、実行可能ファイルとライブラリ間の相対的なフォルダ構造が維持されれば、リンク時に実行可能ファイルが完全に relocatable になります。

もし RPATH の仕組みが機能しない場合、GMXRC は、それにインストールされた libgromacs の絶対パスも LD_LIBRARY_PATH に追加します。 この仕組みがサポートされているプラットフォームでは、リンカがこの場所でライブラリを検索しますが、これはより堅牢ではありません。 たとえば、異なるバージョンの GROMACS への呼び出しを混在させる場合に問題が発生する可能性があります。 ただし、GMXRC は現在、絶対パスをハードコードしているため、移植できません。

ネイティブのWindowsでは、DLLは完全にサポートされていません。現在、DLLはMinGWでコンパイルできるだけで、Visual StudioやIntelコンパイラではコンパイルできません。この場合、DLLは``lib/``ディレクトリではなく``bin/``ディレクトリに配置されます(CMakeによって自動的に、``CMakeLists.txt``に記述された汎用的なバイナリタイプの割り当てに基づいて)。Windowsは実行可能ファイルからDLLを自動的に検索するため、正しいDLLは常に検出されます。

外部ライブラリの場合、標準のCMakeリンクメカニズムが使用され、外部依存関係のためのRPATHが実行ファイルに含まれています。Windowsでは、動的リンクを行う場合、ローダーが正しい外部ライブラリを見つけ出すために、追加の手間が必要となる場合があります。

開発時にテストを実行するために、ビルドツリーからビルドされたバイナリを実行できるように、標準のCMakeメカニズムを使用します。バイナリがビルドされたとき、RPATHはビルドツリーに設定され、インストール時にはCMakeによってバイナリのRPATHが最終的な(相対)値に書き換えられます。さらに、インストールツリーがビルドツリーと同じ相対フォルダー構造を持つ場合、最終的な相対RPATHは初期ビルド時にすでに使用されます。

RPATHの設定は、ルートにある CMakeLists.txt にあります。標準のCMake変数(例えば、CMAKE_SKIP_INSTALL_RPATH=ON を設定するなど)を使用して、インストール時にRPATHの使用を無効にすることができます。

データファイルの検索

その他の、GROMACS-固有の部分は、バイナリを relocatable (移動可能) にするために、インストールツリーからデータファイルを検索できるようにすることです。これらのデータファイルは、プログラム実行の末尾の引用符を表示するなど、複数の目的で使用されます。引用符データベースが見つからない場合、引用符は表示されませんが、他のファイル (主に gmx pdb2gmx および gmx grompp などのシステム準備ツール、および静的データ用のさまざまな分析ツールで使用されるファイル) が見つからない場合、致命的なエラーを引き起こします。

考慮すべき点はいくつかあります:

  • リロケーションが機能するためには、絶対パスに依存せず、実行中のコードの場所をシステム上で特定する必要があります。 その代替手段として、``GMXRC``などの環境変数を使用できます(ただし、現在では使用されていません)。

  • ビルドツリーから実行可能ファイルを実行する場合、関連するソースツリーからデータファイルを自動的に使用し、テストを容易にするようにするのが望ましいです。データファイルはビルドツリーにコピーされず、ユーザーはソースツリーとビルドツリーの相対的な場所を自由に選択できます。また、データファイルはソースツリーとインストールツリー(ソースツリーには share/top/、インストールツリーには share/gromacs/top/ があり、後者は CMake の構成時にカスタマイズ可能)で同じ相対パスには存在しません。

  • GROMACS の実行ファイルに加えて、libgromacs をリンクするプログラムは、ライブラリ内の特定の関数を呼び出す場合に、関連するデータファイルを特定できる必要があります。この場合、実行ファイルが GROMACS がインストールされているディレクトリとは異なる場所に存在する可能性があります。静的リンクの場合、コードのどの部分も GROMACS のインストールプレフィックスからロードされないため、外部の情報なしでデータファイルを特定することはできません。

  • ユーザーは常に GMXLIB 環境変数を活用して、データファイルの代替場所を指定できますが、理想的には、インストールからデータファイルを使用する際には、これを使用する必要は発生しないはずです。

上記のすべての考慮事項が現在の実装によって完全に解決されているわけではありません。現在の実装は、以下の手順で動作します。

  1. 現在の実行ファイルのパスを、「argv[0]」に基づいて特定します。 値にディレクトリが含まれている場合、これは絶対パスまたは現在の作業ディレクトリに対する相対パスとして解釈されます。 ディレクトリが含まれていない場合、「PATH」にリストされているディレクトリから、指定された名前のファイルが検索されます。 Windowsでは、「PATH」を検索する前に、現在のディレクトリも検索されます。 該当する名前のファイルが見つかった場合、追加の検証なしでそのファイルが使用されます。

  2. 実行ファイルが見つかり、それがシンボリックリンクである場合、シンボリックリンクは実際のファイルが見つかるまで辿られます。ただし、ディレクトリ名のリンクは解決されません。また、一部のリンクに相対パスが含まれている場合、最終的な結果には .. などの要素が含まれる可能性があります。

  3. もし実行ファイルの絶対パスが見つかった場合、コードは実行ファイルがビルド出力ディレクトリにあるかどうかを確認します(ディレクトリの構成に符号付きリンクがある可能性を考慮して、``stat()``などの関数を使用)。もしそうであれば、ハードコードされたソースツリーの場所が返されます。

  4. もし実行ファイルの絶対パスが見つかり、それがビルドツリーに含まれていない場合、すべての親ディレクトリがチェックされます。もし親ディレクトリに:file:share/{gromacs}/top/gurgle.dat が含まれている場合、そのディレクトリがインストールプレフィックスとして返されます。ファイル名「gurgle.dat」と場所が、正しいディレクトリが見つかっていることを保証するのに十分ユニークであるとみなされます。読み取り専用のアーキテクチャに依存しないデータファイルのインストールディレクトリは、CMakeの構成時に CMAKE_INSTALL_DATADIR を設定することでカスタマイズでき、このディレクトリ内の GROMACS-固有のデータがホストされるサブディレクトリは、GMX_INSTALL_DATASUBDIR で設定されます。

    注意: この検索はシンボリックリンクを解決したり、入力パスを事前に正規化したりしません。「..」が含まれるパスとシンボリックリンクがある場合、検索は予期しないディレクトリに移動する可能性がありますが、これは問題になるべきではありません。なぜなら、正しいインストールプレフィックスが、そのようなシンボリックリンクに遭遇する前に見つかるはずだからです(ただし、「bin/」ディレクトリがシンボリックリンクでない場合)。

  5. まだデータファイルが見つからなかった場合は、いくつかのハードコードされた推測を試してください(例:元のインストール時の CMAKE_INSTALL_PREFIX/usr/local/)。 適切なファイル(gurgle.dat)を含む最初の推測が返されます。

  6. もしそれでも何も見つからない場合は、CMAKE_INSTALL_PREFIX を返し、その後のデータファイルの読み込みを失敗させます。

上記の、インストールプレフィックスを特定するためのロジックは、src/gromacs/commandline/cmdlineprogramcontext.cpp にあります。 libgromacs をリンクするコードは、gmx::IProgramContext を使用してデータファイルの場所を特定するための代替実装を提供できます。 その場合、上記の考慮事項については、そのコードが完全に責任を負います。

使用されているデータディレクトリに関する情報は、コンソール出力(または -quiet オプションで実行された場合を除く)と、データファイルを見つけられない場合に表示される(一部の)エラーメッセージに表示され、問題の診断に役立ちます。

CMakeで上記で言及されている変数を使用する以外、この探索機能を無効化したり、コンパイル時にプロセスに影響を与える方法はありません。

既知の問題

  • GMXRC は移植不可です。スクリプト内で単一の代入で絶対インストールパスをハードコーディングしているため、移植後に動作しなくなります。現在サポートしているすべてのシェルで、この問題を解決するための貢献を歓迎します。

  • データファイルの検索にはバージョンチェックは行われません。検索に問題が発生した場合、|Gromacs|の別のインストールからのインストールプレフィックスが返される可能性があり、これにより、ファイルが欠落しているか無効であるという曖昧なエラーだけが表示されることがあります。

  • 「インストールプレフィックスの検索が失敗した場合、ハードコードされた絶対パスが使用され、そのうちの1つが選択されます。これらのパスには、libgromacs`のコンパイル時に使用された絶対パスである ``CMAKE_INSTALL_PREFIX` に含まれるパスが含まれますが、これはリロケート後に誤っている可能性があります。」

  • インストールプレフィックスの検索は、実行ファイルの場所を特定することに基づいています。これは、「libgromacs」にリンクしているが、同じプレフィックスにインストールされていないプログラムには機能しません。そのような場合は、ハードコードされた推測を使用するため、リロケート後も正しいデータファイルが見つかりません。ただし、呼び出しコードは、プログラム的に|Gromacs|のインストールプレフィックスを提供できますが、理想的には、呼び出しコードに処理を委ねることなく、この機能が動作するようにします。

  • 一つの解決策としては、上記の2つの問題を(部分的に)解決するために、``GMXDATA``という環境変数を、``GMXRC``によって設定されたものを使用する方法があります(現在、この環境変数は設定されていますが、非常にまれに使用されています)。

  • インストールされた pkg-config ファイルは、絶対パスをハードコードしているため、移動できません。