¿Cómo almacenar las dependencies de la biblioteca C en el control de versiones?

Procedente de un background de Rails, estoy acostumbrado a poder especificar las dependencies de mi aplicación en un Gemfile que está registrado en mi git repo. Cuando se tira de mi aplicación, el usuario solo necesita ejecutar la bundle install y tienen todas las dependencies necesarias.

En esta respuesta , la comunidad parece estar de acuerdo en que las bibliotecas C no deberían ser controladas en el control de la fuente. Esto tiene sentido (después de todo, las Gemas mismas no están registradas en Rails), pero aún crea un problema. Si escribo algún código e incluyo una nueva dependencia en una biblioteca creada por el usuario, ¿cómo puedo express esta dependencia en el control de origen?

Obviamente, las cosas en el mundo C son un poco diferentes porque no necesitas la fuente en time de ejecución. La forma general en que se hacen las cosas en los sistemas GNU / Linux (y muchos otros * ix) es que algunos pasos de configuration se realizan usando un script o progtwig de configuration. El más común de ellos es el famoso script de configure , generado por GNU autoconf . Las autotools generan una gran cantidad de files de caching y copyn muchas secuencias de commands auxiliares en su tree fuente, así que recuerde configurar .gitignore o se volverá loco.

Una gran cantidad de bibliotecas instalan files de control para pkg-config en $prefix/lib/pkgconfig o $prefix/share/pkgconfig . Estos son leídos por la herramienta pkg-config para verificar la existencia de bibliotecas y get los indicadores correctos del comstackdor y el linker para esa biblioteca. Son text sin formatting, así que eche un vistazo a /usr/lib/pkgconfig para tener una idea de cómo se ven.

En autoconf , un file configure.ac se comstack en configure invocando el procesador de macros m4 (a través de un contenedor llamado autoconf ). Para search una biblioteca que funcione con pkg-config , las cosas son realmente fáciles. Agrega algo como lo siguiente para configure.ac

 # Checks for libraries. PKG_CHECK_MODULES([GLib], [glib-2.0]) 

Esto verificará que pkg-config esté instalado y luego lo use para verificar el package glib-2.0 , imprimiendo el post Checking for GLib... en el path. También establecerá las variables de shell GLib_CFLAGS y GLib_LIBS , y dispondrá que se sustituyan en cualquier file creado por AC_CONFIG_FILES (como su Makefile , desde Makefile.in ). Si no encuentra glib, configure fallará con un error. Eche un vistazo a /usr/share/aclocal/pkg.m4 para encontrar la definición de PKG_CHECK_MODULES , que admite algunas otras opciones. La documentation se encuentra en la página man de pkg-config(1) .

Si su biblioteca dependiente no tiene soporte para pkg-config , a veces el proveedor de la biblioteca proporciona una macro de autoconf . Las versiones anteriores de SDL, por ejemplo, proporcionaban AM_PATH_SDL , pero las versiones nuevas simplemente usan pkg-config .

Si no hay soporte del proveedor, a veces hay soporte de terceros en el file de autoconf . El file de autoconf está disponible como un package en Debian GNU / Linux y MacPorts (y probablemente en muchos otros sistemas), lo que significa que cualquier definición necesaria puede usarse sin copyr files .m4 a mano.

Si ninguno de los anteriores es verdadero, AC_CHECK_HEADER un encabezado usando algo como AC_CHECK_HEADER y verifique la biblioteca usando algo como AC_CHECK_LIB .

la comunidad parece estar de acuerdo en que las bibliotecas C no deben ser controladas en el control de la fuente.

Depende de la biblioteca que uses. Por ejemplo, cuando uso Sqlite, verifico los files sqlite en mi control de versiones y lo construyo con mis files fuente. Esto es fácil ya que sqlite viene con un file fuente y un encabezado. Esto no será práctico si la biblioteca tiene más files.

pero aún crea un problema. Si escribo algún código e incluyo una nueva dependencia en una biblioteca creada por el usuario, ¿cómo puedo express esta dependencia en el control de origen?

En Linux, esto se maneja usando autotools. Utilizando eso, puede especificar los packages para usar y la configuration intentará encontrarlo al build. Si está buscando una solución multiplataforma, CMake es la mejor herramienta. Estas herramientas pueden encontrar los packages instalados en ubicaciones estándar ( /usr/lib & /usr/include ) y también proporcionan una forma de ajustar el parche de búsqueda.