deneysel :: dosya sistemi bağlayıcı hatası


100

Yeni c ++ 1z özelliklerini gcc 6.0'da geliştirme aşamasında kullanmaya çalışıyorum.

Bu küçük örneği denersem:

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

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

Bende var:

/ opt / linux-gnu_6-20151011 / bin / g ++ --std = c ++ 1z main.cpp -O2 -g -o go
/tmp/ccaGzqFO.o: \ `std :: experimental :: filesystem :: v1 :: __ cxx11 :: yol :: yol (char const (&) [36]) 'işlevinde:
/opt/linux-gnu_6-20151011/include/c++/6.0.0/experimental/bits/fs_path.h:167: `std :: experimental :: filesystem :: v1 :: __ cxx11 :: yol :: _ M_split_cmpts için tanımlanmamış başvuru () '
Collect2: hata: ld 1 çıkış durumu döndürdü

gcc sürümü anlık görüntüdür linux-gnu_6-20151011

Yeni c ++ 1z özellikleri için nasıl bağlantı kurulacağına dair herhangi bir ipucu var mı?

Yanıtlar:


165

Dosya Sistemi TS'nin C ++ 1z desteğiyle ilgisi yoktur, C ++ 1z çalışma taslağının parçası olmayan tamamen ayrı bir özelliktir. GCC'nin uygulaması (GCC 5.3 ve sonrasında) C ++ 11 modunda bile mevcuttur.

Kullanmak için bağlantı kurmanız yeterlidir -lstdc++fs.

(İlgili kütüphane, libstdc++fs.astatik bir kütüphanedir, bu nedenle herhangi bir statik kütüphanede olduğu gibi, linker komutunda kendisine bağlı olan tüm nesnelerin ardından gelmelidir .)

Kasım 2017 Güncellemesi: Dosya Sistemi TS'nin yanı sıra GCC 8.x , içinde tanımlanan C ++ 17 Dosya Sistemi kitaplığının bir uygulamasına da sahiptir.<filesystem> ve ad alanında std::filesystem(NB bu isimler hiçbir "deneysel") kullanılarak -std=gnu++17veya -std=c++17. GCC'nin C ++ 17 desteği henüz tam veya kararlı değil ve birincil kullanım için hazır olduğu düşünülene kadar -lstdc++fsC ++ 17 Dosya Sistemi özellikleri için bağlantı kurmanız gerekir .

Ocak 2019 Güncellemesi: GCC 9'dan başlayarak, C ++ 17 std::filesystembileşenleri olmadan kullanılabilir -lstdc++fs(ancak yine de bu kitaplığa ihtiyacınız var std::experimental::filesystem).


2
Bu herhangi bir yerde belgelendi mi, bunu kendim belirlemeye çalıştım ve hiçbir şey olmadan geldim, burada bazı kaynakları kaçırdım mı?
Shafik Yaghmour


2
Bunu kullanmaya çalıştığımda aynı linker hatasını alıyorum. c++ -lstd++fs main.cpp. Ben kullanıyorumgcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)
ALFC'si

15
tamam, -lstdc++fssatırın sonunda olmalı (en azından kaynak dosyadan sonra). Neden bazılarının -lxxxsonunda olması gerektiğini ve diğerlerinin olmadığını anlamıyorum.
alfC

5
@alfC çünkü bağlayıcılar böyle çalışır. Referanslar soldan sağa çözülür, bu nedenle statik kitaplıkları, onları kullanan nesnelerden sonra listelemeniz gerekir.
Jonathan Wakely

35

Cmake kullanıyorsanız, şu satırı ekleyin CMakeLists.txt:

link_libraries(stdc++fs)

Böylece cmake, ilgili kitaplığa bağlanabilir.


13
Yaptım target_link_libraries(hello_world_ stdc++fs)ve derledim.
sunapi386

14

Clang 4.0+ ile bağlantı kurmanız gerekir libc++experimental.a

-Stdlib = libc ++ (yorumlarda belirtildiği gibi) ile libc ++ (libstdc ++ değil) ile oluşturduğunuzdan emin olun.


Ayrıca -stdlib = libc ++ 'ya ihtiyacım vardı çünkü clang sürümüm beklenmedik şekilde libstdc ++ kullanıyordu.
Bowie Owens

@BowieOwens teşekkürler, bunu netleştirmek için yanıt güncellendi.
xaxxon

"Libc ++ ile oluşturduğunuzdan emin olun" dediğinizde, bunu nasıl yaparım? (Tercihen CMake ile çözüm.). Teşekkürler.
mannyglover

1
@mannyglover -stdlib=libc++ orset(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
xaxxon

5

İşte gelecekte birine yardımcı olabilecek bir demo:

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

Aşağıdakiler derleniyor ve test ediliyor. Bayraklar şunlardır -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

Ayrıca bayraklarla da çalışır: -std=c++11

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

Aşağıdakiler derleme hatası verdi _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

Ekstra notlar:

Aşağıdaki bağlantı yardımcı olabilir

Devtoolset-8-gcc kullanarak gcc8 nasıl kurulur


1

İçin

dyld: lazy symbol binding failed: Symbol not found: 
__ZNSt3__14__fs10filesystem4path17replace_extensionERKS2_

ve

Undefined symbols for architecture x86_64:   
"std::__1::__fs::filesystem::__current_path(std::__1::error_code*)", 
referenced from:      
sys::path::get_cwd() in Path.cc.o
ld: symbol(s) not found for architecture x86_64

.. takip etmeyi dene:

LLVM clang> = 10 için, libc++.1.0.dylibLLVM tarafından sağlanan ile bağlantı kurun .

add_link_options("-Wl,-rpath,location_of_llvm_install/lib;location_of_llvm_install/lib/libc++.1.0.dylib")

Bu Apple Clang için değil, resmi https://releases.llvm.org adresinden veya bir paket yöneticisi tarafından yüklenen LLVM clang içindir .

Xcode <11 dosya sistemi başlığına sahip değil. macOS <10.15 std::filesystem::path, sistem dylib'de sembollere sahip değil/usr/lib/libc++.1.0.dylib


-1

Kodumu çevrimiçi olarak kolayca deneyebilirsiniz.

//  currentPath.cpp
// /programming/33149878#65128193
#include <experimental/filesystem>
#include <iostream>
using namespace std;

int main() {
  cout << "path = " << experimental::filesystem::current_path() << endl;
}

Derleyin ve çalıştırın:

clang++ currentPath.cpp -lstdc++fs && ./a.out # Linux
clang++ currentPath.cpp -lstdc++fs && ./a.exe # MSYS2, Windows

Not: -lstdc++fsbir bağlayıcı işaretidir, bir derleyici bayrağı değildir. (Makefile yazarken önemlidir.)

Beklenen çıktı:

path = "/path/to/the/current/directory"

Kodumu derlemeye ve çalıştırmaya çalışırsanız, cevabımı yükseltmek için iyi bir neden göreceğinize inanıyorum. Eğer varsa yapmak derleme ve çalıştırmak ve hala upvote istemiyoruz, benim bildirerek düşünün lütfen neden altındaki bir yorumda. - Kuşkusuz, cevabımın @caot'un cevabı ile benzerlikleri var, ancak bazı önemli farklılıklar da var. Bu nedenle, yanıtını belirlemek için düzenlemeler önermektense kendi yanıtımı yayınlamayı tercih ediyorum .
Henke
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.