experimental :: erreur de l'éditeur de liens du système de fichiers

94

J'essaye d'utiliser les nouvelles fonctionnalités de c ++ 1z pour le développement dans gcc 6.0.

Si j'essaye ce petit exemple:

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

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

J'ai eu:

/ opt / linux-gnu_6-20151011 / bin / g ++ --std = c ++ 1z main.cpp -O2 -g -o aller
/tmp/ccaGzqFO.o: Dans la fonction \ `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: référence non définie à `std :: experimental :: filesystem :: v1 :: __ cxx11 :: path :: _ M_split_cmpts () '
collect2: erreur: ld a renvoyé 1 statut de sortie

la version gcc est le snapshot linux-gnu_6-20151011

Des conseils sur la manière de créer un lien pour les nouvelles fonctionnalités de c ++ 1z?

Klaus
la source

Réponses:

154

Le système de fichiers TS n'a rien à voir avec la prise en charge de C ++ 1z, il s'agit d'une spécification complètement distincte qui ne fait pas partie du brouillon de travail de C ++ 1z. L'implémentation de GCC (dans GCC 5.3 et versions ultérieures) est même disponible en mode C ++ 11.

Il vous suffit de créer un lien avec -lstdc++fspour l'utiliser.

(La bibliothèque appropriée,, libstdc++fs.aest une bibliothèque statique, donc comme avec toute bibliothèque statique, elle devrait venir après tous les objets qui en dépendent dans la commande de l'éditeur de liens.)

Mise à jour de novembre 2017: en plus du système de fichiers TS, GCC 8.x a également une implémentation de la bibliothèque C ++ 17 Filesystem, définie dans <filesystem>et dans l'espace de noms std::filesystem(NB pas de "expérimental" dans ces noms) lors de l'utilisation de -std=gnu++17ou -std=c++17. Le support C ++ 17 de GCC n'est pas encore complet ou stable, et jusqu'à ce qu'il soit considéré comme prêt pour une utilisation aux heures de grande écoute, vous devez également établir un lien vers -lstdc++fsles fonctionnalités du système de fichiers C ++ 17.

Mise à jour janvier 2019: à partir de GCC 9, les std::filesystemcomposants C ++ 17 peuvent être utilisés sans -lstdc++fs(mais vous avez toujours besoin de cette bibliothèque pour std::experimental::filesystem).

Jonathan Wakely
la source
2
Est-ce documenté quelque part, j'ai essayé de le déterminer moi-même et je suis venu sans rien, ai-je manqué une ressource ici?
Shafik Yaghmour
2
@ShafikYaghmour, je viens de mettre à jour la documentation: gcc.gnu.org/onlinedocs/libstdc++/manual/… gcc.gnu.org/onlinedocs/libstdc ++/ manual / ... gcc.gnu.org/onlinedocs/libstdc++/manual/… (en bas)
Jonathan Wakely
2
Lorsque j'essaie d'utiliser cela, j'obtiens la même erreur de l'éditeur de liens. c++ -lstd++fs main.cpp. J'utilisegcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)
alfC
15
ok, -lstdc++fsdoit être à la fin de la ligne (au moins après le fichier source). Je ne comprends pas pourquoi certains -lxxxdoivent être à la fin et d'autres non.
alfC
5
@alfC parce que c'est ainsi que fonctionnent les linkers. Les références sont résolues de gauche à droite, vous devez donc répertorier les bibliothèques statiques après les objets qui les utilisent.
Jonathan Wakely
32

Si vous utilisez cmake, ajoutez la ligne suivante à CMakeLists.txt:

link_libraries(stdc++fs)

Pour que cmake puisse établir un lien avec la bibliothèque correspondante.

Searene
la source
10
Je l'ai fait target_link_libraries(hello_world_ stdc++fs)et il a été compilé.
sunapi386
13

Avec clang 4.0+, vous devez établir un lien avec libc++experimental.a

Assurez-vous que vous construisez avec libc ++ (pas libstdc ++) avec -stdlib = libc ++ (comme mentionné dans les commentaires)

xaxxon
la source
J'avais également besoin de -stdlib = libc ++ car ma version clang utilisait de manière inattendue libstdc ++.
Bowie Owens
@BowieOwens merci, réponse mise à jour pour que cela soit clair.
xaxxon
Lorsque vous dites "assurez-vous que vous construisez avec libc ++", comment faire? (Solution de préférence avec CMake.). Merci.
mannyglover le
1
@mannyglover -stdlib=libc++ orset(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
xaxxon
3

Voici une démo qui pourrait être utile à quelqu'un à l'avenir:

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

Les éléments suivants sont la compilation et les tests. Les drapeaux sont -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

Cela fonctionne également avec les drapeaux: -std=c++11

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

Ce qui suit avait une erreur de compilation _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
la source