¿El ejecutable de un programa pequeño y extremadamente simple, como el que se muestra a continuación, que se compila en una versión de Linux, se ejecutará en una versión diferente? ¿O necesitaría ser recompilado?
¿Importa la arquitectura de la máquina en un caso como este?
int main()
{
return (99);
}
glibc
allí, o viceversa. Por supuesto, no es del todo imposible .gcc -m32 -static
). Al hacerlo, cualquier Linux i386 o amd64 podrá ejecutar el ejecutable.Respuestas:
Depende. Algo compilado para IA-32 (Intel de 32 bits) puede ejecutarse en amd64 ya que Linux en Intel conserva la compatibilidad con las aplicaciones de 32 bits (con el software adecuado instalado). Aquí está
code
compilado en el sistema RedHat 7.3 de 32 bits (circa 2002, gcc versión 2.96) y luego el binario copiado y ejecutado en un sistema Centos 7.4 de 64 bits (circa 2017):Ancient RedHat 7.3 a Centos 7.4 (esencialmente RedHat Enterprise Linux 7.4) se mantiene en la misma familia de "distribución", por lo que probablemente tendrá una mejor portabilidad que pasar de una instalación aleatoria "Linux desde cero" de 2002 a otra distribución aleatoria de Linux en 2018 .
Algo compilado para amd64 no se ejecutaría en versiones de Linux de solo 32 bits (el hardware antiguo no conoce el hardware nuevo). Esto también es cierto para el nuevo software compilado en sistemas modernos destinados a ejecutarse en cosas antiguas y antiguas, ya que las bibliotecas e incluso las llamadas al sistema pueden no ser portátiles hacia atrás, por lo que pueden requerir trucos de compilación u obtener un compilador antiguo, etc. compilando en el viejo sistema. (Esta es una buena razón para mantener las máquinas virtuales de cosas antiguas antiguas).
La arquitectura sí importa; amd64 (o IA-32) es muy diferente de ARM o MIPS, por lo que no se esperaría que el binario de uno de ellos se ejecute en otro. En el nivel de ensamblaje, la
main
sección de su código en IA-32 se compila a travésgcc -S code.c
deque un sistema amd64 puede manejar (en un sistema Linux, OpenBSD, por el contrario, en amd64 no admite binarios de 32 bits; la compatibilidad con versiones anteriores con arcos antiguos les da a los atacantes margen de maniobra, por ejemplo, CVE-2014-8866 y amigos). Mientras tanto, en un sistema MIPS big-endian en su
main
lugar se compila para:con el que un procesador Intel no tendrá idea de qué hacer, y tampoco para el ensamblaje Intel en MIPS.
Posiblemente podría usar QEMU o algún otro emulador para ejecutar código extranjero (quizás muy, muy lentamente).
¡Sin embargo! Su código es muy simple, por lo que tendrá menos problemas de portabilidad que cualquier otra cosa; los programas suelen utilizar bibliotecas que han cambiado con el tiempo (glibc, openssl, ...); para aquellos que también pueden necesitar instalar versiones anteriores de varias bibliotecas (RedHat, por ejemplo, generalmente coloca "compat" en algún lugar del nombre del paquete para tales)
o posiblemente preocuparse por los cambios de ABI (Application Binary Interface) para cosas viejas que usan glibc, o cambios más recientes debido a C ++ 11 u otras versiones de C ++. También se podría compilar estática (aumentando enormemente el tamaño binario en el disco) para tratar de evitar problemas de biblioteca, aunque si algún binario antiguo hizo esto depende de si la distribución Linux anterior estaba compilando casi todo lo dinámico (RedHat: sí) o no. Por otro lado, cosas como
patchelf
pueden reiniciar binarios dinámicos (ELF, pero probablemente noa.out
formatear) para usar otras bibliotecas.¡Sin embargo! Poder ejecutar un programa es una cosa, y hacer algo útil con él es otra. Los viejos binarios de Intel de 32 bits pueden tener problemas de seguridad si dependen de una versión de OpenSSL que tiene algún problema de seguridad horrible y no respaldado, o el programa puede no ser capaz de negociar con servidores web modernos (como los modernos los servidores rechazan los protocolos y cifrados antiguos del programa antiguo), o el protocolo SSH versión 1 ya no es compatible, o ...
fuente
for GNU/Linux 2.6.32
(o tal) en la salida defile /usr/bin/ls
.En resumen: si está llevando un binario compilado de un host a otro utilizando la misma arquitectura (o una arquitectura compatible) , puede estar perfectamente bien llevarlo a otra distribución . Sin embargo, a medida que aumenta la complejidad del código, la probabilidad de estar vinculado a una biblioteca que no está instalada; instalado en otra ubicación; o instalado en una versión diferente, aumenta. Tomando por ejemplo su código, para el cual
ldd
informa las siguientes dependencias cuando se compilagcc -o exit-test exit-test.c
en un host Ubuntu Linux (derivado de Debian):Obviamente este binario no se ejecutará si lo pateo a, por ejemplo, una Mac (
./exit-test: cannot execute binary file: Exec format error
). Intentemos moverlo a una caja RHEL:Oh querido. ¿Por qué podría ser esto?
Incluso para este caso de uso, el montacargas falló debido a la falta de bibliotecas compartidas.
Sin embargo, si lo compilo
gcc -static exit-test-static exit-test.c
, portarlo al sistema sin las bibliotecas funciona bien. A expensas, por supuesto, del espacio en disco:Otra solución viable sería instalar las bibliotecas necesarias en el nuevo host.
Al igual que con muchas cosas en el universo U&L, este es un gato con muchas máscaras, dos de las cuales se describen anteriormente.
fuente
amd64
binario y ejecutarlo en otraamd64
distribución, o construir uni386
binario y ejecutarlo en otrai386
distribución.Además de las excelentes respuestas @thrig y @DopeGhoti: los sistemas operativos Unix o similares a Unix, incluido Linux, siempre se diseñaron y alinearon más tradicionalmente para la portabilidad del código fuente que los binarios.
Si no tiene nada específico de hardware o es una fuente simple como en su ejemplo, puede moverlo sin ningún problema entre casi cualquier versión de Linux o arquitectura como código fuente , siempre que los servidores de destino tengan instalados los paquetes de desarrollo C , las bibliotecas necesarias y las bibliotecas de desarrollo correspondientes instaladas.
En la medida en que transfiera código más avanzado de versiones anteriores de Linux distantes en el tiempo, o programas más específicos como módulos de kernel para diferentes versiones de kernel, es posible que deba adaptar y modificar el código fuente para tener en cuenta las bibliotecas / API / ABI en desuso.
fuente
De forma predeterminada , es casi seguro que tenga problemas con las bibliotecas externas. Algunas de las otras respuestas entran en más detalles sobre esos problemas, por lo que no duplicaré su trabajo.
Usted puede , sin embargo, compila muchos programas - incluso los no triviales - para ser portable entre sistemas Linux. La clave es el kit de herramientas llamado Linux Standard Base . El LSB está diseñado para crear solo este tipo de aplicaciones portátiles. Compile una aplicación para LSB v5.0 y se ejecutará en cualquier otro entorno Linux (de la misma arquitectura) que implemente LSB v5.0. Algunas distribuciones de Linux son compatibles con LSB, y otras incluyen kits de herramientas / bibliotecas LSB como un paquete instalable. Si crea su aplicación utilizando las herramientas LSB (como el
lsbcc
contenedor paragcc
) y se vincula a la versión LSB de las bibliotecas, creará una aplicación portátil.fuente
qemu
incluso puede ejecutar programas compilados para una arquitectura diferente (no es de alto rendimiento, pero puede ejecutarlos)apt-get install
un par de paquetes.Tal vez.
Las cosas que tienden a romperlo incluyen.
Si evita usar bibliotecas que cambian rápidamente, evite los cambios de arquitectura y construya sobre la distribución más antigua a la que desea apuntar, tiene una buena oportunidad de hacer que un binario funcione en muchas distribuciones.
fuente
Además de algunas de las cosas mencionadas anteriormente, ha habido algunos cambios en el formato de archivo ejecutable. En su mayor parte, Linux usa ELF, pero las versiones anteriores usaban a.out o COFF.
El comienzo de un wikihole:
https://en.wikipedia.org/wiki/Comparison_of_executable_file_formats
Puede haber una forma de obtener versiones anteriores para ejecutar formatos más nuevos, pero personalmente nunca lo he investigado.
fuente