Compilar desde fuente no es una práctica obsoleta, pero tampoco es algo que debas hacer por defecto. El ecosistema de paquetes de Debian es uno de los más exhaustivos que existen, y la mayoría de las veces hay una razón legítima para que algo no esté empaquetado o esté en una versión anterior. Antes de ejecutar ./configure, tienes que entender qué estás sacrificando y cómo minimizar el daño cuando la compilación es inevitable.
Cuándo tiene sentido y cuándo no
Los casos reales en 2025 se reducen a tres: el software directamente no existe en los repositorios (un daemon experimental, una herramienta interna, algo muy nuevo), necesitas una versión específica con un parche o feature que el paquete oficial no tiene, o estás contribuyendo al proyecto y necesitas el ciclo build-test-patch. Fuera de esos tres casos, compilar es añadir deuda técnica sin justificación.
El problema central de sudo make install es epistemológico: dpkg no sabe que ese software existe. Los binarios, las bibliotecas y los archivos de configuración se distribuyen por /usr/local/ (y a veces directamente por /usr/) sin ningún registro en la base de datos de paquetes. No puedes desinstalar limpiamente, no puedes auditar qué archivos instaló, y si más adelante instalas un paquete que incluye un archivo del mismo nombre, obtienes un conflicto silencioso o una sobreescritura que puede romper cualquiera de los dos. En producción eso es inaceptable.
checkinstall resuelve exactamente ese problema. En lugar de ejecutar make install directamente, intercepta la instalación, registra cada archivo que el proceso hubiera escrito, y genera un paquete .deb real que puedes instalar con dpkg, desinstalar con dpkg -r, y distribuir a otras máquinas con la misma arquitectura. No es un paquete con calidad de distribución —no tiene dependencias correctamente declaradas, no pasa por el ciclo de QA de Debian— pero sí te devuelve control sobre el sistema de archivos.
Si algo sale mal después de la instalación, dpkg -r nombre-del-paquete limpia todo lo que checkinstall registró. Sin él, estarías haciendo make uninstall si tienes suerte, o borrando archivos a mano si no tienes el Makefile original a mano.
Ejemplo completo: compilar e instalar htop desde fuente con checkinstall
El ejemplo usa htop porque su código fuente está disponible, la compilación tarda segundos, y cualquiera puede verificar el resultado comparándolo con el paquete oficial. En producción usarías el paquete, pero para entender el proceso es un caso ideal.
# Instalamos las herramientas de compilación y las dependencias de htop.
# build-essential trae gcc, g++, make y los headers del kernel de glibc.
# Los demás son dependencias propias de htop.
sudo apt install build-essential checkinstall \
libncursesw5-dev libhwloc-dev libnl-3-dev libnl-genl-3-dev
# Descargamos el tarball desde la fuente oficial y lo verificamos
wget https://github.com/htop-dev/htop/releases/download/3.3.0/htop-3.3.0.tar.xz
wget https://github.com/htop-dev/htop/releases/download/3.3.0/htop-3.3.0.tar.xz.sha256
sha256sum --check htop-3.3.0.tar.xz.sha256
tar xf htop-3.3.0.tar.xz
cd htop-3.3.0
# autoreconf genera ./configure a partir de configure.ac.
# Necesario cuando el tarball no incluye el script configure precompilado.
autoreconf -fi
# ./configure examina el entorno: compilador disponible, versiones de
# bibliotecas, cabeceras presentes, y genera el Makefile adaptado a
# este sistema concreto. --prefix controla dónde irá todo.
# /usr/local es el estándar para software fuera del gestor de paquetes.
./configure --prefix=/usr/local
# -j$(nproc) paraleliza la compilación usando todos los núcleos
# disponibles. Sin esta opción, make compila en un solo hilo.
make -j$(nproc)
# Aquí es donde checkinstall reemplaza a "sudo make install".
# Le pasamos metadatos para que el .deb generado sea identificable.
# --pkgname y --pkgversion son los mínimos imprescindibles.
# --nodoc evita empaquetar la documentación, que rara vez necesitas.
sudo checkinstall \
--pkgname=htop-custom \
--pkgversion=3.3.0 \
--pkgrelease=1 \
--pkglicense=GPL \
--pakdir=/tmp \
--nodoc \
--default \
make install
# Verificamos que dpkg conoce la instalación
dpkg -l htop-custom
# El .deb generado está en /tmp para distribuirlo si hace falta
ls -lh /tmp/htop-custom_3.3.0-1_amd64.deb
# Si en algún momento quieres desinstalar limpiamente:
# sudo dpkg -r htop-custom
Qué está pasando en cada paso
build-essential es un meta-paquete: no contiene código propio, solo declara dependencias hacia gcc, g++, make, libc6-dev y los headers de glibc. Instalarlo es el mínimo para compilar cualquier proyecto en C o C++ en Debian. Sin los headers de glibc (linux/types.h, sys/socket.h, etc.), ./configure fallará en la fase de detección de capacidades del sistema.
autoreconf -fi solo es necesario cuando trabajas directamente desde el repositorio git del proyecto o cuando el mantenedor no incluye el script configure en el tarball. El -f fuerza la regeneración aunque los archivos intermedios existan, y el -i copia los archivos auxiliares de automake que puedan faltar. Muchos tarballs de release incluyen configure ya generado y puedes saltarte este paso.
El script ./configure no compila nada: su trabajo es inspeccionar el sistema —qué compilador hay, qué versiones de bibliotecas están instaladas, qué llamadas al sistema están disponibles— y producir un Makefile configurado para ese entorno específico. Si falta una dependencia, falla aquí con un mensaje claro antes de desperdiciar tiempo compilando. El parámetro --prefix=/usr/local es importante: le dice al build system que todos los archivos irán bajo ese árbol, separando el software compilado a mano del gestionado por apt.
make -j$(nproc) lee el Makefile generado y coordina la compilación. El -j$(nproc) es probablemente la optimización de compilación más simple que existe: en una máquina con 8 núcleos, un proyecto mediano pasa de tardar 4 minutos a tardar 40 segundos. El único riesgo es con Makefiles mal escritos que no declaran dependencias entre targets correctamente, cosa rara en proyectos maduros.
checkinstall lanza make install internamente, pero con strace o LD_PRELOAD interceptando las llamadas al sistema de escritura de archivos para registrar exactamente qué se escribe y dónde. Con esa lista construye el .deb. El flag --default acepta todos los valores que le pasamos por línea de comandos sin abrir el menú interactivo, útil para automatización. El .deb que genera en /tmp es un artefacto real: puedes copiarlo a otra máquina Debian con la misma arquitectura e instalarlo con dpkg -i.
Una advertencia sobre ese .deb: checkinstall no resuelve dependencias. Si el binario que compilaste enlaza dinámicamente contra libncursesw6, el paquete generado no lo declarará como dependencia. Funciona en la máquina donde compilaste porque ya tienes las bibliotecas instaladas, pero puede fallar en otra máquina limpia. Para distribuir software serio hay que escribir un debian/control real y usar dpkg-buildpackage. checkinstall es para gestionar tu propio sistema, no para distribuir paquetes.
La regla en producción es simple: si hay un paquete en los repositorios de Debian que satisface tus requisitos, úsalo. Cuando compilas desde fuente porque tienes una razón legítima, documenta en el registro de cambios del sistema —o en tu herramienta de gestión de configuración— exactamente qué compilaste, desde qué fuente, con qué flags de ./configure, y por qué. Tres meses después, cuando actualices el sistema o tengas que replicar el servidor, ese contexto vale más que el propio binario.
N° 58