Ошибки связывания с использованием элементов ‹filesystem› в C++17

Я использую gcc 7.2 в Ubuntu 16.04, и мне нужно использовать новую библиотеку файловой системы из C++17. Несмотря на то, что библиотека под названием Experimental/filesystem действительно существует, я не могу использовать ни одного из ее элементов. Например, когда я пытаюсь скомпилировать этот файл:

#include <iostream>
#include <string>
#include <experimental/filesystem>
using namespace std;
namespace fs = std::experimental::filesystem::v1;

int main(){
    fs::path p1 = "/usr/share/";
}

Я получаю ошибку компиляции, которая выглядит так:

$ g++-7 test.cpp -std=c++17
/tmp/ccfsMnlG.o: In function `std::experimental::filesystem::v1::__cxx11::path::path<char [12], std::experimental::filesystem::v1::__cxx11::path>(char const (&) [12])':
test.cpp:(.text._ZNSt12experimental10filesystem2v17__cxx114pathC2IA12_cS3_EERKT_[_ZNSt12experimental10filesystem2v17__cxx114pathC5IA12_cS3_EERKT_]+0x73): undefined reference to `st
d::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
collect2: error: ld returned 1 exit status

Что я делаю не так? Я не думаю, что с кодом что-то не так, так как я просто скопировал его с веб-сайта. Я использую неправильную версию gcc? Кроме того, зачем мне <experimental/filesystem> вместо <filesystem> в C++17? Заранее спасибо.


person Willie Jeng    schedule 11.02.2018    source источник
comment
См. gcc.gnu.org/projects/cxx-status.html.   -  person Basile Starynkevitch    schedule 11.02.2018
comment
Я бы рекомендовал использовать некоторые внешние библиотеки, такие как Boost или Poco или Qt, или проще использовать POSIX такие вызовы, как syscalls(2), особенно stat(2)...   -  person Basile Starynkevitch    schedule 11.02.2018
comment
@BasileStarynkevitch, первая ссылка, на которую вы указываете, ничего не говорит о поддержке файловой системы в GCC. На самом деле я не получаю совпадений при поиске строкового файла.   -  person mallwright    schedule 04.06.2018
comment
Это потому, что вам нужно проверить страницу о libstdС++, а не о самом g++. В нем указано, что поддержка <filesystem> запланирована в g++ 8: gcc.gnu.org/onlinedocs/libstdc++/manual/   -  person Maël Nison    schedule 02.09.2018


Ответы (3)


Добавьте флаг -lstdc++fs:

$ g++-7 test.cpp -std=c++17 -lstdc++fs

gcc 7.2 поддерживает только экспериментальное пространство имен C++17 filesystem. Я не знаю, может быть, gcc 7.3 уже поддерживает пространство имен std filesystem.

person S.M.    schedule 11.02.2018
comment
У меня есть gcc 7.3 в Arch Linux, и я все еще получаю ошибку компоновщика, даже с -lstdc++fs. - person petersohn; 25.04.2018
comment
У меня есть gcc 8.2, предназначенный для поддержки файловой системы. Я попытался добавить флаг, и начало вывода моего компилятора выглядит так: -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I.. Тем не менее, все вызовы функций явно не определены... Есть мысли? - person Iron Attorney; 19.10.2018
comment
@IronAttorney Пожалуйста, скопируйте и вставьте сообщения об ошибках компилятора. - person S.M.; 21.10.2018
comment
-lstdc++fs должен идти после ваших файлов .cpp в командной строке. Если вы используете make, добавьте его в свою переменную LDLIBS. - person krupan; 28.11.2018
comment
Что произойдет, если я добавлю, что скомпилирую ту же программу с помощью gcc 8? Сможет ли он получить доступ к экспериментальной/файловой системе? - person happy_sisyphus; 02.05.2019
comment
@SashankAryal Вам не нужен флаг -lstdc++fs для GCC 8, теперь он реализует <filesystem> с флагом -std=c++17. - person S.M.; 02.05.2019
comment
Я знаю это, но мой вопрос заключается в том, может ли Gcc 8 скомпилировать заголовок «experimental/filesystem», поскольку вместо него используется «filesystem». - person happy_sisyphus; 02.05.2019
comment
@SashankAryal Извините. Нет, префикс experimental/ должен быть удален. Как я уже сказал, GCC 8 теперь реализует «файловую систему». - person S.M.; 03.05.2019
comment
Но когда я пишу код библиотеки, я не знаю, какой компилятор будет использоваться для его компиляции, вот что я говорю. - person happy_sisyphus; 03.05.2019
comment
@SashankAryal Вы можете использовать макрос GCC_VERSION, он и другие описаны в руководстве GCC: gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html - person S.M.; 04.05.2019

Вы также можете sudo apt install g++-8 и использовать #include <filesystem> в качестве cppreference, описанного вместо #include <experimental/filesystem> в более старых версиях g++ и libstdc++.

Если я установлю gcc 8 в Ubuntu, будут ли у меня две разные библиотеки libstdc++ или будет обновлена ​​только оригинальная?

у вас, вероятно, будет два, хотя более новый должен работать как замена для старого.

Я заметил, что libstdc++-8-dev установлен вместе с g++-8.

Это работает для меня:

g++-8 -g -Wall -std=c++17 test.cpp -lstdc++fs

Кажется, что даже с g++-8 библиотека файловой системы не подключается автоматически, вам все равно нужно предоставить -lstdc++fs, а -std=c++17 также нужен на уровне языка.

person Rick    schedule 29.11.2018

Следующее сработало для меня:

В коде:

#include <filesystem>
namespace filesystem = std::filesystem;

В CMakeList:

set (CMAKE_CXX_FLAGS "-lstdc++fs -std=c++17")

В Ubuntu 18.04 с GCC 10.

person Aquarius_Girl    schedule 26.10.2020