thử nghiệm :: lỗi trình liên kết hệ thống tệp


94

Tôi cố gắng sử dụng các tính năng c ++ 1z mới trên thực tế trên đầu phát triển trong gcc 6.0.

Nếu tôi thử ví dụ nhỏ này:

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

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

Tôi đã nhận:

/ opt / linux-gnu_6-20151011 / bin / g ++ --std = c ++ 1z main.cpp -O2 -g -o go
/tmp/ccaGzqFO.o: Trong hàm \ `std :: Experiment :: filesystem :: v1 :: __ cxx11 :: path :: path (char const (&) [36]) ':
/opt/linux-gnu_6-20151011/include/c++/6.0.0/experimental/bits/fs_path.h:167: tham chiếu không xác định đến `std :: testing :: filesystem :: v1 :: __ cxx11 :: path :: _ M_split_cmpts () '
Collect2: error: ld trả về 1 trạng thái thoát

phiên bản gcc là bản chụp nhanh linux-gnu_6-20151011

Bất kỳ gợi ý làm thế nào để liên kết cho các tính năng c ++ 1z mới?

Câu trả lời:


154

TS hệ thống tập tin không liên quan gì đến hỗ trợ C ++ 1z, nó là một đặc điểm kỹ thuật hoàn toàn riêng biệt không phải là một phần của bản nháp làm việc C ++ 1z. Việc triển khai GCC (trong GCC 5.3 trở lên) thậm chí có sẵn trong chế độ C ++ 11.

Bạn chỉ cần liên kết với -lstdc++fsđể sử dụng nó.

(Thư viện có liên quan libstdc++fs.a, là một thư viện tĩnh, vì vậy với bất kỳ thư viện tĩnh nào, nó sẽ xuất hiện sau bất kỳ đối tượng nào phụ thuộc vào nó trong lệnh trình liên kết.)

Cập nhật tháng 11 năm 2017: cũng như TS Hệ thống tệp, GCC 8.x cũng có triển khai thư viện Hệ thống tệp C ++ 17, được xác định trong <filesystem>và trong không gian tên std::filesystem(NB không có "thử nghiệm" trong các tên đó) khi sử dụng -std=gnu++17hoặc -std=c++17. Hỗ trợ C ++ 17 của GCC chưa hoàn thiện hoặc chưa ổn định và cho đến khi nó được coi là sẵn sàng để sử dụng vào thời gian chính, bạn cũng cần liên kết đến -lstdc++fscác tính năng của Hệ thống tệp C ++ 17.

Cập nhật tháng 1 năm 2019: bắt đầu với GCC 9, các std::filesystemthành phần C ++ 17 có thể được sử dụng mà không cần -lstdc++fs(nhưng bạn vẫn cần thư viện đó cho std::experimental::filesystem).


2
Điều này có được ghi lại ở bất cứ đâu, tôi đã cố gắng tự xác định điều này và không tìm thấy gì, tôi có bỏ lỡ một số tài liệu ở đây không?
Shafik Yaghmour


2
Khi tôi cố gắng sử dụng cái này, tôi gặp lỗi trình liên kết tương tự. c++ -lstd++fs main.cpp. Tôi đang sử dụnggcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)
alfC

15
ok, -lstdc++fsphải ở cuối dòng (ít nhất sau tệp nguồn). Tôi không hiểu tại sao một số -lxxxcần phải ở cuối và những người khác thì không.
alfC

5
@alfC vì đó là cách hoạt động của trình liên kết. Các tham chiếu được giải quyết từ trái sang phải, vì vậy bạn cần liệt kê các thư viện tĩnh sau các đối tượng sử dụng chúng.
Jonathan Wakely

32

Nếu bạn đang sử dụng cmake, hãy thêm dòng sau vào CMakeLists.txt:

link_libraries(stdc++fs)

Vì vậy, cmake đó có thể liên kết với thư viện tương ứng.


10
Tôi đã làm target_link_libraries(hello_world_ stdc++fs)và nó được biên dịch.
sunapi386

13

Với clang 4.0+, bạn cần liên kết với libc++experimental.a

Đảm bảo rằng bạn đang xây dựng bằng libc ++ (không phải libstdc ++) với -stdlib = libc ++ (như đã đề cập trong các nhận xét)


Tôi cũng cần -stdlib = libc ++ vì phiên bản clang của tôi bất ngờ sử dụng libstdc ++.
Bowie Owens

@BowieOwens cảm ơn, câu trả lời được cập nhật để làm rõ điều đó.
xaxxon

Khi bạn nói "hãy đảm bảo rằng bạn đang xây dựng bằng libc ++", làm cách nào để thực hiện việc này? (Tốt nhất là giải pháp với CMake.). Cảm ơn.
mannyglover 12/09/18

1
@mannyglover -stdlib=libc++ hoặcset(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
xaxxon 12/09/18

3

Đây là một bản demo có thể hữu ích cho ai đó trong tương lai:

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

Sau đây là biên dịch và thử nghiệm. Các lá cờ là -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

Nó cũng hoạt động với cờ: -std=c++11

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

Phần sau có lỗi biên dịch _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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.