MSYS2 gestión de paquetes
Introducción
MSYS2 es una colección de herramientas y librerías que proporcionan un entorno fácil de usar para crear, instalar y ejecutar software nativo de Windows.
Proporciona un terminal en línea de comandos, llamado mintty, control de versiones, herramientas como tar o awk. Hablaremos de estas herramientas en futuros artículos.
También nos permite acceder a compilaciones nativas actualizadas para varios compiladores y lenguajes como GCC, mingw-64, CPython, Rust, Ruby, etc.
Esto da acceso a multitud de APIs y aplicaciones de código abierto, escritas originalmente para varios sistemas operativos, desde Windows. Nos permite mantener esos paquetes actualizados de una forma sencilla, o desinstalarlos si fuese necesario.
MSYS2 dispone de diferentes entornos, así que lo primero que hay que decidir es cuál usar. Las diferencias entre los entornos son principalmente variables de entorno, compiladores/enlazadores por defecto, arquitectura, bibliotecas de sistema utilizadas, etc. En caso de duda, es preferible elegir UCRT64.
En nuestro caso, usando Code::Blocks con Mingw como compilador, lo más lógico sería elegir el entorno MINGW64, que usa el Toolchain gcc para la arquitectura x86_64 con las librerías msvcrt y libstdc++ para C y C++, respectivamente.
Por curiosidad, un toolchain es un conjunto de herramientas que se usan secuencialmente para generar ficheros ejecutable a partir de código fuente. En C++ esto incluye el compilador, enlazador (linker), depurador (debugger), entre otras.
Descarga e instalación
Para instalar MSYS2 en tu equipo hay que descargar desde https://www.msys2.org/ el programa de instalación. En el momento de escribir este artículo el fichero tiene el nombre "msys2-x86_64-20240113.exe", pero la parte del nombre correspondiente a la fecha podrá ser diferente en el futuro.
Ejecutar el instalador y elegir una ubicación para instalar, por ejemplo, c:\msys64. MSYS2 requiere una versión de Windows de 64 bits. y se debe instalar en una unidad con formato NTFS.
Abrir el terminal MSYS2 MINGW64, accesible desde el menú de inicio.
Herramienta pacman
pacman es la herramienta que sirve para instalar y actualizar paquetes (librerías y aplicaciones) desde MSYS2.
Esta herramienta dispone de muchas opciones, aunque solo veremos algunas de ellas.
Se puede visualizar una ayuda usando el comando pacman -h. Cuidado, las mayúsculas y minúsculas tienen significados diferentes.
$ pacman -h usage: pacman[...] operations: pacman {-h --help} pacman {-V --version} pacman {-D --database} pacman {-F --files} [options] [file(s)] pacman {-Q --query} [options] [package(s)] pacman {-R --remove} [options] pacman {-S --sync} [options] [package(s)] pacman {-T --deptest} [options] [package(s)] pacman {-U --upgrade} [options] use 'pacman {-h --help}' with an operation for available options
Si queremos más detalles sobre alguna operación en concreto podemos usar esa opción como segundo argumento. Por ejemplo, para ver las opciones de sincronización (actualización), podemos usar el comando pacman -h -S.
Esto nos mostrará otro texto de ayuda con las opciones de sincronización. Tenemos, por ejemplo, '-u' para actualizar los paquetes instalados, '-y' para descargar nuevas bases de datos de paquetes desde el servidor, '-v' para activar salidas de texto explicativas más extensas, etc. Estas opciones se pueden combinar en una única opción.
Por ejemplo, nuestra primera tarea consistirá en actualizar el propio MSYS2:
$ pacman -Suy
Esta orden sincronizará (actualizará) el sistema (MSYS2), descargando bases de datos de paquetes actualizadas desde el servidor.
Para buscar paquetes concretos dentro de las bases de datos usaremos pacman -Ss <cadena>, indicando en la cadena un texto que nos ayude a localizar el paquete concreto que buscamos, por ejemplo:
pacman -Ss sqlite3
Configurar el sistema
Para poder usar MSYS2 junto con Code::Blocks tendremos que descargar algunos paquetes.
La instalación de MSYS2 simplemente instala una versión no actualizada, la que estaba vigente cuando se creó el fichero de instalación, así que lo primero que tenemos que hacer es actualizar MSYS2:
pacman -Suy
Es probable que esta actualización necesite modificar el propio programa "pacman", por lo que se nos pedirá que cerremos la ventana de MSYS2 y volvamos a ejecutarla:
(2/2) upgrading pacman [###############################] 100% :: To complete this update all MSYS2 processes including this terminal will be closed. Confirm to proceed [Y/n]
Si es ese el caso, tendremos que repetir el paso anterior, para que se actualicen todos los paquetes que no se pudieron actualizar la primera vez.
Seguidamente instalaremos los paquetes de desarrollo:
pacman -Suy base-devel
Esto instalará o actualizará varios paquetes con las herramientas necesarias para compilar nuestras aplicaciones y librerías.
A continuación instalaremos los paquetes correspondientes al toolchain de Mingw.
pacman -Suy mingw-w64-x86_64-toolchain
Esto tardará algunos minutos, dependiendo de la velocidad de conexión a internet y del equipo.
Configurar Code::Blocks
Un pequeño inconveniente de utilizar Code::Blocks como IDE es que, cuando usamos la versión que incluye el compilador, tendremos una versión fija de éste. Actualmente, la versión de Code::Blocks es la 20.03, es decir, de marzo de 2020, lo que significa que el compilador no se ha actualizado desde esa fecha. Para la mayoría de los casos eso no es un problema serio, pero cuanto más lejos esté esa fecha de la actual, más probable es que echemos en falta alguna característica del lenguaje que se haya incorporado en versiones más recientes de MinGW.
Con MSYS2 hemos descargado una versión actualizada de MinGW, y podemos mantenerla actualizada con un simple comando desde su consola, solo nos falta que Code::Blocks use esa versión del compilador para compilar nuestras aplicaciones.
Con esto en mente, tal vez nos interese instalar la versión de Code::Blocks sin el compilador, ya que no vamos a utilizar el que se incluye con él. Pero esto es opcional. También, una vez configurado Code::Blocks para usar el compilador que hemos instalado desde MSYS2, podemos borrar la carpeta MinGW del directorio donde hayamos instalado Code::Blocks, aunque esto también es opcional. Incluso podemos optar por una de las compilaciones nocturnas de Code::Blocks, que en todos los casos se suministra sin compilador.
Para que Code::Blocks utilice el nuevo compilador tendremos que crear o modificar una cadena de herramientas nueva y usarla por defecto.
Esto es relativamente sencillo, desde el propio IDE:
Algunos artículos y videos recomiendan crear un nuevo Toolchain, pero yo creo que es preferible modificar uno de los existentes, en nuestro caso, el genérico "GNU GCC Compiler", ya que de este modo nos ahorramos muchos inconvenientes si abrimos un proyecto que usa un compilador que no existe en nuestras opciones de compilador de Code::Blocks.
- Abrimos el diálogo "Global compiler settings" desde el menú "Settings->Compiler".
- Activamos la pestaña "Toolchain executables".
- Buscamos el compilador "GNU GCC Compiler" en la lista de compiladores. (En algunas versiones de Code::Blocks existen varias versiones diferentes de este compilador para un mismo sistema operativo, en las últimas versiones nocturnas solo hay una para cada plataforma.)
- En la zona de "Compiler's installation directory" pulsamos "..." y buscamos la carpeta "C:\msys64\mingw64", asumiendo que msys está instalado en C:\.
- Los valores para cada una de las herramientas son (no es probable que haya que modificar ninguna de estos valores):
- C compiler: gcc.exe.
- C++ compiler: g++.exe.
- Linker for dynamic libs: g++.exe.
- Linker for static libs: ar.exe.
- Debugger: GDB/CDB debugger: Default.
- Resource compiler: windres.exe.
- Make program: mingw32-make.exe.
- Marcamos este toolchain para que sea el usado por defecto, pulsando el botón "Set as default".
También tendremos que configurar las opciones del depurador. Para ello usaremos el menú "Settings->Debugger...", y en el árbol de la izquierda del cuadro de diálogo seleccionaremos la rama "Default" y seleccionaremos un valor para "Executable path", que debe ser la ruta del fichero ejecutable del depurador. Si hemos instalado MSYS2 en "C:\msys64", y usamos MinGW43, la ruta será "C:\msys64\mingw64\bin\gdb.exe".
Es conveniente cerrar Code::Blocks después de modificar la configuración para que los nuevos valores se guarden en disco, de otro modo, si por algún motivo el IDE se cerrase por un crash, la configuración podría corromperse y tendríamos que desinstalar Code::Blocks y comenzar de nuevo desde el principio.
Instalación de un paquete
Pongamos por ejemplo que queremos instalar las librerías para usar sqlite en nuestros programas.
Primero localizaremos el paquete que tendríamos que instalar. Podemos acudir a la página paquetes mingw64 y buscar el paquete concreto para sqlite3, o podemos localizar el paquete desde pacman. Cuanto más específicos seamos con las cadenas a buscar, mejores resultados obtendremos. Nos interesan los paquetes para MinGW y para x86_64. De hecho, nuestros paquetes siempre empezarán con "mingw-w64-x86_64":
$ pacman -Ss mingw-w64-x86_64 sqlite3 mingw64/mingw-w64-x86_64-lua51-lsqlite3 0.9.5-2 LuaSQLite is a Lua 5 binding to allow users/developers to manipulate SQLite 2 and SQLite 3 databases (through different implementations) from lua (mingw-w64) mingw64/mingw-w64-x86_64-python-aiosqlite 0.19.0-2 asyncio bridge to the standard sqlite3 module (mingw-w64) mingw64/mingw-w64-x86_64-python-sqlitedict 2.1.0-2 Persistent dict, backed by sqlite3 and pickle, multithread-safe (mingw-w64) mingw64/mingw-w64-x86_64-sqlite3 3.45.0-1 [installed] A C library that implements an SQL database engine (mingw-w64) mingw64/mingw-w64-x86_64-sqlite3mc 1.8.2-1 SQLite3 encryption extension with support for multiple ciphers (mingw-w64)
Vemos que hay paquetes para LUA y Python, que ahora no nos interesan. Nos quedan los dos últimos, pero el último es una extensión para encriptado, que probablemente tampoco nos interese ahora. Por lo tanto, nuestro paquete es "mingw64/mingw-w64-x86_64-sqlite3", que en este ejemplo ya está instalado.
Para instalarlo usaremos pacman también:
$ pacman -S mingw64/mingw-w64-x86_64-sqlite3 warning: mingw-w64-x86_64-sqlite3-3.45.0-1 is up to date -- reinstalling resolving dependencies... Packages (1) mingw-w64-x86_64-sqlite3-3.45.0-1 Total Installed Size: 19.05 MiB Net Upgrade Size: 0.00 MiB :: Proceed with installation? [Y/n] (1/1) checking keys in keyring [###############################] 100% (1/1) checking package integrity [###############################] 100% (1/1) loading package files [###############################] 100% (1/1) checking for file conflicts [###############################] 100% (1/1) checking available disk space [###############################] 100% :: Processing package changes... (1/1) reinstalling mingw-w64-x86_64-sqlite3 [###############################] 100%
Configurar Code::Blocks para usar un paquete
Definir variables globales
Para cada librería que instalemos nos conviene crear un juego de variables globales en Code::Blocks.
Estas variables se usan para que el compilador y el enlazador puedan localizar los ficheros necesarios de cabecera y librerías.
- Desde el menú "Settings->Global variables" accedemos al diálogo de "Global Variable Editor".
- Creamos una variable nueva con el botón "New" y le asignamos el nombre, en este ejemplo, "sqlite3".
- En la zona de "Built-in fields" tenemos que asignar los valores siguientes (asumiendo que msys2 está instalado en C:\msys2:
- base: C:\msys64\mingw64.
- include: C:\msys64\mingw64\include.
- lib: C:\msys64\mingw64\lib.
- bin: C:\msys64\mingw64\bin.
- Cerramos el diálogo, "close".
Opciones de proyecto
Para cada proyecto que tenga que hacer uso de esta librería tendremos que modificar las opciones de proyecto. Esto se puede hacer desde el menú "Project->Build options" o desde el menú contextural en el árbol de proyectos:
- Aunque se pueden establecer opciones diferentes para las versiones de Debug y Release, es preferible hacerlo globalmente, seleccionando el proyecto completo en el árbol, de la izquierda.
- Si se trata de un proyecto creado antes de usar la versión MSYS de toolchain, tendremos que cambiar el compilador en "Selected compiler".
- En la pestaña "Linker settings" añadiremos la opción de la librería, ya sea estática o dinámica. Para enlazar con la librería dinámica, usaremos "libsqlite3.dll.a" o "sqlite3.dll". Para usar el enlazado estático usaremos "libsqlite3.a" o "sqlite3".
- Al seleccionar la pestaña "Search directories" se mostrará otro conjunto de pestañas:
- En la pestaña "Compiler" añadiremos el directorio donde encontrar los ficheros de cabecera, pero usaremos las variables globales. Para ello usaremos la expresión "$(#sqlite3.include)".
- En la pestaña "Linker" añadiremos el directorio donde se encuentren los ficheros para el enlazador. En nuestro ejemplo "$(#sqlite3.lib)".
Algunos paquetes instalan los ficheros de cabecera en una carpeta dentro de la carpeta include. Puedes incluir esa ruta en la variable, o hacerlo en las opciones de proyecto o en el código fuente.
Este no es el caso de sqlite3, pero si los ficheros de cabecera estuvieran en "C:\msys64\mingw64\include\sqlite3". Podríamos haber optado por incluir esa ruta completa en las variables globales. También podríamos haber usado solo la ruta "C:\msys64\mingw64\include", y añadir "sqlite3" a la ruta en los directorios de búsqueda del compilador por ejemplo "$(#sqlite3.include)/sqlite3".
Una tercera opción es añadir esa ruta en la directiva include:
#include "sqlite3/sqlite3.h"
Personalmente, prefiero la primera opción, o en determinados casos, la segunda. Solo nos conviene usar la tercera opción cuando compilemos programas de terceros, que asuman que los ficheros de cabecera se encuentran en una ruta concreta y lo especifiquen en las directivas include.
Referencias
Página oficial de msys2.org