eksperimental :: kesalahan linker sistem file

98

Saya mencoba untuk menggunakan fitur c ++ 1z baru yang sebenarnya merupakan kepala pengembangan dalam gcc 6.0.

Jika saya mencoba contoh kecil ini:

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

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

Saya mendapatkan:

/ opt / linux-gnu_6-20151011 / bin / g ++ --std = c ++ 1z main.cpp -O2 -g -o go
/tmp/ccaGzqFO.o: Dalam fungsi \ `std :: eksperimental :: filesystem :: v1 :: __ cxx11 :: path :: path (char const (&) [36]) ':
/opt/linux-gnu_6-20151011/include/c++/6.0.0/experimental/bits/fs_path.h:167: referensi tidak ditentukan ke `std :: eksperimental :: filesystem :: v1 :: __ cxx11 :: path :: _ M_split_cmpts () '
collect2: error: ld mengembalikan 1 status keluar

versi gcc adalah snapshot linux-gnu_6-20151011

Adakah petunjuk tentang cara menautkan fitur c ++ 1z yang baru?

Klaus
sumber

Jawaban:

161

TS Filesystem tidak ada hubungannya dengan dukungan C ++ 1z, ini adalah spesifikasi yang benar-benar terpisah bukan bagian dari draft kerja C ++ 1z. Penerapan GCC (di GCC 5.3 dan yang lebih baru) bahkan tersedia dalam mode C ++ 11.

Anda hanya perlu menautkan -lstdc++fsuntuk menggunakannya.

(Pustaka yang relevan libstdc++fs.a,, adalah pustaka statis, sehingga dengan pustaka statis apa pun, pustaka harus muncul setelah objek apa pun yang bergantung padanya dalam perintah linker.)

Pembaruan November 2017: serta TS Filesystem, GCC 8.x juga memiliki implementasi pustaka Filesystem C ++ 17, yang ditentukan di dalam <filesystem>dan di namespace std::filesystem(NB tidak ada "eksperimental" dalam nama tersebut) saat menggunakan -std=gnu++17atau -std=c++17. Dukungan GCC C ++ 17 belum lengkap atau stabil, dan hingga dianggap siap untuk penggunaan waktu utama, Anda juga perlu menautkan ke -lstdc++fsfitur Filesystem C ++ 17.

Pembaruan Jan 2019: dimulai dengan GCC 9, komponen C ++ 17 std::filesystemdapat digunakan tanpa -lstdc++fs(tetapi Anda masih memerlukan pustaka itu untuk std::experimental::filesystem).

Jonathan Wakely
sumber
2
Apakah ini didokumentasikan di mana saja, saya mencoba menentukannya sendiri dan tidak mendapatkan apa-apa, apakah saya melewatkan beberapa sumber daya di sini?
Shafik Yaghmour
2
Ketika saya mencoba menggunakan ini, saya mendapatkan kesalahan penaut yang sama. c++ -lstd++fs main.cpp. Saya menggunakangcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)
alfC
15
ok, -lstdc++fsharus di akhir baris (setidaknya setelah file sumber). Saya tidak mengerti mengapa beberapa -lxxxperlu berada di akhir dan yang lainnya tidak.
alfC
5
@alfC karena begitulah cara kerja penaut. Referensi diselesaikan dari kiri ke kanan, jadi Anda perlu membuat daftar pustaka statis setelah objek yang menggunakannya.
Jonathan Wakely
35

Jika Anda menggunakan cmake, tambahkan baris berikut ke CMakeLists.txt:

link_libraries(stdc++fs)

Sehingga cmake dapat ditautkan ke perpustakaan terkait.

Searene
sumber
12
Saya lakukan target_link_libraries(hello_world_ stdc++fs)dan itu dikompilasi.
sunapi386
14

Dengan clang 4.0+, Anda perlu ditautkan libc++experimental.a

Pastikan Anda membuat dengan libc ++ (bukan libstdc ++) dengan -stdlib = libc ++ (seperti yang disebutkan di komentar)

xaxxon.dll
sumber
Saya juga membutuhkan -stdlib = libc ++ karena versi clang saya tiba-tiba menggunakan libstdc ++.
Bowie Owens
@BowieOwens terima kasih, jawaban yang diperbarui untuk memperjelasnya.
xaxxon
Saat Anda mengatakan "pastikan Anda membuat dengan libc ++", bagaimana cara melakukannya? (Solusi sebaiknya dengan CMake.). Terima kasih.
mannyglover
1
@mannyglover -stdlib=libc++ atauset(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
xaxxon
4

Berikut adalah demo yang mungkin berguna bagi seseorang di masa mendatang:

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

Berikut ini adalah kompilasi dan pengujiannya. Benderanya adalah -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

Ini juga berfungsi dengan bendera: -std=c++11

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

Berikut ini adalah kesalahan kompilasi _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
sumber