boost :: filesystem :: current_path () возвращает пустой путь - PullRequest
0 голосов
/ 03 сентября 2018

У меня есть программа на 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, использую Boost 1.66, установленный с менеджером пакетов Conan.

Раньше я успешно запускал это с предыдущей версией Boost (мне кажется, 1,45) без использования Conan. Boost был просто нормально установлен на моей машине. Теперь я получаю дамп ядра при запуске create_directories( boostPath);.

Два вопроса:

  1. Почему current_path() не предоставляет мне фактический путь, а вместо этого возвращает и пустой путь?
  2. Даже если current_path () ничего не вернул, почему у меня все еще есть дамп ядра, даже если я запускаю его с sudo? Разве я не могу просто создать папку (и) в корне?

Edit:

Запуская скомпилированную программу, имея несколько 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 голосов
/ 03 сентября 2018

Существует некоторое несоответствие между libcxx, используемым в зависимостях, и тем, которое вы используете для создания своего приложения.

В g ++ (linux) есть 2 стандартных режима библиотеки, которые вы можете использовать: libstdc++, созданный без включенного C ++ 11, и libstdc++11, построенный с включенным C ++ 11. Когда вы создаете исполняемый файл (приложение или совместно используемую библиотеку), все отдельные библиотеки, связанные вместе, должны связываться с одним и тем же libcxx.

  • libstdc++11 было установлено по умолчанию для g ++> = 5, но это также зависит от дистрибутива Linux. Бывает, что даже если вы установите g ++> = 5 в более старых дистрибутивах, таких как Ubuntu 14, по умолчанию libcxx все равно будет libstdc++, по-видимому, его нелегко обновить без поломок. Также бывает, что очень популярные сервисы CI, используемые в open source, такие как travis-ci, использовали более старые дистрибутивы linux, и, таким образом, libstdc++ linking был самым популярным.

  • libstdc++ по умолчанию для g ++ <5. </p>

По историческим причинам и из соображений обратной совместимости в профиле 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 и пересоберите свое приложение.
...