SDK Multiplataforma en C logo

SDK Multiplataforma en C

Generar binarios NAppGUI

❮ Anterior
Siguiente ❯

En Inicio rápido ya vimos como descargar, compilar y ejecutar los ejemplos a partir del código fuente. En este capítulo y el siguiente profundizaremos en el proceso de compilación y en la portabilidad entre plataformas. Todo el build system de NAppGUI se centra en un único script src/CMakeLists.txt (Listado 1). En él se definirá una solución con varios proyectos relacionados, así como sus dependencias.

Listado 1: src/CMakeLists.txt
 
cmake_minimum_required(VERSION 2.8.12)
project(NAppGUI)

# NAppGUI Build Scripts
get_filename_component(ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR} PATH)
include(${ROOT_PATH}/prj/CMakeNAppGUI.cmake)

# Static libraries
staticLib("sewer" "sewer" "" NRC_NONE)
staticLib("osbs" "osbs" "sewer" NRC_NONE)
staticLib("core" "core" "osbs" NRC_NONE)
staticLib("geom2d" "geom2d" "core" NRC_NONE)
staticLib("draw2d" "draw2d" "geom2d" NRC_NONE)
staticLib("osgui" "osgui" "draw2d" NRC_NONE)
staticLib("gui" "gui" "draw2d" NRC_EMBEDDED)
staticLib("inet" "inet" "core" NRC_NONE)
staticLib("osapp" "osapp" "osgui;gui" NRC_NONE)

# Executables
desktopApp("Fractals" "demo/fractals" "osapp" NRC_EMBEDDED)
desktopApp("HelloWorld" "demo/hello" "osapp" NRC_EMBEDDED)
desktopApp("HelloCpp" "demo/hellocpp" "osapp" NRC_EMBEDDED)
...

generateSolution()

1. Generar librerías estáticas

Por defecto, el CMakeLists.txt creará la versión estática de las librerías de NAppGUI. Si quieres utilizar NAppGUI de forma externa en tus proyectos, tan solo tienes que seguir los siguientes pasos:

 
git clone --depth 1 https://github.com/frang75/nappgui_src.git
cd nappgui_src

// Windows
cmake -S ./src -B ./build
cmake --build ./build --config Debug
cmake --install ./build --prefix ./install --config Debug

// macOS
cmake -G Xcode -S ./src -B ./build
cmake --build ./build --config Debug
cmake --install ./build --prefix ./install --config Debug

// Linux
cmake -S ./src -B ./build -DCMAKE_BUILD_CONFIG=Debug
cmake --build ./build -j 4
cmake --install ./build --prefix ./install --config Debug

En la carpeta install tendrás los binarios y las cabeceras:

 
install
  |
  +-- inc
  |    |
  |    +-- core
  |   ...   |
  |         +-- array.h
  |        ...
  +-- lib
  |    |
  |    +-- v143_x64
  |         |
  |         +-- Debug
  |              |
  |              +-- core.lib
  |             ...
  +-- bin
       |
       +-- v143_x64
            |
            +-- Debug
                 |
                 +-- Bode.exe
                ...
  • En /install/inc encontrarás los ficheros de cabecera de cada librería.
  • En /install/lib encontrarás las librerías estáticas (.lib, .a).
  • En /install/bin encontrarás las ejecutables de ejemplo.
  • v143_x64 identifica al compilador y arquitectura. En Compiladores e IDEs tienes más información acerca de compiladores, plataformas y arquitecturas soportadas.
  • Debug es una de las tres configuraciones posibles: Debug, Release, ReleaseWithAssert. Configuraciones
Si no quieres compilar las aplicaciones de ejemplo, elimina las líneas desktopApp del script.

2. Generar librerías dinámicas

Para generar las versiones de enlace dinámico (.dll, .so, .dylib) de NAppGUI, edita CMakeLists.txt, sustituyendo los comandos staticLib por dynamicLib. Una vez hecho esto, compila e instala utilizando cmake de la misma forma que en el caso estático.

 
cmake_minimum_required(VERSION 2.8.12)
project(NAppGUI)

# NAppGUI Build Scripts
get_filename_component(ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR} PATH)
include(${ROOT_PATH}/prj/CMakeNAppGUI.cmake)

