访问构建树中的外部文件以进行测试

时间:2012-10-29 12:14:33

标签: c++ testing cmake

我正在使用CMake编译和测试C ++项目。假设我有这样的结构:

inc/
    ..
src/
    ..
data/
    dataFile

可以从代码访问文件dataFile,并将其安装在<prefix>/share或类似内容下。在我的代码中,我做了类似的事情:

std::ifstream dataFile(DATAFILE_PATH);

我知道我可以使用CMake配置DATAFILE_PATH(使用标题模板,或编译选项,或任何其他内容),因此我不必直接在代码中对文件路径进行硬编码。此外,我知道如何将文件安装到安装树,并且可以将文件复制到复制文件以构建树,例如运行测试,只需从构建树运行可执行文件。

我的问题是,我应该如何配置CMake,或者我的C ++代码,以便我可以编译我的程序并从构建树运行并测试它(访问构建树中的dataFile副本)来自安装树(访问dataFile下的<prefix>/share已安装副本)?在CMake中是否有任何我缺失的模式或技术?

感谢。

1 个答案:

答案 0 :(得分:1)

我不知道关于此的CMake细节,所以也许我没有给你最简单的解决方案。但我可以想到两种处理方法,不需要在测试和安装之间重新编译程序。

首先是不使用单个路径,而是使用它们的列表,并使用可以成功打开的第一个路径。

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”,即以逗号分隔的路径列表。

另一种是使用环境变量。对于某些项目,这可能是首选,因为它更灵活,让用户选择保存资源文件的位置。但它通常意味着.bashrc或类似需要修改,这有点icky。

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

通常一个人不会单独使用这种技术,而是将它与上面的技术结合起来,首先检查环境变量,如果失败则回退到编译路径列表中。