diff --git a/content/posts/004-meson-libraries.md b/content/posts/004-meson-libraries.md new file mode 100644 index 0000000..e59c086 --- /dev/null +++ b/content/posts/004-meson-libraries.md @@ -0,0 +1,211 @@ +--- +title: "El sistema de compilación Meson y las librerias" +date: 2022-01-24T20:32:57+01:00 +draft: false +weight: 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: + +```shell +mkdir example +cd example +mkdir src include +``` + +Y una vez creados los directorios creamos los siguientes ficheros en +el proyecto. + +`src/main.c`: + +```c +#include +#include + +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: + +```shell +meson build +meson compile -C build +sudo meson install -C build +``` + +Habremos compilado el proyecto y podremos ejecutarlo escribiendo: + +```shell +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: + +```shell +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`: + +```c +#include + +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: + +```shell +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.