Generadores, compiladores e IDEs
Es muy difícil escribir software que funcione correctamente y de manera eficiente. Entonces, una vez que un programa funciona en un determinado entorno, no queremos repetir parte del trabajo al moverlo a un compilador, procesador o sistema operativo diferente. Idealmente, no debería ser necesario realizar ningún cambio en absoluto. Kernighan & Pike - The Practice of Programming.
1. Concepto de portabilidad
Entendemos por portabilidad (Figura 1) la capacidad de compilar y depurar nuestros programas en otras plataformas diferentes a las que fueron escritos, sin que por ello tengamos que tocar ni una sola línea de código. Entendemos por plataforma a la combinación de un compilador y de una arquitectura CPU. Por ejemplo, v143_x64
hace referencia a Visual Studio 2022 e Intel 64bits. Entendemos por configuración al conjunto de flags y opciones del compilador que se han utilizado para generar los binarios.
- Copia de trabajo: En cada máquina deberá existir una copia del código fuente del proyecto. Normalmente esto se llevará a cabo mediante un sistema de control de versiones (SVN, Git, etc).
- CMake: creará o actualizará un proyecto de compilación a partir del código fuente utilizando
CMakeLists.txt
y los módulos del directorio/prj
. Esto se realizará de forma totalmente automática. - Compilar: Utilizando MSVC, GCC o Clang se compilará la solución y se generarán las librerías y ejecutables incluidos en la misma.
- Ejecutar/Depurar: Los binarios ya se podrán ejecutar y depurar en la plataforma de destino.
2. Generadores CMake
Recordamos que un compilador actúa sobre un único archivo fuente cada vez. Cuando compilamos un .c o .cpp se genera un archivo objeto (.o, .obj) que contiene el código binario de dicha fuente. Pero cualquier proyecto de cierta entidad contiene cientos de archivos, organizados en librerías que hay que enlazar para crear el (o los) ejecutables finales. Conocemos como build system a la herramienta que orquesta la compilación de todos los archivos del proyecto, con el fin de que sea lo más rápida y eficiente posible. Podemos decir que CMake es un meta-build system, capaz de generar proyectos de compilación para diferentes herramientas (Figura 2). Para ello utilizaremos la opción -G
.
|
cmake -G "Visual Studio 17 2022" cmake -G Ninja cmake -G Xcode cmake -G "Unix Makefiles" |
No todos los generadores funcionan en todas la plataformas y, por lo general, no hay una vinculación estricta entre generador y compilador. Por ejemplo, el generador Ninja
puede utilizar por debajo los compiladores MSVC, GCC y Clang. Lo mas importante que debemos recordar es que CMake, por medio del CMakeLists.txt
del proyecto, unifica todo el proceso de build haciéndolo trasparente para el desarrollador, independientemente del generador, compilador y plataforma.
3. Visual Studio
Visual Studio es el entorno de desarrollo por excelencia para Windows. En un mismo paquete integra el build system (msbuild), el compilador (MSVC) y el editor (IDE). Podemos utilizar cualquier versión, a partir de 2005, para compilar NAppGUI en Windows (Tabla 1). Como ya vimos en Inicio rápido lo primero que tenemos que hacer es lanzar CMake sobre el código fuente:
Compilador | Plataforma | S.O.Mínimo | |
Visual Studio 2022 | v143_x64 (x86) | Vista | |
Visual Studio 2019 | v142_x64 (x86) | Vista | |
Visual Studio 2017 | v141_x64 (x86) | Vista | |
Visual Studio 2015 | v140_x64 (x86) | Vista | |
Visual Studio 2013 | v120_x64 (x86) | Vista | |
Visual Studio 2012 | v110_x64 (x86) | Vista | |
Visual Studio 2010 | v100_x64 (x86) | XP | |
Visual Studio 2008 | v90_x64 (x86) | XP | |
Visual Studio 2005 | v80_x64 (x86) | XP |
|
cmake -G "Visual Studio 16 2019" -A x64 -T v120 -S . -B build |
-G
es la versión de Visual Studio (generador).-A
es la arquitectura Intel 32 o 64 bits:-T
es el Platform Toolset (o versión del compilador). Si omites este parámetro se tomará el último soportado por el compilador.-S
: Ruta donde se encuentra elCMakeLists.txt
.-B
: Ruta donde se generarán los proyectos de compilación, binarios y archivos temporales.-DNAPPGUI_DEMO=NO
: Evita generar las aplicaciones de ejemplo. Solo se compilará el SDK.
|
-G "Visual Studio 17 2022" -G "Visual Studio 16 2019" -G "Visual Studio 15 2017" -G "Visual Studio 14 2015" -G "Visual Studio 12 2013" -G "Visual Studio 11 2012" -G "Visual Studio 10 2010" -G "Visual Studio 9 2008" -G "Visual Studio 8 2005" |
|
-A x64 -A Win32 |
|
-T v143 -T v142 -T v141 -T v140 -T v120 -T v110 // For XP compatibility -T v141_xp -T v140_xp -T v120_xp -T v110_xp -T v100 -T v90 -T v80 |
El soporte para Visual Studio 8 2005 fue eliminado en CMake 3.12. Debes utilizar una versión anterior de CMake si aún sigues utilizando VS2005. NAppGUI NO funciona con versiones anteriores a VS2005.
NAppGUI no ofrece soporte para arquitecturas no x86, x64 en Windows: ARM, Itanium, etc.
Tras ejecutar CMake, en la carpeta /build
aparecerá una solución de VisualStudio, NAppGUI.sln
o el nombre que se haya configurado en project(NAppGUI)
del CMakeLists.txt
. Abre dicha solución y, desde Visual Studio, Build->Build Solution
para compilar Debug->Start Debugging
para depurar (Figura 3).
Para cambiar la versión de Visual Studio, selecciona otro generador en CMake -G "Visual Studio 15 2017", cierra y vuelve a abrir la solución.
Como ya vimos en Compilar NAppGUI, si tu intención es solo compilar el SDK, no es necesario que abras la solución en el editor. Puedes compilarla directamente desde la línea de comandos.
|
cmake -G "Visual Studio 17 2022" -S . -B build -DNAPPGUI_DEMO=NO cmake --build build --config Release -j 4 |
3.1. Platform toolset
A partir de Visual Studio 2010, se produce una disociación entre el editor y el compilador. El término Plaform Toolset identifica al propio compilador, que se podrá seguir utilizando con IDEs mas modernos. Si no indicamos nada, CMake utilizará el toolset incluido por defecto en cada versión de VS, pero se puede cambiar mediante el parámetro -T
de CMake (Tabla 2). Por ejemplo, podemos combinar Visual Studio 15 2017
con el toolset de VS2013 para Windows XP v120_xp
:
|
cmake -G "Visual Studio 15 2017" -A Win32 -T v120_xp -S . -B build |
Toolset (-T) | Versión de VS |
v143 | Visual Studio 2022 |
v142 | Visual Studio 2019 |
v141 | Visual Studio 2017 |
v141_xp | Visual Studio 2017 (con soporte XP) |
v140 | Visual Studio 2015 |
v140_xp | Visual Studio 2015 (con soporte XP) |
v120 | Visual Studio 2013 |
v120_xp | Visual Studio 2013 (con soporte XP) |
v110 | Visual Studio 2012 |
v110_xp | Visual Studio 2012 (con soporte XP) |
v100 | Visual Studio 2010 |
v90 | Visual Studio 2008 |
v80 | Visual Studio 2005 |
Es necesario que tengas instalada cada versión de Visual Studio para utilizar su toolset. Existen versiones "ligeras" que instalan las build tools sin el entorno de desarrollo.
3.2. Visual C++ Redistributable
Por defecto, Visual Studio enlaza dinámicamente las funciones de la librería estándar de C, lo que provoca que los .exe
puedan no funcionar en máquinas que no dispongan de las DLL de VC++
(Figura 4). Esto obliga a las aplicaciones a incluir una copia de MSVCRT.dll
, VCRUNTIME.dll
, ... o a instalar los famosos paquetes Visual C++ Redistributable para asegurar que la aplicación pueda correr sin problemas.
NAppGUI utiliza un reducido conjunto de la librería C, ya que accede directamente al API de Windows siempre que sea posible. Por esta razón, todas las aplicaciones creadas con NAppGUI realizan un enlace estático (opción /MT
) de las funciones necesarias de la stdlib, evitando dependencias a costa de aumentar ligeramente (unos pocos Kb) el tamaño del ejecutable final. Esto garantiza que las aplicaciones correrán sin problemas en todas las máquinas Windows sin necesidad de DLLs adicionales y sin tener que instalar los VC++ Redistributable.
Las aplicaciones NAppGUI no requieren los Visual C++ Redistributable. Tampoco utilizan las MFC "Microsoft Foundation Classes" ni la plataforma .NET.
3.3. Soporte WindowsXP
A partir de VS2012, el Platform Toolset genera ejecutables no compatibles con WindowsXP. Si queremos que nuestras aplicaciones corran en este sistema, deberemos seleccionar el toolset alternativo acabado en _xp
: v141_xp
, v140_xp
, v120_xp
, v110_xp
. O bien los v100
, v90
ó v80
(VS2010, 2008, 2005), que sí soportan directamente XP (Figura 5).
El soporte para WindowsXP se ha eliminado definitivamente en Visual Studio 2019. No existe el Platform Toolset v142_xp.
No se pueden crear aplicaciones con NAppGUI que funcionen en Windows anteriores a XP.
3.4. Soporte SSE
Con el Pentium III, Intel incorporó un juego de instrucciones adicional para operaciones en coma flotante denominado SSE Streaming SIMD Extensions. Esto permite optimizar los cálculos matemáticos a costa de perder la compatibilidad, ya que las aplicaciones que utilicen SSE no funcionarán en los modelos Pentium II o anteriores. En NAppGUI se han reservado los toolset v80_x86
y v90_x86
para crear aplicaciones compatibles con los procesadores más antiguos (Tabla 3). A partir de v100_x86
, se utilizará SSE2 en todos los toolset.
Toolset | SSE | CPU Mínima |
v80_x86 | x87 (no SSE) | Pentium II/AMD K6 |
v90_x86 | SSE | Pentium III/AMD Duron |
v100_x86 | SSE2 | Pentium IV/AMD Sempron |
v110_x86 | SSE2 | Pentium IV/AMD Sempron |
... | SSE2 | ... |
El soporte SSE solo se deshabilita en arquitecturas de 32 bits (x86). Todas las CPU de 64 bits (x64) incorporan SSE2.
4. MinGW
MinGW-w64 es un proyecto creado para soportar los compiladores GCC/Clang en sistemas Windows. Se bifurcó en 2007 del original mingw.org
. Además de los compiladores, proporciona las cabeceras y librerías de Win32, lo que permite crear aplicaciones nativas de Windows, sin necesidad de instalar VisualStudio. A partir de la versión 1.4.2, NAppGUI proporciona soporte para este entorno.
4.1. MinGW-GCC
Para compilar NAppGUI con MinGW-GCC (Tabla 4) haremos:
|
cmake -G "MinGW Makefiles" -S . -B build -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release cmake --build build -j 4 |
-DCMAKE_BUILD_TYPE=[Debug|Release]
: Al contrario que VisualStudio, MinGW está basado en la herramientamake
la cual es mono-configuración. Deberemos indicarla en tiempo de generación y no de compilación.
Compilador | Plataforma | S.O.Mínimo | |
MinGW-GCC 13 | mwgcc13_2_0_x64 | Vista |
Al no generarse proyectos IDE, recomendamos utilizar Visual Studio Code o Eclipse CDT para depurar proyectos generados con MinGW.
4.2. MinGW-Clang
Si queremos utilizar el compilador Clang (Tabla 5) en lugar de GCC:
|
cmake -G "MinGW Makefiles" -S . -B build -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release cmake --build build -j 4 |
Compilador | Plataforma | S.O.Mínimo | |
MinGW-Clang 18 | mwclang18_1_4_x64 | Vista |
4.3. MSYS2
Si bien existen diferentes maneras de instalar MinGW, la más directa, actualizada y recomendada es hacerlo a través de una consola MSYS2. Este proyecto recrea un terminal Unix en Windows, proporcionando las típicas herramientas (grep
, sed
, curl
, ...) y comandos (ls
, cp
, rm
, cat
, ...). MSYS2 también incluye el gestor de paquetes pacman
.
- Descarga MSYS2 desde https://www.msys2.org/. La instalación típica es en
C:\msys64
. - Abre un terminal MSYS2 (Figura 6) y teclea:
- Edita las variables de entorno de Windows añadiendo estas rutas a
PATH
: - Abre un terminal
CMD
y comprueba que los compiladores funcionan:
|
# GCC install pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain # Clang install pacman -S mingw-w64-x86_64-clang |
|
C:\msys64\mingw64\bin C:\msys64\ucrt64\bin |
|
C:\>gcc --version gcc (Rev6, Built by MSYS2 project) 13.2.0 C:\>clang --version clang version 18.1.4 C:\>mingw32-make -version GNU Make 4.4.1 |
Por último, es posible que quieras compilar a través de la consola MSYS2 en lugar del CMD de Windows. En ese caso:
|
# GCC compiler under MSYS cmake -G "MSYS Makefiles" -S . -B build -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release # Clang compiler under MSYS cmake -G "MSYS Makefiles" -S . -B build -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release # Build cmake --build build -j 4 |
Tanto MinGW como MSYS utilizan las mismas versiones Windows nativas de GCC y Clang. La diferencia entre ambos generadores radica en las utilidades que orquestan la compilación: Windows-like (MinGW) y Unix-like (MSYS).
5. Xcode
Para compilar para los iMac, macBook y macMini de Apple necesitaremos Xcode a partir de la versión 3.2.6 (Tabla 6). NAppGUI permite generar aplicaciones que funcionen en MacOSX 10.6 Snow Leopard y posteriores:
Compilador | S.O.Mínimo | Plataforma | |
Xcode 15.0.1 | Sonoma | sdk14_0_x64 (arm) | |
Xcode 14.3.1 | Ventura | sdk13_6_x64 (arm) | |
Xcode 13.4.1 | Monterey | sdk12_3_x64 (arm) | |
Xcode 12.5.1 | Big Sur | sdk11_5_x64 (arm) | |
Xcode 11.7 | Catalina | sdk10_15_x64 | |
Xcode 10.3 | Mojave | sdk10_14_x64 | |
Xcode 9.4.1 | High Sierra | sdk10_13_x64 | |
Xcode 8.3.3 | Sierra | sdk10_12_x64 | |
Xcode 7.3.1 | El Capitan | sdk10_11_x64 | |
Xcode 6.4 | Yosemite | sdk10_10_x64 | |
Xcode 6.2 | Mavericks | sdk10_9_x64 | |
Xcode 5.1.1 | Mountain Lion | sdk10_8_x64 | |
Xcode 4.6.3 | Lion | sdk10_7_x64 | |
Xcode 3.2.6 | Snow Leopard | sdk10_6_x64 (x86) |
|
cmake -G Xcode -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 -DCMAKE_ARCHITECTURE=arm64 -S . -B build |
-G
siempreXcode
. Utilizarxcode-select
para alternar si tienes varias versiones instaladas.-DCMAKE_OSX_DEPLOYMENT_TARGET
. Sistema operativo mínimo que será soportado. Si se omite se establecerá el Base SDK incluido en la versión de Xcode.-DCMAKE_ARCHITECTURE
.arm64
,x64
,i386
. La arquitecturaarm64
se incluye a partir del SDK 11.0 Big Sur. Lai386
se declaró obsoleta en macOS 10.13 High Sierra.
|
-DCMAKE_OSX_DEPLOYMENT_TARGET=14.0 // Sonoma -DCMAKE_OSX_DEPLOYMENT_TARGET=13.6 // Ventura -DCMAKE_OSX_DEPLOYMENT_TARGET=13.5 // Ventura -DCMAKE_OSX_DEPLOYMENT_TARGET=13.4 // Ventura -DCMAKE_OSX_DEPLOYMENT_TARGET=13.3 // Ventura -DCMAKE_OSX_DEPLOYMENT_TARGET=13.2 // Ventura -DCMAKE_OSX_DEPLOYMENT_TARGET=13.1 // Ventura -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 // Ventura -DCMAKE_OSX_DEPLOYMENT_TARGET=12.4 // Monterey -DCMAKE_OSX_DEPLOYMENT_TARGET=12.3 // Monterey -DCMAKE_OSX_DEPLOYMENT_TARGET=12.2 // Monterey -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 // Monterey -DCMAKE_OSX_DEPLOYMENT_TARGET=11.5 // Big Sur -DCMAKE_OSX_DEPLOYMENT_TARGET=11.4 // Big Sur -DCMAKE_OSX_DEPLOYMENT_TARGET=11.3 // Big Sur -DCMAKE_OSX_DEPLOYMENT_TARGET=11.2 // Big Sur -DCMAKE_OSX_DEPLOYMENT_TARGET=11.1 // Big Sur -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 // Big Sur -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 // Catalina -DCMAKE_OSX_DEPLOYMENT_TARGET=10.14 // Mojave -DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 // High Sierra -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 // Sierra -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 // El Capitan -DCMAKE_OSX_DEPLOYMENT_TARGET=10.10 // Yosemite -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 // Mavericks -DCMAKE_OSX_DEPLOYMENT_TARGET=10.8 // Mountain Lion -DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 // Lion -DCMAKE_OSX_DEPLOYMENT_TARGET=10.6 // Snow Leopard |
|
-DCMAKE_ARCHITECTURE=arm64 -DCMAKE_ARCHITECTURE=x64 -DCMAKE_ARCHITECTURE=i386 |
NAppGUI no soporta la creación de Apple's Fat binaries. Debes indicar un solo valor en este campo.
-S
: Ruta donde se encuentra elCMakeLists.txt
.-B
: Ruta donde se generarán los proyectos de compilación, binarios y archivos temporales.-DNAPPGUI_DEMO=NO
: Evita generar las aplicaciones de ejemplo. Solo se compilará el SDK.
Tras ejecutar CMake, en la carpeta /build
aparecerá una solución de Xcode, NAppGUI.xcodeproj
o el nombre que se haya configurado en project(NAppGUI)
del CMakeLists.txt
. Al abrir la solución Xcode, vemos los diferentes proyectos que la forman, incluidos Die y Dice. Seleccionamos Die en el desplegable superior izquierdo y después pulsamos Play
o Product->Run
(Figura 7). Esto compilará el programa y lo lanzará en modo depuración, donde podremos establecer puntos de ruptura para inspeccionar la pila y el valor de las variables.
5.1. Base SDK y Deployment Target
Cada año, Apple lanza una nueva versión de macOS, que viene acompañada de un nuevo SDK y de la actualización de Xcode que incluye dicho SDK. A esta se denomina Base SDK.
Base SDK es la versión incluida en cada nueva versión mayor de Xcode, que coincide con la última versión del sistema macOS aparecida en el mercado.
Apple tiene una política mucho más restrictiva que Microsoft en lo referente a la compatibilidad de las aplicaciones con versiones anteriores del sistema operativo. Por defecto, un programa compilado con SDK 10.14 (macOS Mojave) no funcionará en el inmediatamente anterior macOS High Sierra (Figura 8).
Para evitar este problema, y que las aplicaciones funcionen en macOS más antiguos, existe el parámetro Deployment Target. Al utilizarlo, se activará una macro que anulará las nuevas características del Base SDK. Esto permitirá que el programa corra en versiones antiguas a costa, claro está, de no tener acceso a las últimas funcionalidades de los iMac. Podrás seleccionar el Deployment Target requerido por tu proyecto a través del parámetro -DCMAKE_OSX_DEPLOYMENT_TARGET
, como ya hemos visto en el apartado anterior.
Xcode 14 considera obsoletos los Deployment Target inferiores a 10.13 (Figura 9). Utiliza Xcode 13 si quieres compatibilidad con Mac OSX 10.12 Sierra y anteriores.
Xcode 8 considera obsoletos los Deployment Target inferiores a 10.9 (Figura 10). Utiliza Xcode 7 si quieres compatibilidad con Mac OSX 10.8 Mountain Lion y anteriores.
5.2. xcode-select
Ya hemos visto que CMake solo ofrece un generador para Xcode (-G Xcode
), aunque es posible tener varias versiones instaladas en la misma máquina, cada una dentro de su propio bundle Xcode.app
. Siempre existirá un Xcode por defecto en el sistema (el más reciente) pero se puede cambiar mediante la utilidad xcode-select
:
|
xcode-select -p /Applications/Xcode.app/Contents/Developer |
|
sudo xcode-select -s /Applications/Xcode8.app/Contents/Developer |
|
sudo xcode-select -r |
Deberás ejecutar de nuevo cmake -G Xcode cada vez que utilices xcode-select
para que tu proyecto actualice el cambio de compilador.
5.3. macOS ARM
En Noviembre de 2020 Apple lanza su nueva línea de ordenadores de sobremesa y portátiles (iMac, macBook y macMini) basados en el procesador Apple M1 con arquitectura ARM (Figura 11). A pesar que son capaces de ejecutar programas compilados para Intel x64 mediante el programa Rosetta 2 (Figura 12) lo ideal sería compilar nuestras aplicaciones para la nueva arquitectura con el fin de optimizar al máximo los ejecutables.
NAppGUI soporta la compilación para la arquitectura Apple ARM. Tan solo deberás incluir la opción -DCMAKE_ARCHITECTURE=arm64
en CMake, como ya vimos en la sección anterior.
Puedes compilar la arquitectura M1 desde máquinas Intel x64, pero no podrás depurar los ejecutables.
La arquitectura M1 solo está disponible para el sistema Big Sur (macOS 11.0) y posteriores.
5.4. macOS 32bits
Desde la versión macOS High Sierra, Apple ha declarado obsoleta la arquitectura de 32 bits, emitiendo avisos a los usuarios en el caso de detectar ejecutables i386
(Figura 13). A partir de Xcode 10, no se puede compilar en esta arquitectura (Figura 14).
El soporte para aplicaciones 32bits ha desaparecido definitivamente en macOS Catalina, que solo permite ejecutar aplicaciones de 64bits.
Esto tiene cierto sentido ya que todos los modelos de iMac basados en Intel incorporan procesadores de 64 bits, a excepción de unos pocos modelos de 2006 en policarbonato blanco que montaban el Intel Core Duo de 32 bits (Figura 15). Estos iMac admitían como máximo el Mac OSX 10.6 Snow Leopard, siendo requisito fundamental a partir de 10.7 Lion, el disponer de una CPU de 64 bits. Para compilar sin problemas en 32bits hay que utilizar, como máximo, Xcode 6 (Figura 16).
6. macOS Make
La utilidad Unix Make
se incluye como parte de las build tools de Xcode. Por tanto, podemos utilizarla como generador en macOS, si podemos prescindir de los proyectos Xcode. Make es mono-configuración, por lo que debemos indicar el tipo de configuración durante la generación.
|
cmake -G "Unix Makefiles" -S . -B build -DNAPPGUI_DEMO=NO -DCMAKE_BUILD_TYPE=Release cmake --build build |
7. Linux GCC
Para las versiones Linux, utilizaremos el compilador gcc
(Tabla 7) y la herramienta make
para generar los binarios, pero no existe un entorno de desarrollo "oficial" tal como ocurre en Windows y macOS. Para realizar una configuración elemental de nuestro equipo teclear los siguientes comandos en un terminal:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// Development tools sudo apt-get install build-essential sudo apt-get install git sudo apt-get install cmake // Development libraries sudo apt-get install libgtk-3-dev sudo apt-get install libglu1-mesa-dev freeglut3-dev mesa-common-dev sudo apt-get install libcurl4-openssl-dev // GTK Inspector (Ctrl+D when debugging) gsettings set org.gtk.Settings.Debug enable-inspector-keybinding true // Check system libraries version pkg-config --modversion gtk+-3.0 3.24.20 pkg-config --modversion libcurl 7.68.0 |
S.O.Mínimo | Compilador | Toolkit | Plataforma | |
Ubuntu 24.04 LTS | GCC 13.2.0 | GTK 3.24.41 | gcc13_2_0_gtk3_x64 | |
Ubuntu 22.04 LTS | GCC 11.2.0 | GTK 3.24.33 | gcc11_2_0_gtk3_x64 | |
Ubuntu 20.04 LTS | GCC 9.4.0 | GTK 3.24.20 | gcc9_4_0_gtk3_x64 | |
Ubuntu 18.04 LTS | GCC 7.5.0 | GTK 3.22.30 | gcc7_5_0_gtk3_x64 | |
Ubuntu 16.04 LTS | GCC 5.4.0 | GTK 3.18.9 | gcc5_4_0_gtk3_x64 (x86) | |
Ubuntu 14.04 LTS | GCC 4.8.4 | GTK 3.10.8 | gcc4_8_4_gtk3_x64 (x86) | |
Ubuntu 12.04 LTS | GCC 4.6.3 | GTK 3.4.2 | gcc4_6_3_gtk3_x64 (x86) | |
Raspbian 11 Bullseye | GCC 10.2.1 | GTK 3.24.24 | gcc10_gtk3_arm64 | |
Raspbian 10 Buster | GCC 8.3.0 | GTK 3.24.5 | gcc8_gtk3_arm | |
Raspbian 9.1 Strech | GCC 6.3.0 | GTK 3.22.11 | gcc6_gtk3_arm | |
Raspbian 8.0 Jessie | GCC 4.9.2 | GTK 3.14.5 | gcc4_9_gtk3_arm |
Al igual que hicimos en Windows y macOS, ejecutamos cmake
para generar el proyecto de compilación:
|
cmake -G "Unix Makefiles" -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_ARCHITECTURE=x64 -DCMAKE_TOOLKIT=GTK3 -S . -B build |
-G
siempre"Unix Makefiles"
. Adicionalmente se pueden crear proyectos para los principales IDEs disponibles en Linux:DCMAKE_C_COMPILER
. Compilador de C. Por defecto,gcc
.DCMAKE_CXX_COMPILER
. Compilador de C++. Por defecto,g++
.-DCMAKE_BUILD_TYPE
. A diferencia de Visual Studio y Xcode, Make no permite la creación de proyectos multi-configuración. Hay que indicarla en el momento de la generación:-DCMAKE_ARCHITECTURE
.x64
,i386
,arm
,arm64
. En Linux no se permite la compilación cruzada. Deberemos seleccionar la misma arquitectura que la máquina anfitrión. Este parámetro puede omitirse, se configurará automáticamente.-DCMAKE_TOOLKIT
. A día de hoy, la única opción disponible esGTK3
, ya que NAppGUI no soporta otros toolkits gráficos. Este parámetro puede omitirse, se configurará automáticamente.-S
: Ruta donde se encuentra elCMakeLists.txt
.-B
: Ruta donde se generarán los proyectos de compilación, binarios y archivos temporales.-DNAPPGUI_DEMO=NO
: Evita generar las aplicaciones de ejemplo. Solo se compilará el SDK.
|
-G "Unix Makefiles" -G "CodeBlocks - Unix Makefiles" -G "CodeLite - Unix Makefiles" -G "Sublime Text 2 - Unix Makefiles" -G "Kate - Unix Makefiles" -G "Eclipse CDT4 - Unix Makefiles" |
|
-DCMAKE_BUILD_TYPE=Debug -DCMAKE_BUILD_TYPE=Release -DCMAKE_BUILD_TYPE=ReleaseWithAssert |
|
-DCMAKE_ARCHITECTURE=x64 // Only in Linux Intel 64bits hosts -DCMAKE_ARCHITECTURE=i386 // Only in Linux Intel 32bits hosts -DCMAKE_ARCHITECTURE=arm // Only in Linux ARM 32bits hosts -DCMAKE_ARCHITECTURE=arm64 // Only in Linux ARM 64bits hosts |
|
-DCMAKE_TOOLKIT=GTK3 |
Tras ejecutar cmake
tendremos, en la carpeta /build
una serie de Makefiles
preparados para compilar el proyecto.
|
cmake --build build -j 4 ... [ 93%] Linking CXX executable ../../Debug/bin/DrawBig [ 93%] Linking CXX executable ../../Debug/bin/GuiHello [ 93%] Built target DrawBig [ 94%] Building C object howto/drawhello/CMakeFiles/DrawHello.dir/resgen/res_drawhello.c.o [ 94%] Linking CXX executable ../../Debug/bin/Col2dHello [ 98%] Built target GuiHello [ 98%] Building C object howto/drawimg/CMakeFiles/DrawImg.dir/resgen/res_drawimg.c.o [ 98%] Linking CXX executable ../../Debug/bin/UrlImg [ 98%] Linking CXX executable ../../Debug/bin/DrawHello [ 98%] Built target Col2dHello [ 98%] Linking CXX executable ../../Debug/bin/ColorView [ 98%] Built target UrlImg [ 98%] Built target DrawHello [ 99%] Linking CXX executable ../../Debug/bin/DrawImg [100%] Built target ColorView [100%] Built target DrawImg |
Una vez terminada la compilación, podemos lanzar los ejecutables directamente desde el terminal:
|
./build/demo/die/Debug/Die |
Si tienes cierta soltura con gdb
, puedes intentar depurar el código directamente desde el terminal (Figura 17). Más adelante veremos como hacerlo mediante Eclipse y Visual Studio Code.
|
gdb ./build/demo/die/Debug/Die (gdb) run ... |
Para generar las aplicaciones de ejemplo, debes omitir la opción -DNAPPGUI_DEMO=NO
en CMake.
7.1. Múltiples versiones de GCC
Aunque cada distribución de Linux incorpora una versión "canónica" de GCC, es posible tener varias instaladas en la misma máquina y alternar entre ellas de forma similar a como hacíamos en macOS con xcode-select
. Para ello utilizaremos el comando update-alternatives
de Linux. Suponemos que estamos en Ubuntu 18.04 LTS:
|
gcc --version gcc 7.5.0 |
|
sudo apt-get install gcc-6 g++-6 |
|
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 60 --slave /usr/bin/g++ g++ /usr/bin/g++-7 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 50 --slave /usr/bin/g++ g++ /usr/bin/g++-6 |
|
sudo update-alternatives --set gcc /usr/bin/gcc-6 gcc --version gcc 6.5.0 g++ --version g++ 6.5.0 |
|
sudo update-alternatives --auto gcc gcc --version gcc 7.5.0 g++ --version g++ 7.5.0 |
7.2. Linux 32bits
Para compilar aplicaciones 32bits desde un sistema Ubuntu 64bits es necesario instalar el paquete multilib
:
|
sudo apt-get install gcc-multilib |
Pero actualmente existen problemas para realizar compilación cruzada que incluya la librería GTK+, por lo que no será posible utilizar la misma máquina de desarrollo para generar en ambas arquitecturas, como ocurre en Windows. Las aplicaciones de consola o librerías que no accedan a GTK sí que se pueden compilar en 32bits desde un ordenador de 64bits.
No es posible compilar en 32bits desde un sistema Ubuntu de 64bits aplicaciones que utilicen GTK+3. Debes utilizar para ello un sistema Linux de 32bits.
7.3. Linux ARM
La arquitectura ARM Advanced RISC Machine es la predominante en el mercado de los dispositivos embebidos como teléfonos inteligentes y tablets. Actualmente, NAppGUI no ofrece soporte para el desarrollo de aplicaciones móviles iOS/Android, pero sí para otro tipo de placas que soporten versiones de Linux ARM "de escritorio", como la Raspberry PI. Para portar nuestro código a Raspberry Pi hay que seguir los mismos pasos que en Ubuntu Linux (Figura 18). Ambas distribuciones están basadas en Debian, por lo que disponemos de GCC, CMake y Make de forma directa a través de apt-get
.
8. Linux Clang
GCC es el compilador por defecto que se instala con el paquete build-essential
. No obstante, podemos utilizar Clang si así lo preferimos (Tabla 8). Lo primero es instalar el compilador:
|
sudo apt-get install clang clang --version clang version 10.0.0-4ubuntu1 |
S.O.Mínimo | Compilador | Toolkit | Plataforma | |
Ubuntu 24.04 LTS | Clang 18.1.3 | GTK 3.24.41 | clang18_1_3_gtk3_x64 | |
Ubuntu 22.04 LTS | Clang 14.0.0 | GTK 3.24.33 | clang14_0_0_gtk3_x64 | |
Ubuntu 20.04 LTS | Clang 10.0.0 | GTK 3.24.20 | clang10_0_0_gtk3_x64 | |
Ubuntu 18.04 LTS | Clang 6.0.0 | GTK 3.22.30 | clang6_0_0_gtk3_x64 | |
Ubuntu 16.04 LTS | Clang 3.8.0 | GTK 3.18.9 | clang3_8_0_gtk3_x64 (x86) | |
Ubuntu 14.04 LTS | Clang 3.4.0 | GTK 3.10.8 | clang3_4_0_gtk3_x64 (x86) | |
Ubuntu 12.04 LTS | Clang 3.0.0 | GTK 3.4.2 | clang3_0_0_gtk3_x64 (x86) |
Para utilizar Clang, tan solo cambiamos el nombre del compilador a la hora de generar el proyecto de compilación:
|
cmake -G "Unix Makefiles" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_ARCHITECTURE=x64 -DCMAKE_TOOLKIT=GTK3 -S . -B build |
9. Linux GTK
A diferencia de Windows y macOS, Linux soporta multitud de entornos de escritorio basados en diferentes librerías (o toolkits) siendo GTK y Qt las dos más famosas. NAppGUI utiliza GTK+3 para la parte gráfica ya que es la base del entornos Gnome, Xfce, Lxde, etc, (Tabla 9) presentes en muchas de las distribuciones mas extendidas. GTK+3 estará presente de forma natural en todas ellas, no siendo necesarias otras dependencias adicionales. Eso sí, para compilar bajo GTK+3 tendremos que instalar la versión de desarrollador, como vimos anteriormente.
Entorno | Distribuciones | |
Gnome | Ubuntu, Debian, Fedora, Red Hat, CentOS, Manjaro, Suse, Arch, ... | |
Xfce | Xubuntu, Debian, Fedora, Manjaro, ... | |
Lxde | Lubuntu, Raspbian, Debian, Fedora, Mandriva, ... | |
Cinnamon | Mint, Debian, Ubuntu, Fedora, OpenSuse, ... | |
Mate | Ubuntu Mate, Mint, Debian, Fedora, OpenSuse, ... | |
Pantheon | Elementary OS | |
Sugar |
10. Ninja
El generador Ninja
permite realizar compilaciones más rápidas que Visual Studio, Xcode o Make, a cambio de perder los proyectos *.sln, *.vcxproj o *.xcodeproj muy útiles para depurar desde el IDE. Suele utilizarse en sistemas de integración continua donde prima la velocidad en pro de la versatilidad.
Para instalar Ninja en Windows, lo descargamos desde Ninja, copiamos ninja.exe
en cualquier carpeta del sistema y lo hacemos accesible mediante la variable PATH
.
|
ninja --version 1.11.1 |
En macOS, lo instalaremos mediante brew
:
|
brew install ninja ninja --version 1.11.1 |
Y en Linux desde apt-get
:
|
sudo apt-get install ninja-build ninja --version 1.10.1 |
Utilizar Ninja es exactamente igual que en casos anteriores. Tan solo cambiaremos el nombre del generador en CMake.
|
cmake -G Ninja -S . -B build -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release cmake --build build |
También podemos utilizar la versión multi-configuración de Ninja:
|
cmake -G "Ninja Multi-Config" -S . -B build -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release |
CMake soporta "Ninja Multi-Config" a partir de la versión 3.17.
-DCMAKE_C_COMPILER/DCMAKE_CXX_COMPILER
: Ninja utilizará cualquier compilador de C/C++ que tengamos instalado.gcc/g++
,clang/clang++
ocl/cl
(MSVC).
En Windows, el compilador MVSC
, en principio, no es accesible directamente desde línea de comandos. Para hacerlo accesible tenemos dos formas:
- Utilizar la consola
Developer Command Prompt 2022
(o la versión que toque). Este terminal conoce la ubicación de las herramientas de build. - Establecer las variables de entorno mediante el script
vcvarsall.bat [Win32|x64]
. Una posible ubicación será"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
, pero cambiará en función de la versión de Visual Studio que tengamos instalada.
11. Configuraciones
NAppGUI se puede compilar en tres configuraciones diferentes, en función del nivel de depuración que necesitemos.
- Debug: Incluye información de depuración en los binarios y no se realizan optimizaciones del código. Es la versión para el desarrollador.
- Release: Se elimina la información de depuración y se realizan todas las optimizaciones posibles. Es la versión para el usuario.
- ReleaseWithAssert: Es la versión de Release, pero dejando activas las sentencias Asserts. Está dirigida al usuario final, pero en casos donde sea necesario obtener información detallada de posibles anomalías, a costa de una bajada del rendimiento global del programa.
Tanto Visual Studio como Xcode son entornos multi-configuración, es decir, podemos alternar entre una y otra directamente desde el propio editor. En Visual Studio tenemos un desplegable en la parte superior del editor (Figura 19).
En Xcode está un poco más escondido. Hacemos Product->Scheme->Edit Scheme
. Aparecerá una ventana emergente. Seleccionamos Run->Info->Build Configuration
(Figura 20).
Desafortunadamente, Unix Makefiles
y Ninja
no soportan múltiples configuraciones. Esto nos obliga a introducir la propiedad CMAKE_BUILD_TYPE
(Figura 21) para establecer la configuración en CMake antes de generar los scripts de build.
|
cmake -G Ninja -S . -B build DCMAKE_BUILD_TYPE=Release cmake --build build |
|
cmake -G Xcode -S . -B build cmake --build build --config Release |
12. Eclipse CDT
Los generadores basados en Ninja
y Unix Makefiles
están orientados a terminal, mientras que los basados en Visual Studio
y Xcode
generan un proyecto IDE. Trabajar directamente con el terminal nos brinda una gran flexibilidad a la hora de configurar nuestras propias herramientas. Con volver a la consola y teclear cmake --build build
se re-compilará todo lo necesario. Ahora bien, utilizar GDB
directamente resultará bastante tedioso, por lo que resultará de gran utilidad disponer de IDE alternativos para depurar proyectos basados en estos generadores. En el desarrollo de NAppGUI utilizamos dos: Eclipse CDT y Visual Studio Code.
- Eclipse CDT es una plataforma de código abierto compuesta por un conjunto de herramientas de programación en C/C++ disponible desde 2021 en todas las plataformas. Para utilizarlo deberemos anteponer
Eclipse CDT4
al nombre del generador: - Adicionalmente a los
Makefile
, se crearán los archivos.cproject
y.project
necesarios para importar el proyecto dentro de Eclipse. - Abrimos Eclipse y hacemos
File->Import->Existing Projects into Workspace
. Aparecerá un cuadro de diálogo donde indicamos el directorio build que hayamos configurado en CMake (/build
). Eclipse abrirá el proyecto situando a la izquierda un árbol con todos los archivos. - Para compilar
Project->Build All
. - A la hora de depurar (Die en este caso) desplegamos el árbol
Binaries
, seleccionando el ejecutable, clic derechoDebug As->Local C/C++ Application
(Figura 22). - Por último situaremos los Breakpoints donde nos interese y navegaremos por el código paso a paso, inspeccionando variables o la pila de llamadas (Figura 23).
|
-G "Eclipse CDT4 - Unix Makefiles" -G "Eclipse CDT4 - MinGW Makefiles" -G "Eclipse CDT4 - Ninja" |
Algunas opciones interesantes de Eclipse CDT bajo Window->Preferences
.
- Run/Debug->Launching->Terminate and Relaunch while launching.
13. Visual Studio Code
Otro entorno interesante para desarrollar y depurar es Visual Studio Code. Con las extensiones apropiadas, es posible trabajar en C/C++ con CMake de una forma muy cómoda y fluida. Dispones de instaladores para todas las plataformas, pero también está disponible desde varios gestores de paquetes, por ejemplo apt-get
:
|
sudo apt-get install code |
Añadimos, como mínimo, C/C++ Extension Pack que incluirá también soporte para CMake (Figura 24).
Abrimos nuestro proyecto con Open Folder
. Posteriormente, ejecutamos CMake desde el propio entorno: [F1]->CMake:Configure
. La primera vez, VSCode preguntará por la ubicación del CMakeLists.txt
principal (Figura 25) en caso que no lo encuentre en el directorio raíz.
Tras la configuración ya podemos compilar con [F1]->CMake:Build
. En la pestaña Output de VSCode veremos la evolución del proceso:
|
[build] [ 97%] Building C object demo/die/CMakeFiles/Die.dir/resgen/res_die.c.o [build] [ 98%] Built target Bode [build] [ 98%] Building C object demo/products/CMakeFiles/Products.dir/products.c.o [build] [ 98%] Built target Fractals [build] [ 98%] Building C object demo/products/CMakeFiles/Products.dir/prview.c.o [build] [ 99%] Linking CXX executable ../../Debug/bin/Die [build] [100%] Building C object demo/products/CMakeFiles/Products.dir/resgen/res_products.c.o [build] [100%] Built target Die [build] [100%] Linking CXX executable ../../Debug/bin/Products [build] [100%] Built target Products |
Para depurar, lo primero es seleccionar el target (o ejecutable) con [F1]->CMake:Set Debug Target
(Figura 26).
Y lanzamos el depurador con [F1]->CMake:Debug
(Figura 27).