# Dynamic libraries
dynamicLib("sewer" "sewer" "" NRC_NONE)
dynamicLib("osbs" "osbs" "sewer" NRC_NONE)
dynamicLib("core" "core" "osbs" NRC_NONE)
dynamicLib("geom2d" "geom2d" "core" NRC_NONE)
dynamicLib("draw2d" "draw2d" "geom2d" NRC_NONE)
dynamicLib("osgui" "osgui" "draw2d" NRC_NONE)
dynamicLib("gui" "gui" "draw2d" NRC_EMBEDDED)
dynamicLib("inet" "inet" "core" NRC_NONE)
dynamicLib("osapp" "osapp" "osgui;gui" NRC_NONE)

# Executables
desktopApp("Fractals" "demo/fractals" "osapp" NRC_EMBEDDED)
desktopApp("HelloWorld" "demo/hello" "osapp" NRC_EMBEDDED)
desktopApp("HelloCpp" "demo/hellocpp" "osapp" NRC_EMBEDDED)
...

generateSolution()

Tras la instalación:

  • En /install/inc encontrarás los ficheros de cabecera de cada librería.
  • En /install/lib se guardarán las librerías de importación de símbolos de las .dll (.lib), solo en Windows.
  • En /install/bin se guardarán las librerías dinámicas .dll, .so, .dylib junto con los ejecutables de ejemplo.
  •  
    
    11-Dec-22  19:42    <DIR>          .
    11-Dec-22  19:42    <DIR>          ..
    11-Dec-22  19:42    <DIR>          res
    11-Dec-22  19:42           217,088 osgui.dll
    11-Dec-22  19:42            93,184 casino.dll
    11-Dec-22  19:41           119,808 osbs.dll
    11-Dec-22  19:42           241,152 core.dll
    11-Dec-22  19:42           100,864 osapp.dll
    11-Dec-22  19:42           118,784 inet.dll
    11-Dec-22  19:42           222,208 draw2d.dll
    11-Dec-22  19:42           250,880 gui.dll
    11-Dec-22  19:42           329,728 geom2d.dll
    11-Dec-22  19:41           229,376 sewer.dll
    11-Dec-22  19:42           462,336 DrawImg.exe
    11-Dec-22  19:42           188,416 DrawHello.exe
    11-Dec-22  19:42           129,024 DrawBig.exe
    11-Dec-22  19:42           483,840 GuiHello.exe
    11-Dec-22  19:42           138,240 HelloCpp.exe
    11-Dec-22  19:42           123,904 HelloWorld.exe
    11-Dec-22  19:42           132,096 Die.exe
    11-Dec-22  19:42           124,928 Dice.exe
    11-Dec-22  19:42           152,576 Col2dHello.exe
    11-Dec-22  19:42           126,464 Bricks.exe
    11-Dec-22  19:42           153,088 Products.exe
    11-Dec-22  19:42           159,744 Bode.exe
    11-Dec-22  19:42           127,488 Fractals.exe
    11-Dec-22  19:42           128,000 UrlImg.exe
    

Si vas a utilizar estas librerías en proyectos de terceros, no generados mediante CMakeLists.txt, deberás previamente definir estas macros con el fin de que la importación de símbolos se realice correctamente.

 
#define OSAPP_IMPORT
#define OSGUI_IMPORT
#define DRAW2D_IMPORT
#define GEOM2D_IMPORT
#define CORE_IMPORT
#define OSBS_IMPORT
#define SEWER_IMPORT
#define GUI_IMPORT
#define INET_IMPORT

3. Más sobre CMakeLists.txt

NAppGUI simplifica el uso de CMake, proporcionando funciones de alto nivel, ubicadas en la carpeta /prj de la distribución. El CMakeLists.txt define una solución donde coexisten diferentes librerías y ejecutables relacionados a través de dependencias. Tras ser procesado por CMake este script creará, en la carpeta /build, los proyectos de compilación de cada plataforma (VisualStudio, Xcode, Make). Dentro del script trabajaremos con cuatro comandos esencialmente:

