Error de inclusión en Visual Studio Code bajo Linux

Resuelto
JLesage Mensajes publicados 39 Estado Miembro -  
mamiemando Mensajes publicados 33228 Fecha de registro   Estado Moderador Última intervención   -

Hola,

Soy principiante en C++, intento usar la biblioteca SFML para programar juegos en Visual Studio Code, pero tengo un error que dice que la ruta de inclusión de SFML no es reconocida. Sin embargo, no tengo ningún error cuando ejecuto un simple código en C++; esto solo ocurre cuando intento incluir un archivo ".h" de SFML. En mi archivo ".json" intenté indicar la ruta de instalación de la biblioteca, en "includePath", guardo, reinicio el editor, pero aún así no funciona. Les envío 2 capturas de pantalla para ilustrar lo que escribo.

Votre aide sera très précieuse pour moi. Merci. 

4 respuestas

  1. mamiemando Mensajes publicados 33228 Fecha de registro   Estado Moderador Última intervención   7 944
     

    Hola,

    ¿Qué distribución de Linux has instalado? ¿Cómo procediste para instalar la biblioteca? En Debian y las distribuciones derivadas (Ubuntu, Mint, ...) el paquete a instalar parece ser libsfml-dev :

    sudo apt update sudo apt install g++ libsfml-dev

    Los headers de la biblioteca se despliegan en /usr/include/SFML, como muestra el contenido del paquete. Se encuentra en esa lista el archivo /usr/include/SFML/Graphics.hpp que incluyes en tu código. Como /usr/include es un directorio estándar, tu compilador (supongo g++) debe localizar directamente tus headers sin opciones adicionales (no hace falta la opción -I).

    Sin embargo, habrá que enlazar (linker) tu programa con las bibliotecas de las que depende. Según el contenido del paquete, las bibliotecas son:

     /usr/lib/x86_64-linux-gnu/libsfml-audio.so /usr/lib/x86_64-linux-gnu/libsfml-graphics.so /usr/lib/x86_64-linux-gnu/libsfml-network.so /usr/lib/x86_64-linux-gnu/libsfml-system.so /usr/lib/x86_64-linux-gnu/libsfml-window.so

    Nuevamente /usr/lib/x86_64-linux-gnu es un directorio estándar, por lo que no es necesario indicar en qué carpeta debe buscar las bibliotecas (opciones -L y/o -Wl,R). Pero sí hay que indicar al compilador la o las bibliotecas a enlazar con la opción -l. Enlazar el programa a libtoto.so se escribe -ltoto durante la compilación, así que en tu caso, diría que tu programa se compila así (algunas bibliotecas listadas a continuación no son necesarias como veremos más abajo) :

    g++ main.cpp -o mon_application -lsfml-audio -lsfml-graphics -lsfml-network -lsfml-system -lsfml-window

    Ahora, si miramos este tutorial podemos mejorar la orden de compilación anterior :

    g++ main.cpp -o mon_application -lsfml-graphics -lsfml-window -lsfml-system

    A continuación, tu programa terminará teniendo varios ficheros C++ y cada uno de ellos deberá compilarse individualmente (opción -c, para compilar un ".cpp" en ".o") y luego ensamblarlos con una última orden de compilación (que incluye todos los ".o" y todas las opciones de enlace). Se entiende rápidamente que eso se volverá muy tedioso a mano y conviene preparar un Makefile para compilar el programa con la orden make all y sudo make install (esta orden significa: lee el Makefile en la carpeta actual y ejecuta los objetivos all y install).

    Hoy en día, rara vez se escribe ese Makefile uno mismo (ocurre en proyectos muy pequeños cuando hay prisa, pero no es lo ideal, sobre todo porque el Makefile que escribimos depende del compilador, del sistema operativo, etc.). En tiempos pasados se usaban herramientas como automake pero no es tan sencillo de poner en marcha. En fin, por todas estas razones te recomiendo optar por cmake. Si desarrollas con kdevelop (y supongo que anjuta también?), está de hecho posible inicializar tu proyecto para usar cmake. Dado un archivo CMakeLists.txt, el comando cmake genera un archivo Makefile compatible con tu instalación, que luego puedes usar mediante el comando make. Por lo general, creamos una carpeta build en la raíz del proyecto y es aquí donde construiremos todo. Desde esa carpeta ejecutamos entonces :

    cmake .. make all sudo make install

    Bonne chance

    1
  2. mamiemando Mensajes publicados 33228 Fecha de registro   Estado Moderador Última intervención   7 944
     

    Bonjour,

    Gracias por evitar capturas de pantalla (poco ecológicas y poco prácticas) cuando un simple copiar pegar y un compartir fragmento de código pueden ser suficientes.

    Instalación

    En tu caso solo necesitas instalar explícitamente g++ (ya que es C++), gcc se usa para código en C puro. De la misma manera clang es otro compilador C del que no necesitas. Así que este comando bastaría:

    sudo apt update sudo apt install g++ libsfml-dev

    Compilador

    El compilador indicado en la configuración de tu proyecto debería ser g++ (no gcc). Si usas un compilador C para compilar C++, eso no funcionará.

    Ejemplo :

    toto.cpp

    #include <iostream> int main() { std::cout << "hello" << std::endl; return 0; }

    Compilación con gcc toto.cpp :

     (mando@silk) (~) $ gcc toto.cpp /usr/bin/ld: /tmp/ccbEYG74.o: atención: réaddressage sur « _ZSt4cout » dans la section en lecture seule « .text » /usr/bin/ld : /tmp/ccbEYG74.o : dans la fonction « main » : toto.cpp:(.text+0x11) : référence indéfinie vers « std::cout » /usr/bin/ld : toto.cpp:(.text+0x19) : référence indéfinie vers « std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) » /usr/bin/ld : toto.cpp:(.text+0x20) : référence indéfinie vers « std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&) » /usr/bin/ld: toto.cpp:(.text+0x2b) : référence indéfinie vers « std::ostream::operator<<(std::ostream& (*)(std::ostream&)) » /usr/bin/ld : /tmp/ccbEYG74.o : dans la fonction « __static_initialization_and_destruction_0(int, int) » : toto.cpp:(.text+0x5e) : référence indéfinie vers « std::ios_base::Init::Init() » /usr/bin/ld : toto.cpp:(.text+0x79) : référence indéfinie vers « std::ios_base::Init::~Init() » /usr/bin/ld: attention: création de DT_TEXTREL dans un PIE collect2: error: ld returned 1 exit status

    Compilación con g++ toto.cpp : no hay error

    Inclusión de los headers

    La opción includePath corresponde a la opción -I en gcc/g++. Puedes mantenerla, pero solo permite incluir más fácilmente los headers implicados en el código fuente de tu proyecto (no los headers externos, como los de SFML). Podrías indicar que hay que buscar headers en /usr/include, pero normalmente eso debería hacerse directamente por g++, sin necesidad de una opción especial.

    Si tu proyecto está bien configurado, tu IDE no debería subrayar en rojo las include.

    Adición de las librerías externas

    Supongo que puedes añadir en este archivo de configuración las librerías a las que te vinculas. Te invito a mirar esta discusión.

    cmake

    De todos modos, este archivo de configuración depende de tu IDE (VisualStudio). Esto significa que si Redistribuyes tu código, a menos que otros desarrolladores usen VisualStudio y hayas compartido el archivo de configuración de tu proyecto, ellos también tendrán problemas para compilar tu proyecto. La forma "limpia" de proceder es usar cmake y crear un proyecto basado en cmake en tu IDE (y que parece ser soportado en VisualStudio, ver este enlace).

    Personalmente tendría desde el principio la tendencia a partir de bases sanas (a saber: hacer que tu proyecto se compile con cmake, luego crear en tu IDE un proyecto basado en cmake). Esto debería resolver todos tus problemas (porque, en el peor de los casos, puedes compilar desde la línea de comandos). De hecho, cmake permite especificar todo (compilador, inclusión de headers, librerías externas, etc).

    Si optas por este método, puedes basarte en este tutorial. Para instalar los paquetes correspondientes en Debian (u otra distribución derivada) :

    sudo apt update sudo apt install cmake cmake-gui-qt

    Bonne chance

    1
  3. JLesage
     
    Gracias por las explicaciones, @mamiemando. En mi PC, instalé la distribución "Linux pop-os 6.2.6". Antes de instalar la biblioteca, instalé los compiladores C++ con:

    sudo apt install gcc g++ clang gdb

    Luego, en Visual Studio Code, añadí Intellisense de C/C++. Para la biblioteca SFML, uso el siguiente comando para instalarla:

    sudo apt-get install libsfml-dev

    En el archivo de propiedades ".json", observé que el compilador activo es "gcc"; intenté cambiarlo a "g++" para ver si se solucionaba el problema, pero no es así.

    He importado más abajo una captura de pantalla de la configuración para mostrar lo que digo. Además, ¿hay alguna forma de enlazar mi programa con las bibliotecas sin pasar por las líneas de comandos?


    0
  4. JLesage Mensajes publicados 39 Estado Miembro 5
     

    Gracias por tomarte el tiempo de responder, @mamiemando EstadoModerador.

    0
    1. mamiemando Mensajes publicados 33228 Fecha de registro   Estado Moderador Última intervención   7 944
       

      De nada :-)

      He importado más abajo una captura de pantalla de la configuración para mostrar lo que digo. Por otro lado, ¿hay alguna forma de vincular mi programa con las bibliotecas sin pasar por las líneas de comandos?

      En teoría, tu IDE debería permitirte compilar usando cmake sin tener que escribir tú mismo los comandos que eso implica. Supongo que, como el tema se marcó como resuelto, ¿lo has logrado?

      0