ทดลอง :: ข้อผิดพลาดตัวเชื่อมโยงระบบไฟล์


98

ฉันพยายามใช้คุณสมบัติ c ++ 1z ใหม่ที่เป็นจริงในส่วนหัวของการพัฒนาภายใน gcc 6.0

ถ้าฉันลองตัวอย่างเล็กน้อยนี้:

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

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

ฉันได้:

/ opt / linux-gnu_6-20151011 / bin / g ++ --std = c ++ 1z main.cpp -O2 -g -o go
/tmp/ccaGzqFO.o: ในฟังก์ชัน \ `std :: trial :: filesystem :: v1 :: __ cxx11 :: path :: path (char const (&) [36]) ':
/opt/linux-gnu_6-20151011/include/c++/6.0.0/experimental/bits/fs_path.h:167: การอ้างอิงที่ไม่ได้กำหนดถึง `std :: experiment :: filesystem :: v1 :: __ cxx11 :: path :: _ M_split_cmpts () '
collect2: error: ld ส่งคืนสถานะการออก 1 ครั้ง

เวอร์ชัน gcc คือสแนปชอต linux-gnu_6-20151011

มีคำแนะนำวิธีการเชื่อมโยงสำหรับคุณลักษณะ c ++ 1z ใหม่หรือไม่

คำตอบ:


161

ระบบไฟล์ TS ไม่เกี่ยวข้องกับการรองรับ C ++ 1z แต่เป็นข้อกำหนดแยกต่างหากโดยสิ้นเชิงซึ่งไม่ได้เป็นส่วนหนึ่งของแบบร่างการทำงาน C ++ 1z การใช้งานของ GCC (ใน GCC 5.3 และใหม่กว่า) สามารถใช้ได้ในโหมด C ++ 11

คุณเพียงแค่ต้องเชื่อมโยง-lstdc++fsเพื่อใช้งาน

(ไลบรารีที่เกี่ยวข้องlibstdc++fs.aเป็นไลบรารีแบบคงที่เช่นเดียวกับไลบรารีแบบคงที่ควรมาตามหลังอ็อบเจ็กต์ใด ๆ ที่ขึ้นอยู่กับมันในคำสั่ง linker)

ปรับปรุงพฤศจิกายน 2017:เช่นเดียวกับระบบแฟ้ม TS, GCC 8.x ยังมีการดำเนินงานของ C ++ 17 ห้องสมุด Filesystem กำหนดใน<filesystem>และใน namespace std::filesystem(NB ไม่ "ทดลอง" ในชื่อเหล่านั้น) เมื่อใช้หรือ-std=gnu++17 -std=c++17การสนับสนุน C ++ 17 ของ GCC ยังไม่สมบูรณ์หรือมีความเสถียรและจนกว่าจะถือว่าพร้อมสำหรับการใช้งานในช่วงไพรม์ไทม์คุณจะต้องเชื่อมโยง-lstdc++fsสำหรับคุณสมบัติระบบไฟล์ C ++ 17

อัปเดตมกราคม 2019:ตั้งแต่ GCC 9 std::filesystemคุณสามารถใช้คอมโพเนนต์C ++ 17 ได้โดยไม่ต้องใช้-lstdc++fs(แต่คุณยังต้องใช้ไลบรารีนั้นstd::experimental::filesystem)


2
เอกสารนี้ถูกบันทึกไว้ทุกที่หรือไม่ฉันพยายามตรวจสอบสิ่งนี้ด้วยตัวเองและไม่มีอะไรเลยฉันพลาดแหล่งข้อมูลบางอย่างที่นี่หรือไม่?
Shafik Yaghmour

2
@ShafikYaghmour ฉันได้ปรับปรุงเพียงเอกสาร: gcc.gnu.org/onlinedocs/libstdc++/manual/... gcc.gnu.org/onlinedocs/libstdc++/manual/... gcc.gnu.org/onlinedocs/libstdc++/manual/... (ที่ด้านล่าง)
Jonathan Wakely

2
เมื่อฉันพยายามใช้สิ่งนี้ฉันได้รับข้อผิดพลาดตัวเชื่อมโยงเดียวกัน c++ -lstd++fs main.cpp. ฉันใช้gcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)
alfC

15
ตกลง-lstdc++fsจะต้องอยู่ท้ายบรรทัด (หลังไฟล์ต้นฉบับเป็นอย่างน้อย) ฉันไม่เข้าใจว่าทำไมบางคน-lxxxต้องอยู่ที่จุดจบและคนอื่น ๆ ไม่ทำ
alfC

5
@alfC เพราะนั่นคือวิธีการทำงานของตัวเชื่อมโยง การอ้างอิงได้รับการแก้ไขจากซ้ายไปขวาดังนั้นคุณต้องแสดงรายการไลบรารีแบบคงที่หลังอ็อบเจ็กต์ที่ใช้
Jonathan Wakely

35

หากคุณใช้ cmake ให้เพิ่มบรรทัดต่อไปนี้ในCMakeLists.txt:

link_libraries(stdc++fs)

เพื่อให้ cmake สามารถเชื่อมโยงกับไลบรารีที่เกี่ยวข้อง


12
ฉันทำtarget_link_libraries(hello_world_ stdc++fs)และรวบรวม
sunapi386

14

ด้วยเสียงดัง 4.0+ คุณต้องเชื่อมโยง libc++experimental.a

ตรวจสอบให้แน่ใจว่าคุณกำลังสร้างด้วย libc ++ (ไม่ใช่ libstdc ++) ด้วย -stdlib = libc ++ (ตามที่กล่าวไว้ในความคิดเห็น)


ฉันต้องการ -stdlib = libc ++ ด้วยเพราะเวอร์ชันเสียงดังของฉันใช้ libstdc ++ โดยไม่คาดคิด
Bowie Owens

@BowieOwens ขอบคุณคำตอบที่อัปเดตเพื่อให้ชัดเจน
xaxxon

เมื่อคุณพูดว่า "ตรวจสอบให้แน่ใจว่าคุณกำลังสร้างด้วย libc ++" ฉันจะทำอย่างไร (วิธีแก้ไขควรใช้ CMake) ขอบคุณ.
mannyglover

1
@mannyglover -stdlib=libc++ หรือset(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
xaxxon

4

นี่คือตัวอย่างที่อาจเป็นประโยชน์กับใครบางคนในอนาคต:

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

ต่อไปนี้กำลังรวบรวมและทดสอบ ธงคือ-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

นอกจากนี้ยังใช้งานได้กับแฟล็ก: -std=c++11

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

ต่อไปนี้มีข้อผิดพลาดในการคอมไพล์ _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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.