c++11 - boost::filesystem::current_path() 返回空路径

标签 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)成功地运行了这个,而不使用 Conan。 Boost 通常安装在我的机器上。我现在在运行 create_directories( boostPath); 时获得核心转储。

两个问题:

  1. 为什么 current_path() 不向我提供实际路径,而是返回空路径?
  2. 即使 current_path() 什么也没返回,为什么即使我使用 sudo 运行它,我仍然会有核心转储?难道我不应该简单地在根目录下创建文件夹吗?

编辑:

运行编译后的程序,在行之间放置上述变量的一些 cout 输出而不是使用 Debug模式,通常会给出以下输出:

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]

最佳答案

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

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

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

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

出于历史和向后兼容性的原因,conan 默认配置文件始终使用 libstdc++,即使对于现代发行版中的现代编译器也是如此。您可以在第一次执行 conan 时读取默认配置文件,也可以在 .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 并重建您的应用。

关于c++11 - boost::filesystem::current_path() 返回空路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52147033/

相关文章:

重载 I/O 运算符时的 C++ unicode 框字符绘制

c++ - 将 glm::vec3 与 boost 多精度 float 相乘

c++ - 包含字符串的结构的 Boost Interprocess vector 是否需要特殊分配器?

c++ - unix 时间戳到 boost::posix_time::ptime

将Windows短路径转换为长路径的Ruby方法?

c++ - 无法将 std::tuple 初始化为 std::pair?

c++ - 类型检测 : using variadic arguments to properly implement a function that calculates the mean

linux - 如何获取文件的完整路径?

python - 使用 os.path.join 构建向上路径时,如何避免连续出现大量 os.pardir?

c++ - g++ 4.4.7 -std=gnu++0x 应该编译 "for each"构造吗?