2

CMake を使用して C++ プロジェクトをコンパイルおよびテストしています。次のような構造があるとしましょう。

inc/
    ..
src/
    ..
data/
    dataFile

ファイルdataFileはコードからアクセスされ、<prefix>/shareまたは類似の下にインストールされます。私のコードでは、次のようなことを行います。

std::ifstream dataFile(DATAFILE_PATH);

CMake を使用して (ヘッダー テンプレート、コンパイル オプションなどを使用して)構成できることがわかっDATAFILE_PATHたので、コードにファイル パスを直接ハードコーディングする必要はありません。また、ファイルをインストール ツリーにインストールする方法と、ファイルをコピーしてファイルをビルド ツリーにコピーできることも知っています。たとえば、テストを実行したり、単にビルド ツリーから実行可能ファイルを実行したりできます。

dataFile私の質問は、プログラムをコンパイルし、ビルド ツリー (ビルドツリー内のコピーにアクセス)およびインストール ツリー (インストールされたdataFileコピーにアクセス)からプログラムをコンパイルして実行およびテストできるように、CMake または私の C++ コードをどのように構成すればよいかということ<prefix>/shareです。私が見逃している CMake に実装されているパターンやテクニックはありますか?

ありがとう。

4

1 に答える 1

1

私はこれに関する CMake の詳細を知らないので、おそらく最も簡単な解決策を提供していません。しかし、テストとインストールの間にプログラムを再コンパイルする必要のない、これを処理する 2 つの方法を考えることができます。

1 つ目は、単一のパスを使用するのではなく、それらのリストを使用し、正常に開くことができる最初のパスを使用することです。

const char* datafile_paths[] = { DATAFILE_PATH };
...
std::ifstream dataFile;
for(int i = 0; i < sizeof(datafile_paths)/sizeof(char*); i++)
{
    data.open(datafile_paths[i]);
    if(data.is_open()) break;
}
if(!data.is_open()) handle error;

ここで、DATAFILE_PATH は次のようになります。たとえば、"/foo/bar/data.dat"、"/foo/data.dat"、つまりコンマで区切られたパスのリストです。

もう 1 つは、代わりに環境変数を使用することです。一部のプロジェクトでは、これがより柔軟であり、ユーザーがリソース ファイルを保持する場所を選択できるため、好ましい場合があります。しかし、これは通常、.bashrc などを変更する必要があることを意味します。

char * datapath = getenv("MYPROJECT_DATAPATH");
if(!datapath) handle error;
std::ifstream data(datapath);

通常、この手法を単独で使用するのではなく、上記の手法と組み合わせて、最初に環境変数をチェックし、失敗した場合はコンパイルされたパス リストにフォールバックします。

于 2012-10-29T13:24:44.260 に答える