experimental::error del enlazador del sistema de archivos

5 minutos de lectura

experimentalerror del enlazador del sistema de archivos
klaus

Intento usar las nuevas características de c++1z en la cabeza del desarrollo dentro de gcc 6.0.

Si pruebo este pequeño ejemplo:

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

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

Tengo:

/opt/linux-gnu_6-20151011/bin/g++ --std=c++1z main.cpp -O2 -g -o go
/tmp/ccaGzqFO.o: In function \`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: undefined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
collect2: error: ld returned 1 exit status

la versión gcc es la instantánea linux-gnu_6-20151011

¿Algún consejo sobre cómo vincular las nuevas características de c++1z?

1646756049 254 experimentalerror del enlazador del sistema de archivos
jonathan wakely

El Filesystem TS no tiene nada que ver con el soporte de C++1z, es una especificación completamente separada que no forma parte del borrador de trabajo de C++1z. La implementación de GCC (en GCC 5.3 y versiones posteriores) está incluso disponible en modo C++11.

Solo tienes que enlazar con -lstdc++fs para usarlo

(La biblioteca correspondiente, libstdc++fs.aes una biblioteca estática, por lo que, al igual que con cualquier biblioteca estática, debería venir después cualquier objeto que dependa de él en el comando del enlazador).

Actualización de noviembre de 2017: así como el sistema de archivos TS, GCC 8.x además tiene una implementación de la biblioteca C++17 Filesystem, definida en <filesystem> y en el espacio de nombres std::filesystem (NB no “experimental” en esos nombres) cuando se usa -std=gnu++17 o -std=c++17. La compatibilidad con C++17 de GCC aún no está completa ni es estable, y hasta que se considere que está lista para su uso en horario de máxima audiencia, también debe conectarse a -lstdc++fs para las características del sistema de archivos C++17.

Actualización de enero de 2019: a partir de GCC 9, el C++17 std::filesystem Los componentes se pueden utilizar sin -lstdc++fs (pero aún necesita esa biblioteca para std::experimental::filesystem).

  • ¿Está esto documentado en alguna parte? Traté de determinarlo yo mismo y no encontré nada. ¿Me perdí algún recurso aquí?

    – Shafik Yaghmour

    16 oct 2015 a las 9:34

  • @ShafikYaghmour, acabo de actualizar los documentos: gcc.gnu.org/onlinedocs/libstdc++/manual/… gcc.gnu.org/onlinedocs/libstdc++/manual/… gcc.gnu.org/onlinedocs/libstdc++/manual/… (en el fondo)

    –Jonathan Wakely

    16/10/2015 a las 14:01


  • Cuando trato de usar esto, obtengo el mismo error del enlazador. c++ -lstd++fs main.cpp. estoy usando gcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)

    – alfC

    8 de enero de 2016 a las 9:17

  • OK, -lstdc++fs tiene que estar al final de la línea (al menos después del archivo fuente). no entiendo porque algunos -lxxx necesitan estar al final y otros no.

    – alfC

    8 de enero de 2016 a las 9:33

  • @alfC porque así es como funcionan los enlazadores. Las referencias se resuelven de izquierda a derecha, por lo que debe enumerar las bibliotecas estáticas después de los objetos que las usan.

    –Jonathan Wakely

    11 de enero de 2016 a las 2:28

Si está utilizando cmake, agregue la siguiente línea a CMakeLists.txt:

link_libraries(stdc++fs)

Para que cmake pueda vincularse con la biblioteca correspondiente.

  • yo hice target_link_libraries(hello_world_ stdc++fs) y compiló.

    – sunapi386

    19 de marzo de 2019 a las 23:19

  • target_link_libraries no me funcionó en g++-8. esto funcionó

    – Teshan Shanuka J.

    23 de julio de 2021 a las 5:12

1646756050 636 experimentalerror del enlazador del sistema de archivos
xaxxon

Con clang 4.0+, necesitas enlazar contra libc++experimental.a

Asegúrese de estar compilando con libc++ (no con libstdc++) con -stdlib=libc++ (como se menciona en los comentarios)

  • También necesitaba -stdlib=libc++ porque mi versión clang estaba usando inesperadamente libstdc++.

    – Bowie Owens

    9 de agosto de 2018 a las 23:31

  • @BowieOwens gracias, respuesta actualizada para dejar eso claro.

    – xaxxon

    9 de agosto de 2018 a las 23:42

  • Cuando dices “asegúrate de que estás compilando con libc++”, ¿cómo hago esto? (Solución preferiblemente con CMake.) . Gracias.

    – mannyglover

    12/09/2018 a las 18:37

  • @mannyglover -stdlib=libc++ o set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")

    – xaxxon

    12/09/2018 a las 20:45


1646756051 352 experimentalerror del enlazador del sistema de archivos
caot

Aquí hay una demostración que podría ser útil para alguien en el futuro:

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

Lo siguiente es compilar y probar. las banderas son -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

También funciona con banderas: -std=c++11

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

Lo siguiente tenía un error de compilación _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

Notas adicionales:

El siguiente enlace puede ser útil

Cómo instalar gcc8 usando devtoolset-8-gcc

1646756052 125 experimentalerror del enlazador del sistema de archivos
Puio

Para

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

y

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

.. intente lo siguiente:

Para LLVM clang >= 10, enlace con libc++.1.0.dylib suministrado por LLVM.

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

Esto no es para Apple Clang, sino para LLVM Clang instalado desde el sitio oficial https://releases.llvm.org o por un administrador de paquetes.

Xcode < 11 no tiene encabezado de sistema de archivos. macOS <10.15 no tiene std::filesystem::path símbolos en el sistema dylib en /usr/lib/libc++.1.0.dylib

Puedes probar fácilmente mi código en línea.

//  currentPath.cpp
// https://stackoverflow.com/questions/33149878#65128193
#include <experimental/filesystem>
#include <iostream>
using namespace std;

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

Compilar y ejecutar:

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

Nota: -lstdc++fs es una bandera del enlazador, no una bandera del compilador. (Importante cuando escribe un archivo MAKE).

Rendimiento esperado:

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

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad