Błąd konsolidatora Experimental :: filesystem

98

Staram się używać nowych funkcji c ++ 1z na czele rozwoju w gcc 6.0.

Jeśli spróbuję tego małego przykładu:

#include <iostream>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
int main()
{
    fs::path p1 = "/home/pete/checkit";

    std::cout << "p1 = " << p1 << std::endl;
}

Mam:

/ opt / linux-gnu_6-20151011 / bin / g ++ --std = c ++ 1z main.cpp -O2 -g -o go
/tmp/ccaGzqFO.o: In function \ `std :: experimental :: filesystem :: v1 :: __ cxx11 :: path :: path (char const (&) [36]) ':
/opt/linux-gnu_6-20151011/include/c++/6.0.0/experimental/bits/fs_path.h:167: niezdefiniowane odniesienie do `std :: experimental :: filesystem :: v1 :: __ cxx11 :: path :: _ M_split_cmpts () ”
collect2: error: ld zwrócił 1 status wyjścia

Wersja gcc to migawka linux-gnu_6-20151011

Jakieś wskazówki, jak utworzyć link do nowych funkcji C ++ 1z?

Klaus
źródło

Odpowiedzi:

161

Filesystem TS nie ma nic wspólnego z obsługą C ++ 1z, jest to całkowicie oddzielna specyfikacja, która nie jest częścią roboczej wersji C ++ 1z. Implementacja GCC (w GCC 5.3 i nowszych) jest nawet dostępna w trybie C ++ 11.

Aby -lstdc++fsgo użyć, wystarczy połączyć się z .

(Odpowiednia biblioteka libstdc++fs.ajest biblioteką statyczną, więc tak jak w przypadku każdej biblioteki statycznej powinna znajdować się po obiektach, które są od niej zależne w poleceniu konsolidatora).

Aktualizacja listopad 2017: oprócz Filesystem TS, GCC 8.x posiada również implementację biblioteki C ++ 17 Filesystem, zdefiniowanej <filesystem>w przestrzeni nazw i w przestrzeni nazw std::filesystem(uwaga: brak „eksperymentalnego” w tych nazwach) podczas używania -std=gnu++17lub -std=c++17. Obsługa GCC C ++ 17 nie jest jeszcze kompletna ani stabilna i dopóki nie zostanie uznana za gotową do użytku w czasie największej oglądalności, musisz również połączyć się -lstdc++fsz funkcjami systemu plików C ++ 17.

Aktualizacja, styczeń 2019: począwszy od GCC 9, std::filesystemkomponenty C ++ 17 mogą być używane bez -lstdc++fs(ale nadal potrzebujesz tej biblioteki std::experimental::filesystem).

Jonathan Wakely
źródło
2
Czy to jest gdzieś udokumentowane, próbowałem to ustalić sam i nie wyszedłem bez niczego, czy przegapiłem tutaj jakieś źródło?
Shafik Yaghmour
2
Kiedy próbuję tego użyć, pojawia się ten sam błąd konsolidatora. c++ -lstd++fs main.cpp. Używamgcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)
alfC
15
ok, -lstdc++fsmusi znajdować się na końcu linii (przynajmniej za plikiem źródłowym). Nie rozumiem, dlaczego niektórzy -lxxxmuszą być na końcu, a inni nie.
alfC
5
@alfC, ponieważ tak działają konsolidatory. Odniesienia są rozwiązywane od lewej do prawej, więc należy wyświetlić biblioteki statyczne po obiektach, które ich używają.
Jonathan Wakely
35

Jeśli używasz cmake, dodaj następujący wiersz do CMakeLists.txt:

link_libraries(stdc++fs)

Dzięki temu cmake może łączyć się z odpowiednią biblioteką.

Searene
źródło
12
Zrobiłem target_link_libraries(hello_world_ stdc++fs)i skompilowałem.
sunapi386
14

W przypadku clang 4.0+ musisz połączyć się z libc++experimental.a

Upewnij się, że tworzysz za pomocą libc ++ (nie libstdc ++) z opcją -stdlib = libc ++ (jak wspomniano w komentarzach)

xaxxon
źródło
Potrzebowałem również -stdlib = libc ++, ponieważ moja wersja clang nieoczekiwanie korzystała z libstdc ++.
Bowie Owens
@BowieOwens thanks, zaktualizowana odpowiedź, aby to wyjaśnić.
xaxxon,
Kiedy mówisz „upewnij się, że budujesz za pomocą libc ++”, jak mam to zrobić? (Rozwiązanie najlepiej z CMake.). Dzięki.
mannyglover
1
@mannyglover -stdlib=libc++ lubset(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
xaxxon
4

Oto demo, które może być pomocne dla kogoś w przyszłości:

env: el6,gcc/5.5.0

#include <iostream>
#include <string>
#include <experimental/filesystem>

int main()
{
    std::string path = std::experimental::filesystem::current_path();

    std::cout << "path = " << path << std::endl;
}

Poniżej znajduje się kompilacja i testowanie. Flagi to -std=c++17 -lstdc++fs:

$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/apps/gcc-5.5.0/bin/../libexec/gcc/x86_64-unknown-linux-gnu/5.5.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../configure --prefix=/apps/gcc-5.5.0 --disable-multilib --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-languages=all
Thread model: posix
gcc version 5.5.0 (GCC)

$ ls -lrt /apps/gcc-5.5.0/lib64 | grep libstdc
-rwxr-xr-x. 1 root root  11272436 Jun 25 10:51 libstdc++.so.6.0.21
-rw-r--r--. 1 root root      2419 Jun 25 10:51 libstdc++.so.6.0.21-gdb.py
-rwxr-xr-x. 1 root root       976 Jun 25 10:51 libstdc++.la
-rwxr-xr-x. 1 root root  11272436 Jun 25 10:51 libstdc++.so
-rw-r--r--. 1 root root  10581732 Jun 25 10:51 libstdc++fs.a
-rw-r--r--. 1 root root  28985412 Jun 25 10:51 libstdc++.a
-rwxr-xr-x. 1 root root       916 Jun 25 10:51 libstdc++fs.la
-rwxr-xr-x. 1 root root  11272436 Jun 25 10:51 libstdc++.so.6

$ g++ filesystem-testing.cpp -lstdc++fs -std=c++17
$ ./a.out

$ g++ -std=c++17 filesystem-testing.cpp -lstdc++fs
$ ./a.out
path = /home/userid/projects-c++/filesystem-testing

Działa również z flagami: -std=c++11

$ g++ -std=c++11 filesystem-testing.cpp -lstdc++fs
$ ./a.out
path = /home/userid/projects-c++/filesystem-testing

Poniżej wystąpił błąd kompilacji _ZNSt12experimental10filesystem2v112current_pathB5cxx11Ev

$ g++ -std=c++17 -lstdc++fs filesystem-testing.cpp
/tmp/ccA6Q9oF.o: In function `main':
filesystem-testing.cpp:(.text+0x11): undefined reference to `_ZNSt12experimental10filesystem2v112current_pathB5cxx11Ev'
collect2: error: ld returned 1 exit status
caot
źródło