¿Por qué los makefiles tienen un objetivo de "instalación"?


18

Viniendo del mundo de C y C ++, la mayoría de los sistemas de compilación tienen un installobjetivo, en particular Makefiles (donde GNU lo recomienda, por ejemplo) o CMake . Este objetivo copia los archivos de tiempo de ejecución (ejecutables, bibliotecas, ...) en el sistema operativo (por ejemplo, en C:\Program Files\Windows).

Esto se siente realmente extraño, ya que para mí no es responsabilidad del sistema de compilación instalar programas (que en realidad es responsabilidad del sistema operativo / administrador de paquetes). También significa que el sistema de compilación o el script de compilación deben conocer la organización de los programas instalados, con variables de entorno, variables de registro, enlaces simbólicos, permisos, etc.

En el mejor de los casos, los sistemas de compilación deben tener un releaseobjetivo que genere un programa instalable (por ejemplo .debo .msi), y luego solicite amablemente al sistema operativo que instale ese programa. También permitiría al usuario desinstalar sin tener que escribir make uninstall.

Entonces, mi pregunta: ¿por qué el sistema de compilación generalmente recomienda tener un installobjetivo?


77
Su argumento de que "hacer instalar" no es responsabilidad de un sistema de compilación, pero sí la responsabilidad mucho más compleja y específica de la plataforma de crear un paquete instalable.
pmf

2
De todos modos: a veces desea instalar una aplicación que no es manejada por el administrador de paquetes / SO (porque tiene dependencias que causarían conflictos imposibles de resolver usando el administrador de paquetes, etc.). make installgeneralmente se instala bajo /usr/local(o incluso /opt), que son directorios no manejados por el "sistema operativo principal / sistema de gestión de paquetes". Sin embargo, no tengo idea de si Windows tiene alguna convención similar.
Bakuriu el

11
"Esto se siente realmente hacky". Bueno, ¿qué esperabas del mundo de C / C ++? ;-)
Mason Wheeler

1
Tenga en cuenta que make installno tiene sentido cuando hablamos de compilación cruzada
Hagen von Eitzen

1
@HagenvonEitzen lo hace con DESTDIR.
Nax 'vi-vim-nvim'

Respuestas:


23

Muchos scripts de compilación o Makefiles tienen un objetivo de instalación porque se crearon antes de que existieran los administradores de paquetes, y porque incluso hoy en día muchos sistemas no tienen administradores de paquetes. Además, hay sistemas en los que en make installrealidad es la forma preferida de administrar paquetes.


Tengo curiosidad acerca de los sistemas donde make installse prefiere. Aparte de eso, me refería al administrador de programas cuando dije que los archivos MAKE deberían crear paquetes instalables. ¿Creo que casi todos los sistemas operativos vienen con una forma de administrar los programas instalados? Por ejemplo, Windows no tiene un administrador de paquetes (aparte de la tienda) pero aún tiene una forma de administrar los programas instalados (a través de .msipaquetes, por ejemplo)
Synxis

2
@Synxis BSD, Linux, Unix todos usan archivos MAKE. Si se prefiere usarlos para la instalación, no lo sé, pero a menudo tienes esa capacidad de usar make install.
Rob

1
En Debian, al menos, se prefiere el uso de checkinstallmás make installde dos razones: "Se puede quitar fácilmente el paquete con un paso." y "Puede instalar el paquete resultante en varias máquinas". - como checkinstall construye un .deb y lo instala, usa el administrador de paquetes ...
Aaron Hall

1
@Synxis: hay varias distribuciones de Linux (a menudo llamadas distribuciones de origen) en las que el administrador de paquetes instala programas descargando un archivo tar, descomprimiéndolo y luego ejecutándolomake install
slebetman

1
@AaronHall Corrígeme si me equivoco, pero tengo la impresión de que una checkinstallinvocación realmente usará make install y monitoreará sus acciones para la construcción de paquetes.
cmaster - reinstalar a monica el

5

Es makefileposible que A no tenga un installdestino y, lo que es más importante, puede tener programas que ni siquiera se supone que sean instalables (por ejemplo, porque deberían ejecutarse desde su directorio de compilación o porque pueden ejecutarse instalados en cualquier lugar). El installobjetivo es solo una convención para los usuales makefile.

Sin embargo, muchos programas requieren recursos externos para ejecutarse (por ejemplo: fuentes, bases de datos, archivos de configuración, etc.). Y su ejecutable a menudo formula algunas hipótesis sobre estos recursos. Por ejemplo, su bashshell generalmente leería algún archivo de inicialización, /etc/bash.bashrcetc. Estos recursos generalmente se encuentran en el sistema de archivos (consulte hier (7) para conocer las convenciones sobre la jerarquía de archivos) y la ruta de archivo predeterminada está integrada en su ejecutable.

Intente utilizar cadenas (1) en la mayoría de los ejecutables de su sistema. Descubrirá qué rutas de archivo conoce.

Por cierto, para muchos programas GNU que usan autoconf, podría ejecutarse make install DESTDIR=/tmp/destdir/sin ser root. Luego /tmp/destdir/se llena con los archivos que luego deben empaquetarse.

FWIW, tiendo a creer que mi programa bismon (licencia GPLv3 +) (descrito en mi informe bismon-chariot-doc.pdf ) no se puede "instalar"; No estoy seguro de poder probar eso, y no puedo imaginar cómo podría hacer que ese programa sea instalable.


2
DESTDIR u otros prefijos se olvidan con demasiada frecuencia. Tan pronto como intervienen recursos externos como bibliotecas dinámicas, no es posible construir el software sin saber dónde se instalará . También es ideal para instalar en ubicaciones no estándar, por ejemplo, /opto en $HOME. La única forma de evitar diferentes prefijos es usar contenedores, pero esa es, por supuesto, una solución específica de Linux.
amon

