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

rag*_*got 3 boost path boost-filesystem c++11 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); 
Run Code Online (Sandbox Code Playgroud)

我在 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)
Run Code Online (Sandbox Code Playgroud)

有时(大约 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)
Run Code Online (Sandbox Code Playgroud)

编辑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]
Run Code Online (Sandbox Code Playgroud)

dro*_*dri 5

libcxx依赖项中使用的 和您用于构建应用程序的之间存在一些差异。

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

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

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

出于历史和向后兼容性的原因,conan 默认配置文件始终使用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并重建您的应用程序。