Blag/content/posts/004-meson-libraries.md

4.3 KiB

title date draft weight
El sistema de compilación Meson y las librerias 2022-01-24T20:32:57+01:00 false 4

El sistema de compilación Meson.

¿Por qué usar un sistema de compilación automatizado?

Aunque es ciertamente posible escribir todo un proyecto en un único archivo, conforme la complejidad aumente probablemente queramos dividirlo en varios ficheros, lo cual hará cada vez más compleja nuestra llamada a gcc y ciertamente para cualquier cosa no trival querremos poder usar librerías para facilitar dicho trabajo.

Eso es lo que nos aporta Meson, la posibilidad de escalar nuestro proyecto (o más bien su compilación.) de una forma declarativa e intuitiva.

¿Como comienzo a usar Meson?

La forma más sencilla de usar Meson en nuestro proyecto es crear un fichero meson.build en su raíz, usemos por ejemplo el código final de la anterior sección del tutorial.

Ejecutamos:

mkdir example
cd example
mkdir src include

Y una vez creados los directorios creamos los siguientes ficheros en el proyecto.

src/main.c:

#include <stdio.h>
#include <stdlib.h>

typedef enum {
    COLOR_CYAN = 1,
    COLOR_VERDE = 2,
    COLOR_AMARILLO = 4
} Color;

struct prueba {
    int numero;
    char *hola;
    Color color;
};

struct prueba *
create_struct_prueba_allocated (char *hola) {
    struct prueba *prueba = malloc (sizeof *prueba);

    prueba->numero = 42;
    prueba->hola = hola;
    prueba->color = COLOR_CYAN;

    return prueba;
}

char *
create_array_hola_allocated (size_t *hola_len) {
    char hola[] = { 'h', 'o', 'l', 'a', '\0' };
    size_t hola_to_return_len = sizeof hola;
    char *hola_to_return = malloc (hola_to_return_len * sizeof *hola_to_return);   

    for (size_t i = 0; i < hola_to_return_len; i++) {
        hola_to_return[i] = hola[i];
    }

    if (hola_len) {
        *hola_len = hola_to_return_len;
    }

    return hola_to_return;
}

int
main (int argc, char **argv) {
    size_t hola_len = 0;
    char *hola = create_array_hola_allocated (&hola_len);
    struct prueba *prueba = create_struct_prueba_allocated (hola);
    printf ("%d %d %s\n", prueba->numero, prueba->color, prueba->hola);

    free (hola);
    hola = NULL;
    free (prueba);
    prueba = NULL;
}

meson.build:

project('example', 'c')

inc = include_directories('include')

sources = [
    'src/main.c',
]

executable('example',
    sources,
    include_directories : inc,
    install : true,
)

Ahora simplemente ejecutando:

meson build
meson compile -C build
sudo meson install -C build

Habremos compilado el proyecto y podremos ejecutarlo escribiendo:

example

Librerias

Digamos que queremos hacer una aplicación gráfica, gracias a meson podremos usar gtk de una forma sencilla, veamos como:

En primer lugar buscaremos el nombre de la librería en pkg-config:

pkg-config --list-package-names | grep gtk

En este caso salen varias, pero la que buscamos es gtk4.

meson.build:

project('example', 'c')

inc = include_directories('include')

example_dependencies = [
    dependency('gtk4'),
]

sources = [
    'src/main.c',
]

executable('example',
    sources,
    dependencies : example_dependencies,
    include_directories : inc,
    install : true,
)

Copiemos el ejemplo de la documentación de GTK4:

src/main.c:

#include <gtk/gtk.h>

static void
activate (GtkApplication* app, gpointer user_data) {
    GtkWidget *window;

    window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "Window");
    gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
    gtk_widget_show (window);
}

int
main (int argc, char **argv) {
    GtkApplication *app;
    int status;

    app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return status;
}

Y compilemoslo con:

meson compile -C build
sudo meson install -C build
example

Deberíamos ver una ventana vacía de GTK.

De esta forma podemos incluir cualquiera de las muchas librerias de C para apoyarnos en el desarrollo sin necesidad de estar copiando linker flags y cflags en nuestro código gracias a la integración de Meson y pkg-config.