boost::filesystem::current_path() returns 空路径
boost::filesystem::current_path() returns empty path
我有一个 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。
我曾经 运行 在没有使用 Conan 的情况下使用以前版本的 Boost(我相信是 1.45)成功地做到了这一点。 Boost 通常安装在我的机器上。我现在在 运行ning create_directories( boostPath);
.
时得到一个核心转储
两个问题:
- 为什么
current_path()
不向我提供实际路径,而是 returns 和空路径?
- 即使 current_path() 什么也没返回,为什么即使我用 运行 和
sudo
我仍然有一个核心转储?难道我不能简单地在根目录下创建文件夹吗?
编辑:
运行 编译后的程序,在两行之间有一些 cout
上述变量的输出,而不是使用调试模式,normally 给了我以下输出:
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]
依赖项ci中使用的 libcxx
与您用于构建应用程序的 libcxx
之间存在一些差异。
在 g++ (linux) 中,您可以使用 2 种标准库模式,libstdc++
,未启用 C++11 构建,以及 libstdc++11
,使用 C++ 构建11 启用。当您构建可执行文件(应用程序或共享库)时,所有单独的库 link 必须 link 具有相同的 libcxx
。
libstdc++11
是 g++ >= 5 的默认设置,但这也取决于 linux 发行版。碰巧即使你在像 Ubuntu 14 这样的旧发行版中安装了 g++ >=5,默认的 libcxx
仍然是 libstdc++
,显然要升级它而不破坏它并不容易。也发生在开源中非常流行的 CI 服务,如 travis-ci,使用较旧的 linux 发行版,因此 libstdc++
linkage 是最受欢迎。
libstdc++
是 g++ < 5 的默认设置。
出于历史和向后兼容性的原因,柯南默认配置文件始终使用 libstdc++
,即使对于现代发行版中的现代编译器也是如此。您可以在第一次执行 conan 时读取您的默认配置文件,也可以在 .conan/profiles/default
中找到它作为一个文件,或者用 conan profile show default
显示它。这可能会在柯南 2.0(或更早)中发生变化,并且如果可能的话,将为每个编译器检测到正确的 libcxx
。
因此,如果您不更改默认配置文件(建议在生产环境中使用您自己的配置文件),那么当您执行 conan install
时,安装的 depedencies 是针对libstdc++
。请注意,此 conan install
在大多数情况下独立于构建,它只是下载、解压缩和配置所需的依赖项ci,并使用请求的配置(来自默认配置文件)。
然后,在构建时,如果不更改 _GLIBCXX_USE_CXX11_ABI,则可以使用系统编译器默认值,在本例中为 libstdc++11
。在大多数情况下,会出现一个 linking 错误来显示这种差异。但在你的情况下,你很不幸,你的应用程序设法 link,但随后在运行时崩溃了。
有几种方法可以解决这个问题:
- 也可以使用
libstdc++
构建您的应用程序。确保定义 _GLIBCXX_USE_CXX11_ABI=0
.
- 安装
libstdc++11
的依赖项cies。编辑您的默认配置文件以使用 libstdc++11
,然后发布新的 conan install
并重建您的应用程序。
我有一个 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。
我曾经 运行 在没有使用 Conan 的情况下使用以前版本的 Boost(我相信是 1.45)成功地做到了这一点。 Boost 通常安装在我的机器上。我现在在 运行ning create_directories( boostPath);
.
两个问题:
- 为什么
current_path()
不向我提供实际路径,而是 returns 和空路径? - 即使 current_path() 什么也没返回,为什么即使我用 运行 和
sudo
我仍然有一个核心转储?难道我不能简单地在根目录下创建文件夹吗?
编辑:
运行 编译后的程序,在两行之间有一些 cout
上述变量的输出,而不是使用调试模式,normally 给了我以下输出:
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]
依赖项ci中使用的 libcxx
与您用于构建应用程序的 libcxx
之间存在一些差异。
在 g++ (linux) 中,您可以使用 2 种标准库模式,libstdc++
,未启用 C++11 构建,以及 libstdc++11
,使用 C++ 构建11 启用。当您构建可执行文件(应用程序或共享库)时,所有单独的库 link 必须 link 具有相同的 libcxx
。
libstdc++11
是 g++ >= 5 的默认设置,但这也取决于 linux 发行版。碰巧即使你在像 Ubuntu 14 这样的旧发行版中安装了 g++ >=5,默认的libcxx
仍然是libstdc++
,显然要升级它而不破坏它并不容易。也发生在开源中非常流行的 CI 服务,如 travis-ci,使用较旧的 linux 发行版,因此libstdc++
linkage 是最受欢迎。libstdc++
是 g++ < 5 的默认设置。
出于历史和向后兼容性的原因,柯南默认配置文件始终使用 libstdc++
,即使对于现代发行版中的现代编译器也是如此。您可以在第一次执行 conan 时读取您的默认配置文件,也可以在 .conan/profiles/default
中找到它作为一个文件,或者用 conan profile show default
显示它。这可能会在柯南 2.0(或更早)中发生变化,并且如果可能的话,将为每个编译器检测到正确的 libcxx
。
因此,如果您不更改默认配置文件(建议在生产环境中使用您自己的配置文件),那么当您执行 conan install
时,安装的 depedencies 是针对libstdc++
。请注意,此 conan install
在大多数情况下独立于构建,它只是下载、解压缩和配置所需的依赖项ci,并使用请求的配置(来自默认配置文件)。
然后,在构建时,如果不更改 _GLIBCXX_USE_CXX11_ABI,则可以使用系统编译器默认值,在本例中为 libstdc++11
。在大多数情况下,会出现一个 linking 错误来显示这种差异。但在你的情况下,你很不幸,你的应用程序设法 link,但随后在运行时崩溃了。
有几种方法可以解决这个问题:
- 也可以使用
libstdc++
构建您的应用程序。确保定义_GLIBCXX_USE_CXX11_ABI=0
. - 安装
libstdc++11
的依赖项cies。编辑您的默认配置文件以使用libstdc++11
,然后发布新的conan install
并重建您的应用程序。