boost :: filesystem :: current_path()返回空路径

时间:2018-09-03 09:37:12

标签: c++11 boost path boost-filesystem conan

我有一个C ++程序,在这里我需要当前路径才能稍后创建文件夹。我的可执行文件的位置为/home/me/foo/bin。这是我运行的:

//Here I expect '/home/me/foo/bin/', but get ''
auto currentPath = boost::filesystem::current_path(); 

//Here I expect '/home/me/foo/', but get ''
auto parentPath = currentPath.parent_path();

//Here I expect '/home/me/foo/foo2/', but get 'foo2/'
string subFolder    = "foo2";
string folderPath   = parentPath.string() + "/" + subFolder + "/";

//Here I expect to create '/home/me/foo/foo2/', but get a core dump
boost::filesystem::path boostPath{ folderPath};
boost::filesystem::create_directories( boostPath); 

我在Ubuntu 16.04上运行,使用与软件包管理器Conan一起安装的Boost 1.66。

我曾经在不使用柯南的情况下使用Boost的早期版本(我相信是1.45)成功运行了此操作。 Boost通常只是安装在我的机器上。现在,我在运行create_directories( boostPath);时得到了一个核心转储。

两个问题:

  1. 为什么current_path()没有为我提供实际路径,而是返回并返回空路径?
  2. 即使current_path()不返回任何内容,即使使用sudo运行它,为什么仍会有一个核心转储?我不是可以简单地在根目录下创建文件夹吗?

编辑:

运行编译后的程序,在行之间有上述变量的cout输出,而不是使用调试模式,通常给我以下输出:

currentPath: ""
parentPath: ""
folderPath: /foo2/
Segmentation fault (core dumped)

但是有时(大约20%的时间)会给我以下输出:

currentPath: "/"
parentPath: "/home/me/fooA�[oFw�[oFw@"
folderPath: /home/me/fooA�[oFw�[oFw@/foo2/
terminate called after throwing an instance of 'boost::filesystem::filesystem_error'
  what():  boost::filesystem::create_directories: Invalid argument
Aborted (core dumped)

编辑2:

运行conan profile show default我得到:

[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=5
compiler.libcxx=libstdc++
build_type=Release
[options]
[build_requires]
[env]

1 个答案:

答案 0 :(得分:3)

在依赖项中使用的libcxx与您用来构建应用程序的那个之间有一些差异。

在g ++(Linux)中,可以使用2种标准库模式,libstdc++(未启用C ++ 11的情况下构建)和libstdc++11(已启用C ++ 11的情况下构建)。在构建可执行文件(应用程序或共享库)时,链接在一起的所有单个库都必须使用相同的libcxx链接。

  • libstdc++11已成为g ++> = 5的默认值,但这也取决于linux发行版。碰巧,即使您在较旧的发行版(如Ubuntu 14)中安装了g ++> = 5,默认的libcxx仍为libstdc++,显然要升级它而不破坏它并不容易。碰巧,开源软件中使用的非常流行的CI服务(例如travis-ci)也使用了较旧的Linux发行版,因此libstdc++链接是最受欢迎的。

  • libstdc++是g ++ <5的默认值。

出于历史和向后兼容性的原因,即使对于现代发行版中的现代编译器,柯南默认配置文件也始终使用libstdc++。您可以在第一次执行柯南时阅读默认配置文件,也可以在.conan/profiles/default中找到它作为文件,或与conan profile show default一起显示。这可能会在conan 2.0中(甚至更快)发生变化,并且如果可能,将为每个编译器检测到正确的libcxx

因此,如果您不更改默认配置文件(建议在生产中使用您自己的配置文件),则在执行conan install时,将根据libstdc++构建已安装的功能。请注意,在大多数情况下,此conan install与版本无关,它只是使用所需的配置(从默认配置文件中)下载,解压缩并配置所需的依赖项。

然后,在构建时,如果不更改_GLIBCXX_USE_CXX11_ABI,则可以使用系统编译器默认值,在这种情况下,将使用libstdc++11。在大多数情况下,会出现链接错误,显示出这种差异。但是,根据您的情况,您很不幸,您的应用程序成功进行了链接,但随后在运行时崩溃了。

有两种方法可以解决此问题:

  • 也使用libstdc++构建应用程序。确保定义_GLIBCXX_USE_CXX11_ABI=0
  • libstdc++11安装依赖项。编辑默认配置文件以使用libstdc++11,然后发出新的conan install并重建您的应用。