jueves, 21 de octubre de 2021

Configurar Visual Studio Code para trabajar con C++ y G++


Introducción 

El objetivo de este post es de mantener una memoria práctica para compilar y depuerar en VSCode. De esta manera se eliminará la dependencia de un XCode o Visual Studio y apegarse a los estandares de g++, clang u otro compilador, sin importar el sistema operativo, siempre y cuando este pueda ejecutar el Visual Studio Code.


Entornos

Los entonrnos que se configurarón para la realización de este documentos son:

 Linux: 

  • OS: Manjaro 5.13.19-2
  • Visual Studio Code V 1.60.2
  • Compilador g++ (GCC) 11.1.0
  • Debuger: gdb

OSX:

  • OS: macOS Big Sur 11.5.2
  • Visual Studio Code V1.61.1
  • Compilador: Apple clang version 11.0.0 (clang-1100.0.33.17
  • Debuger: lldb-1100.0.30.12


Visual Studio Code:

  • C++ Extension Pack V1.0


Información Previa

Se requiere tener en cuenta que VSCode, para los poryecto de C/C++, se pueden utilizar varios extensiones que complementar la funcionalidad del VSCode. en mi caso he decidido trabajar con la extensión de microsoft C++ Extension Pack V1.0, la cual proporciona todos los elementos para codificar y depurar. 



Compilar on GNU g++

Antes de configurar el VSCode, es necesario tener en cuenta los comandos que requiere en este caso el g++. 

En mi caso, ocupo este paso para compilar la solición a modo de poder depurarlo "Debuging". Para construir una solucuión completa prefiero utilizar un archivo Makefile


$g++ -g [Flags] [Files] -o [Out File]


En este caso, las bandera más importante son:

  • -g Lo cual agrega la información requerida para realizar un depurado del compilado.
  • -o Nombre y ruta dónde se depositará el compilado.
Las secciones relacionadas a las banderas ([Flags]) son las banderas y sus parámentros que requiere la bandera, como puede ser la inclusión de una ruta en include. La sección de archivos ([Files]) corresponde a los archivos que se utilizarán para compilar, por ejemplo:

$g++ -g -L[Libs Path] -l[Lib Name] -I [Include Paths] main.cpp file2.cpp -o [Out file]

Con éste previo, se procederá a configurar las tareas que se utilizaran en VSCode para compilar y ejecutar


Tareas en VSCode

En cada proyecto de VSCode, se pueden configurar tareas de compilación, las cuales se verán reflejadas en el archivo .vscode/task.json.



Este archivo contendrá todas las tareas, tareas que serán ejecutadas en modo de consola de comandos. Para generar este archivo, siga estos pasos: 


Oprima F1.

Ecriba Tasks, y seleccione la opción Configure Task: 


Oprima enter y siga selecciones Crear archivo task.json desde plantilla:


Selecciones la opción Others, en este caso es mi preferido:


El archivo tasks.json se generará:



Parámetros

En este caso, compilación en C++, siga la siguiente plantilla:

{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ compilar archivo activo",
"command": "g++",
"args": [],
"group": "build",
"detail": "compilador: /usr/bin/g++"
        }
}


  • type: Tipo de tarea que se llevará a cabo. Para este caso se especificará el tipo de cppbuild.
  • label: Etiqueta con el que se identificará esta tarea.
  • command. Es el comando que se ejecutará. Ubiquelo en una consola de comandos. Si no esta dado de alta la ruta en el path, se deberá especifiar la ruta del commando, p.e: /usr/bin/g++.
  • args. Lista dearguments que requiere el comando. Cada elemento de los argumentos estan delimitados por un espacio en blanco, es decir, si se tiene el comando:

$g++ -g -I ./myPath -o  ./myPath/bin/out

"args": [
        "-g",
        "-I",
        "./myPath",
        "-o",        
        "./myPath/bin/out"
],


Para concer más detalles de los parámetros de configuración del archivo task.json, vea el link Integrate with external tools via Tasks:




Caso Básico

Compilación / Construcción

Este caso implica conocer los conceptos básicos de compilación.



Crear una tarea de compilación Shift + Ctrl + B, le solicitará crear una el archivio task.json:

{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ compilar archivo activo",
"command": "/usr/bin/g++",
"args": [
"-g",
"-std=c++17",
"${file}",
"-o",
"${fileDirname}/../bin/sample.out"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$g++"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Tarea generada por el depurador."
}
],
"version": "2.0.0"
}

  • command indica el compilador con el que se realizará la tarea, en este caso la de construir el programa.
  • args. contiene los parámetros de compilación que, en este caso, g++ utilizará, dónde
    • -std=c++17 Soporte para estándar C++17, puede indicarse el estándar 11 o 14.
    • -o indica la salida del compilador con un nombre especifico, establecido en el siguiente argumento, en este caso se refiere a sample.out.


Nota: ${fileDirname} es la macro para especificar el directorio sobre el archivo main.cpp, sobre el cual se debe ejecutar el comando de construcción Shift + Ctrl + B y seleccionando la tarea de compilación C/C++ g++ compiler archivo activo.





Iniciar la Depuración

{
// Use IntelliSense para saber los atributos posibles.
// Mantenga el puntero para ver las descripciones de los existentes atributos.
// Para más información, visite: https://go.microsoft.com/fwlink/?linkid=830387
//https://code.visualstudio.com/docs/cpp/launch-json-reference
"version": "0.2.0",
"configurations": [
{
"name": "(DEBUG) Iniciar",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/../bin/sample.out",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb"
}
]
}


Dónde los parámetros más importantes son:

  • type. El cual indica que una tarea de depuración de c++ gdb.
  • programm. Indica el compilado a ejecutar.
  • args: indica los argumentos con los que se ejecutará el programa a depurar.
  • externalConsole. Indica si se utilizará la consola de VSCode o la consola ecterna.
  • MIMode. Indica el depurador que utilizará el VSCode, hay dos tipos: gdb o lldb, este último para mac. 


Depuración con multiples archivos


Construcción

A diferencia del caso básico, aqui se debe definir en los argumentos de la compilación los archivos que se deben considerar para la compilación, como se haría en una el caso de compilarlo en línea de comando:

{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ compilar de Proyecto",
"command": "/usr/bin/g++",
"args": [
"-g",
"-std=c++17",
"${fileDirname}/main.cpp",
"${fileDirname}/myclass.cpp",
"-o",
"${fileDirname}/../bin/sample.out"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": "build",
"detail": "compilador: /usr/bin/g++"
}
]
}


Conclusión

En resume, la compilación del programa se debe especificar como una nueva tarea y tener en cuenta que se debe especificar el compilador y sus argumentos de compilación, como se haría en línea de comandos.

En lo que respecta a la depuración, el archivo launch.json contiene la configuración requerida para iniciar un progrma, utilizando el depurador gdb en linux o lldb en OSX.