pkg-config

pkg-config es una herramienta para sistemas UNIX como GNU/Linux o *BSD, que facilita la obtención de los parámetros que son necesarios proporcionarles a GCC para que el software que depende de bibliotecas dinámicas que hayamos instalado en nuestro ordenador pueda saber contra qué debe enlazarse.

Una de las grandes ventajas que nos ha traído Internet es el acceso a un vasto repositorio de bibliotecas que podemos utilizar para acelerar nuestro desarrollo en C, sin tener que programar todo desde cero. Por ejemplo, si queremos crear una aplicación gráfica, no necesitamos construir nuestro propio sistema de ventanas; podemos apoyarnos en bibliotecas como GTK o QT para disponer de ventanas, botones y otros elementos gráficos listos para usar.

Estas bibliotecas suelen estar disponibles a través de los gestores de paquetes de nuestro sistema operativo. Sin embargo, instalar solo la biblioteca dinámica no es suficiente para desarrollar nuestros propios programas. Necesitamos también los archivos de cabecera y otros recursos de desarrollo, que normalmente vienen en paquetes adicionales con sufijos como -devel o -dev. Estos paquetes incluyen, entre otras cosas, archivos de cabecera y archivos de configuración para herramientas como pkg-config.

Aquí es donde pkg-config se vuelve fundamental. El problema con las dependencias en C es que los archivos de cabecera y las bibliotecas pueden estar instalados en diferentes ubicaciones, y algunas dependencias pueden requerir otras, lo que complica la tarea de indicar al compilador dónde buscar todo. pkg-config actúa como una base de datos que conoce la ubicación de estos archivos y las opciones necesarias para compilar y enlazar correctamente.

Cuando instalamos la versión de desarrollo de una biblioteca, esta suele incluir un archivo .pc que describe dónde están sus archivos de cabecera y bibliotecas, y qué flags deben usarse. Así, con pkg-config podemos pedir directamente las opciones que necesitamos para compilar nuestro programa sin preocuparnos por las rutas exactas.

Por ejemplo, si queremos usar GTK 3.0, podemos listar las dependencias instaladas con:

pkg-config --list-all

Y luego obtener las opciones para el compilador con:

pkg-config --cflags gtk+-3.0

Esto nos devolverá una serie de flags -I que indican dónde están los archivos de cabecera, como:

-I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 ...

Estas rutas pueden ser muchas y complejas, ya que GTK depende de varias otras bibliotecas. Intentar ponerlas a mano sería tedioso y propenso a errores.

Para el enlazador, usamos:

pkg-config --libs gtk+-3.0

Que nos devuelve las opciones -l necesarias para enlazar con las bibliotecas dinámicas, por ejemplo:

-lgtk-3 -lgdk-3 -lpango-1.0 -lcairo ...

Podemos combinar ambas opciones para obtener todo de una vez:

pkg-config --cflags --libs gtk+-3.0

Y para compilar nuestro programa window.c que utiliza GTK, podemos usar la sustitución de comandos en Bash para pasar directamente estas opciones a gcc:

gcc -o window window.c $(pkg-config --cflags --libs gtk+-3.0)

Esto hace que el compilador reciba todas las rutas y bibliotecas necesarias sin que tengamos que escribirlas manualmente.

Por otro lado, algunas bibliotecas como SDL no usan pkg-config, sino que proporcionan su propia herramienta similar llamada sdl2-config. Su uso es muy parecido: con sdl2-config --cflags obtenemos las rutas de los archivos de cabecera, y con sdl2-config --libs las opciones para enlazar.

En definitiva, estas herramientas nos permiten gestionar las dependencias de manera sencilla y evitar complicaciones al compilar y enlazar, lo que acelera nuestro desarrollo y nos permite centrarnos en escribir código en lugar de en configurar rutas y flags manualmente. Para profundizar más, siempre podemos consultar el manual con:

man pkg-config

y descubrir todas las opciones que nos ofrece esta útil herramienta.

Lista de reproducción
  1. 1
    Instalar CodeBlocks
    15 minutos
  2. 2
    Funciones y hola mundo
    17 minutos
  3. 3
    Variables y tipos de datos
    17 minutos
  4. 4
    Condicionales y operadores lógicos
    16 minutos
  5. 5
    Bucles
    11 minutos
  6. 6
    Punteros
    12 minutos
  7. 7
    Arrays
    14 minutos
  8. 8
    Estructuras
    12 minutos
  9. 9
    Otras construcciones de C
    9 minutos
  10. 10
    Memoria dinámica
    8 minutos
  11. 11
    El preprocesador (parte 1)
    10 minutos
  12. 12
    El preprocesador (parte 2)
    9 minutos
  13. 13
    Archivos de cabecera y múltiples .c (parte 1)
    8 minutos
  14. 14
    Archivos de cabecera y múltiples .c (parte 2)
    9 minutos
  15. 15
    C desde la línea de comandos (parte 1)
    8 minutos
  16. 16
    C desde la línea de comandos (parte 2)
    9 minutos
  17. 17
    Break y continue
    10 minutos
  18. 18
    Goto
    13 minutos
  19. 19
    Manipulación de bits
    15 minutos
  20. 20
    Máscaras de bit
    19 minutos
  21. 21
    Archivos (1): fopen y fclose
    13 minutos
  22. 22
    Archivos (2): leer con fgetc
    9 minutos
  23. 23
    Archivos (3): fseek y ftell
    11 minutos
  24. 24
    Archivos (4): leer con fgets
    9 minutos
  25. 25
    Archivos (5): fputc y fputs
    7 minutos
  26. 26
    Archivos (6): volcar en archivos con fwrite
    10 minutos
  27. 27
    Archivos (7): fread, fwrite y los arrays
    10 minutos
  28. 28
    Archivos (8): entrada estándar y salida estándar
    9 minutos
  29. 29
    Archivos (9): buffers
    14 minutos
  30. 30
    Archivos (y 10): otras funciones útiles con archivos
    5 minutos
  31. 31
    printf (1)
    18 minutos
  32. 32
    printf (parte 2)
    12 minutos
  33. 33
    scanf (parte 1)
    17 minutos
  34. 34
    scanf (parte 2)
    17 minutos
  35. 35
    fprintf, sprintf y snprintf
    8 minutos
  36. 36
    Tipos de datos opacos
    13 minutos
  37. 37
    Bibliotecas estáticas
    13 minutos
  38. 38
    Bibliotecas dinámicas
    15 minutos
  39. 39
    Más flags: i mayúscula (include), wall, werror, pedantic...
    12 minutos
  40. 40
    pkg-config
    12 minutos
  41. 41
    Make
    17 minutos
  42. 42
    GDB
    21 minutos
  43. 43
    Variables globales
    6 minutos
  44. 44
    extern
    9 minutos
  45. 45
    Funciones variádicas
    12 minutos
  46. 46
    El optimizador de GCC y la opción -O
    12 minutos
  47. 47
    Volatile
    6 minutos