En el ejemplo siguiente definimos una solución que contiene una librería dinámica y dos aplicaciones, una de escritorio y otra por línea de comandos. Ambas hacen uso (dependen) de dicha librería dinámica y de NAppGUI (librerías estáticas) para la interfaz gráfica y el soporte multiplataforma.

CMakeLists.txt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#------------------------------------------------------------------------------
# CMake build script
# Copyright (C) 2023 - PhysicsLab
# See LICENSE.txt for details
#------------------------------------------------------------------------------
cmake_minimum_required(VERSION 2.8.12)
project(PhysicsSimulator)

# NAppGUI Build Scripts
get_filename_component(ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR} PATH)
include(${ROOT_PATH}/prj/CMakeNAppGUI.cmake)

# NAppGUI static libraries
staticLib("sewer" "sewer" "" NRC_NONE)
staticLib("osbs" "osbs" "sewer" NRC_NONE)
staticLib("core" "core" "osbs" NRC_NONE)
staticLib("geom2d" "geom2d" "core" NRC_NONE)
staticLib("draw2d" "draw2d" "geom2d" NRC_NONE)
staticLib("osgui" "osgui" "draw2d" NRC_NONE)
staticLib("gui" "gui" "draw2d" NRC_EMBEDDED)
staticLib("osapp" "osapp" "osgui;gui" NRC_NONE)
staticLib("inet" "inet" "core" NRC_NONE)

# User dynamic library
dynamicLib("physics" "physics" "geom2d" NRC_NONE)

# Exes
desktopApp("PhysicsSim" "phsim" "osapp;physics" NRC_EMBEDDED)
commandApp("PhysicsTest" "phtest" "core;physics" NRC_NONE)

generateSolution()
  • Línea 6: Versión mínima requerida de CMake.
  • Línea 7: Nombre del proyecto o solución.
  • Líneas 10-11: Incluye los scripts CMake de NAppGUI, ubicados en /prj.
  • Líneas 14-22: Generan las librerías estáticas que componen NAppGUI.
  • Línea 25: Genera una librería dinámica con funciones propias del usuario.
  • Línea 28: Genera una aplicación de escritorio.
  • Línea 29: Genera una aplicación por línea de comandos.
  • Línea 31: Procesa la solución. Este comando deberá ser el último del script.

4. ¿Por qué nueve librerías independientes?

NAppGUI proporciona un soporte completo multiplataforma a varios niveles. No es necesario crear una aplicación con interfaz gráfica para aprovechar las ventajas que nos ofrece en cuanto a portabilidad del código. Podemos desarrollar potentes aplicaciones back-end por línea de comandos orientadas a servidores. En función del nivel de asistencia que requiera cada proyecto, podemos optar por enlazar estas librerías. Más información en NAppGUI API.

  • Sewer: Tipos básicos, aserciones, Unicode, funciones matemáticas, wrapper sobre la librería estándar de C.
  • Osbs: Servicios del sistema operativo. API portable sobre archivos, directorios, procesos, hebras, memoria, etc.
  • Core: Utilidades no gráficas de uso común. Auditor de memoria, estructuras de datos, strings, streams, expresiones regulares, recursos, etc.
  • Geom2D: Geometría 2D. Transformaciones, vectores, polígonos, colisiones, etc.
  • Draw2D: API portable de dibujo vectorial, imágenes y fuentes. Se puede utilizar en aplicaciones por línea de comandos, ya que es posible dibujar en memoria y exportar a un archivo o transmitir por la red.
  • osgui: Acceso de bajo a nivel a los elementos de interfaz de usuario (widgets o controles) de cada sistema operativo. No está documentada y no se recomienda utilizarla directamente.
  • Gui: Compositor de interfaces de usuario. Utiliza osgui para renderizar.
  • OSApp: Implementa el ciclo de mensajes de una aplicación de escritorio. Utilízala únicamente para crear aplicaciones desde cero. Si solo necesitas crear ventanas en una aplicación ya existente, gui será la dependencia de más alto nivel.
  • INet: Utilízala si tu aplicación va a utilizar protocolos de Internet como HTTP. Válida para aplicaciones por línea de comandos o escritorio.
❮ Anterior
Siguiente ❯