2
He visto más de un paquete que si intentara DESTDIR = / tmp / destdir no funcionaría más tarde cuando se instalara en el lugar normal porque DESTDIR se usó en la generación de rutas.
Joshua

@amon: No estoy seguro de caracterizar los contenedores como específicos de Linux. Linux puede ser una plataforma objetivo común para la contenedorización, pero existe algún tipo de tecnología de contenedor en la mayoría de los sistemas operativos modernos.
Kevin

1
@Joshua No debería, DESTDIR solo debería ser relevante durante el paso de instalación. Debería poder hacer: ./configure --prefix="/opt/foo" && make && DESTDIR=/tmp/foo make install y poder reubicar el paquete /opt/foosin ningún problema.
Nax 'vi-vim-nvim'

3

Hay varias razones que me vienen a la mente.

  • Muchos programas de creación de paquetes, como el sistema de compilación de Debian y el IIRC rpm también, ya esperan que el script de construcción "instale" el programa en algún subdirectorio especial. Por lo tanto, es impulsado por la compatibilidad con versiones anteriores en ambas direcciones.
  • Un usuario puede querer instalar el software en un espacio local, como en el $HOMEdirectorio. No todos los administradores de paquetes lo admiten.
  • Todavía puede haber entornos que no tienen paquetes.

Reescribí la pregunta un poco, me refería al administrador de programas cuando dije que los archivos MAKE deberían crear paquetes instalables.
Synxis

1

Una razón no mencionada es que hay muchas veces cuando no está utilizando la versión actual del software o una versión modificada del software. Intentar crear un paquete personalizado no solo es más trabajo, sino que puede entrar en conflicto con los paquetes actualmente creados y distribuidos. En el código fuente abierto, esto sucede mucho, especialmente si se introducen cambios importantes en las versiones futuras que está utilizando.

Supongamos que está utilizando el proyecto de código abierto FOO que se encuentra actualmente en la versión 2.0.1 y está utilizando la versión 1.3.0. No desea usar nada anterior porque la versión 2.0.0 es incompatible con lo que está haciendo actualmente, pero hay una única corrección de errores en 2.0.1 que necesita desesperadamente. Tener la make installopción le permite instalar el software 1.3.0 modificado sin tener que preocuparse por crear un paquete e instalarlo en su sistema.


1

Las distribuciones de Linux generalmente separan el mantenimiento del programa del mantenimiento del paquete. Un sistema de compilación que integra la generación de paquetes obligaría a los encargados del mantenimiento del programa a realizar también el mantenimiento de paquetes.

Esta suele ser una mala idea. Las distribuciones tienen mucha infraestructura para verificar la consistencia interna, proporcionar binarios para múltiples plataformas de destino, realizar pequeñas modificaciones para integrarse mejor con el resto del sistema y proporcionar una experiencia consistente para los usuarios que reportan errores.

Para generar paquetes directamente desde un sistema de compilación, deberá integrar o omitir toda esta infraestructura. Integrarlo sería mucho trabajo para un beneficio cuestionable, y evitarlo daría una peor experiencia al usuario.

Este es uno de los problemas "principales de la cadena alimentaria" que son típicos en los sistemas multipartidistas. Si tiene múltiples sistemas complejos, debe existir una jerarquía clara de qué sistema es responsable de coordinar todos los demás.

En el caso de la gestión de instalación de software, el administrador de paquetes es este componente, y ejecutará el sistema de compilación del paquete, luego tomará la salida a través de una interfaz conveniente ("archivos en un directorio después de un paso de instalación"), generará un paquete y preparará para subir a un repositorio.

El administrador de paquetes se encuentra en el medio entre el sistema de compilación y el repositorio aquí, y está en la mejor posición para integrarse bien con ambos.

Usted puede haber notado que hay sólo unos pocos de los JavaScript paquetes disponibles a través npmtambién disponible a través de apt- esto se debe principalmente a las personas de JavaScript decidieron que npmy el repositorio asociado iba a ser la parte superior de la cadena alimentaria, lo que hacía casi imposible envíe estos paquetes como paquetes Debian.

Con mi sombrero de desarrollador de Debian encendido: si libera software de código abierto, deje el paquete a los encargados de la distribución. Le ahorra a usted y a nosotros mucho trabajo.


Usted ha dicho nada acerca de por qué hay un objetivo de instalar, y me parece que la mayoría de lo que ha escrito se aplicaría a él también ...
curiousdannii

1
@curiousdannii, debe haber alguna interfaz entre el sistema de compilación y el administrador de paquetes, y esta es la más simple, por lo que ganó.
Simon Richter

1

Bueno, los desarrolladores de aplicaciones son los que saben a dónde debe ir cada archivo. Podrían dejar eso en la documentación y hacer que los encargados del paquete lo lean y creen un script para cada paquete. Quizás los encargados del paquete interpreten mal la documentación y tengan que depurar el script hasta que funcione. Esto es ineficiente. Es mejor que el desarrollador de la aplicación escriba un script para instalar correctamente la aplicación que ha escrito.

Podría escribir una secuencia de comandos de instalación con un nombre arbitrario o tal vez hacerla parte del procedimiento de otra secuencia de comandos. Sin embargo, al tener un comando de instalación estándar make install(una convención anterior a los administradores de paquetes), es muy fácil crear paquetes. Si observa la plantilla PKGBUILD para hacer paquetes de Archlinux , puede ver que la función que realmente empaqueta simplemente hace a make DESTDIR="$pkgdir/" install. Esto probablemente funciona para la mayoría de los paquetes y probablemente más con una pequeña modificación. Gracias a que make(y las herramientas automáticas) son estándar, el empaquetado es realmente fácil.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.