помилка експериментальної :: файлової системи


94

Я намагаюся використовувати нові можливості 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 :: 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: невизначене посилання на `std :: Experimental :: filesystem :: v1 :: __ cxx11 :: path :: _ M_split_cmpts () '
collect2: помилка: ld повернув 1 статус виходу

версія gcc - це знімок linux-gnu_6-20151011

Будь-які підказки, як зв’язати нові функції c ++ 1z?

Відповіді:


154

Filesystem TS не має нічого спільного з підтримкою C ++ 1z, це абсолютно окрема специфікація, яка не є частиною робочого проекту C ++ 1z. Реалізація GCC (у GCC 5.3 та новіших версіях) доступна навіть у режимі C ++ 11.

Вам просто потрібно зв’язати з, -lstdc++fsщоб використовувати його.

(Відповідна бібліотека, libstdc++fs.aє статичною бібліотекою, тому, як і будь-яка статична бібліотека, вона повинна з’являтися після будь-яких об’єктів, які залежать від неї в команді компонувальника.)

Оновлення в листопаді 2017 р. , А також Filesystem TS, GCC 8.x також має реалізацію бібліотеки файлової системи C ++ 17, визначену в <filesystem>та у просторі імен 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
Це де-небудь задокументовано, я спробував це визначити сам і не придумав нічого, чи не пропустив я тут якогось ресурсу?
Шафік Ягмор


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, бо саме так працюють лінкери. Посилання вирішуються зліва направо, тому вам потрібно перерахувати статичні бібліотеки після об’єктів, які їх використовують.
Джонатан Уейклі

32

Якщо ви використовуєте cmake, додайте наступний рядок до CMakeLists.txt:

link_libraries(stdc++fs)

Так що cmake може посилатися на відповідну бібліотеку.


10
Я зробив, target_link_libraries(hello_world_ stdc++fs)і це складено.
sunapi386

13

З clang 4.0+ вам потрібно встановити посилання проти libc++experimental.a

Переконайтеся, що ви будуєте за допомогою libc ++ (а не libstdc ++) за допомогою -stdlib = libc ++ (як зазначено в коментарях)


Мені також знадобився -stdlib = libc ++, оскільки у моїй версії clang несподівано використовувався libstdc ++.
Боуї Оуенс,

@BowieOwens дякую, оновлену відповідь, щоб це було зрозуміло.
xaxxon,

Коли ви говорите "переконайтеся, що ви будуєте за допомогою libc ++", як це зробити? (Рішення бажано з CMake.). Дякую.
mannyglover

1
@mannyglover -stdlib=libc++ абоset(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
xaxxon

3

Ось демонстрація, яка може бути корисною комусь у майбутньому:

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.