experimenteller :: Dateisystem-Linker-Fehler

94

Ich versuche, die neuen c ++ 1z-Funktionen tatsächlich auf dem Kopf der Entwicklung in gcc 6.0 zu verwenden.

Wenn ich dieses kleine Beispiel versuche:

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

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

Ich habe:

/ opt / linux-gnu_6-20151011 / bin / g ++ --std = c ++ 1z main.cpp -O2 -g -o go
/tmp/ccaGzqFO.o: In der Funktion \ `std :: experimentelle :: Dateisystem :: v1 :: __ cxx11 :: Pfad :: Pfad (char const (&) [36]) ':
/opt/linux-gnu_6-20151011/include/c++/6.0.0/experimental/bits/fs_path.h:167: undefinierter Verweis auf `std :: experimentelle :: Dateisystem :: v1 :: __ cxx11 :: Pfad :: _ M_split_cmpts () '
collect2: error: ld hat 1 Exit-Status zurückgegeben

gcc version ist der snapshot linux-gnu_6-20151011

Irgendwelche Hinweise, wie man für die neuen c ++ 1z-Funktionen verlinkt?

Klaus
quelle

Antworten:

154

Das Dateisystem TS hat nichts mit der Unterstützung von C ++ 1z zu tun. Es ist eine völlig separate Spezifikation, die nicht Teil des C ++ 1z-Arbeitsentwurfs ist. Die Implementierung von GCC (in GCC 5.3 und höher) ist sogar im C ++ 11-Modus verfügbar.

Sie müssen nur eine Verknüpfung herstellen -lstdc++fs, um es zu verwenden.

(Die relevante Bibliothek libstdc++fs.aist eine statische Bibliothek. Wie bei jeder statischen Bibliothek sollte sie nach allen Objekten kommen, die im Linker-Befehl davon abhängen.)

Update Nov 2017: Neben dem Dateisystem TS verfügt GCC 8.x auch über eine Implementierung der C ++ 17-Dateisystembibliothek, die im <filesystem>und im Namespace definiert ist std::filesystem(NB kein "experimentelles" in diesen Namen), wenn -std=gnu++17oder verwendet wird -std=c++17. Die C ++ 17-Unterstützung von GCC ist noch nicht vollständig oder stabil. Bis zur Verwendung zur Hauptsendezeit müssen Sie auch eine Verknüpfung zu -lstdc++fsden C ++ 17-Dateisystemfunktionen herstellen.

Update Januar 2019: Ab GCC 9 können die C ++ 17- std::filesystemKomponenten ohne verwendet werden -lstdc++fs(für die Sie diese Bibliothek jedoch noch benötigen std::experimental::filesystem).

Jonathan Wakely
quelle
2
Ist dies irgendwo dokumentiert, ich habe versucht, dies selbst festzustellen und bin auf nichts gestoßen. Habe ich hier eine Ressource verpasst?
Shafik Yaghmour
2
@ShafikYaghmour, ich habe gerade die Dokumente aktualisiert: gcc.gnu.org/onlinedocs/libstdc++/manual/… gcc.gnu.org/onlinedocs/libstdc++/manual/… gcc.gnu.org/onlinedocs/libstdc++/manual/… (unten)
Jonathan Wakely
2
Wenn ich versuche, dies zu verwenden, erhalte ich den gleichen Linkerfehler. c++ -lstd++fs main.cpp. Ich benutzegcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)
alfC
14
ok, -lstdc++fsmuss am Ende der Zeile stehen (mindestens nach der Quelldatei). Ich verstehe nicht, warum einige -lxxxam Ende sein müssen und andere nicht.
AlfC
5
@alfC, denn so funktionieren Linker. Verweise werden von links nach rechts aufgelöst, sodass Sie statische Bibliotheken nach den Objekten auflisten müssen, die sie verwenden.
Jonathan Wakely
31

Wenn Sie cmake verwenden, fügen Sie die folgende Zeile hinzu CMakeLists.txt:

link_libraries(stdc++fs)

Damit kann cmake mit der entsprechenden Bibliothek verknüpfen.

Searene
quelle
9
Ich habe target_link_libraries(hello_world_ stdc++fs)und es kompiliert.
Sunapi386
13

Mit clang 4.0+ müssen Sie dagegen verlinken libc++experimental.a

Stellen Sie sicher, dass Sie mit libc ++ (nicht libstdc ++) mit -stdlib = libc ++ erstellen (wie in den Kommentaren erwähnt).

xaxxon
quelle
Ich brauchte auch -stdlib = libc ++, weil meine Clang-Version unerwartet libstdc ++ verwendete.
Bowie Owens
@ BowieOwens danke, aktualisierte Antwort, um das klar zu machen.
Xaxxon
Wie mache ich das, wenn Sie sagen "Stellen Sie sicher, dass Sie mit libc ++ erstellen"? (Lösung vorzugsweise mit CMake.) Vielen Dank.
Mannyglover
1
@mannyglover -stdlib=libc++ oderset(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
xaxxon
3

Hier ist eine Demo, die in Zukunft für jemanden hilfreich sein könnte:

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;
}

Im Folgenden werden kompiliert und getestet. Die Flaggen sind -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

Es funktioniert auch mit Flags: -std=c++11

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

Das Folgende hatte einen Kompilierungsfehler _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
quelle