¿Funcionará mi binario de Linux en todas las distribuciones?

24

Encontré un buen IDE de reemplazo para Delphi llamado Lazarus. Pero no tengo una pregunta para los programadores.

¿ Funcionará el binario de Linux estáticamente vinculado en todas las distribuciones de Linux? Es decir, no importa en qué distribución de Linux lo construí y funcionará en Debian / ArchLinux / Ubuntu / OpenSUSE / ... ¿lo que sea?

Como resultado de mis hallazgos, ¿realmente solo importa 32 bits frente a 64 bits? Quiero estar seguro antes de publicar.

LinuxSecurityFreak
fuente
Vagamente relacionada: Sistema Linux llama en C en OS X .
G-Man dice 'reinstalar a Monica' el
¿Puede ser más específico sobre qué tipo de bibliotecas planea vincular su programa? Algunas bibliotecas tienen dependencias ocultas (archivos de datos, subsistemas dinámicos) o suposiciones implícitas sobre el sistema en el que se están ejecutando.
Thomas Erker

Respuestas:

29

Esta respuesta se escribió primero para la pregunta más general "mi binario se ejecutará en todas las distribuciones", pero aborda los binarios enlazados estáticamente en la segunda mitad.


Para cualquier cosa que sea más compleja que un mundo hola estáticamente vinculado, la respuesta es probablemente no .
Sin probarlo en la distribución X, suponga que la respuesta es no para X.

Si desea enviar su software en forma binaria, limítese a

  • algunas distribuciones populares para el campo de uso de su software (escritorio, servidor, incrustado, ...)

  • las últimas una o dos versiones de cada

De lo contrario, terminará con cientos de distribución de todos los tamaños, versiones y edades (la distribución de diez años todavía está en uso y es compatible).

Prueba para esos. Solo algunos indicadores sobre qué puede (y lo hará) salir mal de lo contrario:

  • El paquete de una herramienta / biblioteca que necesita tiene un nombre diferente en todas las distribuciones e incluso en versiones de la misma distribución.

  • Las bibliotecas que necesita son demasiado nuevas o demasiado antiguas (versión incorrecta). No asuma que solo porque su programa puede vincularse, se vincula con la biblioteca correcta.

  • La misma biblioteca (archivo en el disco) tiene un nombre diferente en diferentes distribuciones, lo que hace imposible la vinculación

  • 32 bits en 64 bits: es posible que el entorno de 32 bits no esté instalado o que una biblioteca de 32 bits no esencial se traslade a un paquete adicional aparte del entorno 32on64, por lo que tiene una dependencia adicional solo para este caso.

  • Shell: no asumas tu versión de Bash. No asumas ni siquiera Bash.

  • Herramientas: no asuma que existe alguna herramienta de línea de comandos que no sea POSIX en ninguna parte.

  • Herramientas: no asumas que la herramienta reconoce una opción solo porque la versión GNU de tu distribución sí.

  • Interfaces del kernel: no asuma la existencia o la estructura de los archivos /procsimplemente porque existen / tienen la estructura en su máquina

  • Java: ¿está realmente seguro de que su programa se ejecuta en JRE de IBM como se entrega con SLES sin probarlo?

Prima:

  • Conjuntos de instrucciones: el binario compilado en su máquina no se ejecuta en hardware antiguo.

¿Es un enlace estático (o: agrupar todas las bibliotecas que necesita con su software) una solución? Incluso si funciona técnicamente, los costos asociados pueden ser demasiado altos. Entonces, desafortunadamente, la respuesta es probablemente tampoco.

  • Seguridad: usted transfiere la responsabilidad de actualizar las bibliotecas del usuario de su software a usted mismo.

  • Tamaño y complejidad: solo por diversión, intente crear un programa GUI estáticamente vinculado.

  • Interoperabilidad: si su software es un "complemento" de cualquier tipo, usted depende del software que lo llame.

  • Diseño de la biblioteca: si vincula su programa estáticamente a GNU libc y usa servicios de nombres ( getpwnam()etc.), terminará vinculado dinámicamente contra el NSS (cambio de servicio de nombres) de libc.

  • Diseño de la biblioteca: la biblioteca con la que vincula su programa estáticamente utiliza archivos de datos u otros recursos (como zonas horarias o locales).


Por todas las razones mencionadas anteriormente, la prueba es esencial.

  • Familiarícese con KVM u otras técnicas de virtualización y tenga una VM de cada distribución que planee admitir. Pruebe su software en cada VM.

  • Use instalaciones mínimas de esas distribuciones.

  • Cree una máquina virtual con un conjunto de instrucciones restringido (por ejemplo, sin SSE 4).

  • Solo estáticamente vinculado o agrupado: verifique sus binarios lddpara ver si realmente están vinculados estáticamente / use solo sus bibliotecas agrupadas.

  • Solo estático o vinculado: cree un directorio vacío y copie su software en él. chrooten ese directorio y ejecuta tu software.

Thomas Erker
fuente
Esa es una respuesta bastante completa +1
sirlark
2
Shell: en particular, Debian no utiliza bash , y dado que eso mitigó en gran medida la vulnerabilidad Shellshock en los sistemas Debian, no puedo imaginar que cambie en el futuro inmediato.
Kevin
1
Además, si desea enviar binarios, vincúlelos estáticamente .
user253751
¿Por qué el "conjunto de instrucciones" se llama "bonificación"? Si distribuye en forma binaria, realmente necesita considerar para qué ISA estará compilando. Es posible que no le interesen los usuarios de m68k, pero es difícil ignorar ARM, IA32 y X86_64 al menos.
Toby Speight
@TobySpeight Piense en SSE4 y tal. Solo podría morderte si usas ensamblador.
Thomas Erker
9

La respuesta es que depende. , pero en la mayoría de los casos, sí, siempre que las bibliotecas necesarias estén instaladas en el sistema operativo.

En general, las distribuciones más importantes como las que mencionó tienen sus herramientas de administración de paquetes que instalan la versión de la aplicación mantenida por la comunidad. Esto se encarga de los paquetes de requisitos previos que la aplicación necesitará. Si lo está instalando sin un administrador de paquetes, depende de usted asegurarse de que todos los paquetes y bibliotecas necesarios estén instalados en el sistema operativo. Es una buena idea incluir una lista de estas aplicaciones de requisitos previos en la documentación.

AlexJerez
fuente
2

Respuesta horrible primero: depende

Si usted está liberando binarios, suponer que la respuesta es "no" a no ser que se va a distribuir todas las librerías que siempre implica con ella (a partir de cero, lo cual es molesto a menos que usted está proporcionando un sistema realmente enorme que vale por sí mismo de todos modos ) o están vinculando estáticamente el equivalente.

... pero magos y dinero, y magos de dinero ...

IBM tiene algunos instaladores "Unixish generales" que me han sorprendido al trabajar en todas partes donde los he probado: varios Linuces de varias generaciones de kernel, OpenSolaris (o como se llame ahora), Solaris y BSD. Pero son enormes. Y las cosas que proporcionan son igualmente enormes. No se publican pequeños programas de autos de carrera de esta manera, solo las grandes cosas de tipo empresarial que esperarías de IBM.

En cuanto a permanecer en Linux, pero funciona bien en la mayoría de Linuxdom, esto parece ser posible en forma binaria, como lo demuestra la variedad de instaladores binarios tipo "para Linux (general)" que verá de algunos proveedores. Varios chat, navegador, juegos, metainstaladores, etc. se publican de esta manera, pero siempre por grandes vendedores que pueden pasar el tiempo para hacer esto bien. Es algo sorprendente que puedan decir "para Linux" y en general confían en que funcionará, pero este parece ser el caso.

Pero...

Distribuyo mi software como fuente con una utilidad de compilación. Hago esto en C, Erlang, Python, Guile, etc. Esto me da mucha más flexibilidad sobre si se ejecutará o no, y es mucho más fácil escribir un buildscript que se asegure de que existan las cosas correctas en el momento de la compilación que asegúrese de que todo esté en su lugar en tiempo de ejecución. Una vez que existe, es trivial escribir un autoactualizador para su programa si distribuye la fuente: la fuente suele ser mucho más pequeña que un binario que incluye todos los deps y otra locura. Al usar este método, no he tenido muchos problemas para implementar de manera confiable en Unices (y, a veces, en Windows, pero eso es un poco más complicado).

Basta de juegos de niños, ¡ármate!

Cuando se está volviendo serio, como srsly srs, acerca de encajar sin problemas en el mundo de Linux, distribuye fuentes C o recurre a un entorno totalmente administrado para un lenguaje increíblemente encantador que ya está preconstruido. Si está escribiendo código Python, por ejemplo, puede verificar las versiones y saber con qué versión de CPython funciona la suya, y generalmente espera que exista alguna versión compatible en un determinado Linux (y esto es mucho más fácil de verificar que un amplio barrido de C libs / versiones que podría estar usando). Erlang, Guile, Python, Perl, CL, etc. son todos muy objetivos fáciles para este tipo de implementación, y muchos de ellos tienen un repositorio central como CPAN o pip (o lo que sea) donde los usuarios pueden ejecutar un comando para extraer la fuente firmada cuando lo deseen, y saben que las cosas generalmente funcionarán como usted pretendía .

[Anexo: 1. Incluso Haskell generalmente puede lograr esto a través de Cabal , aunque sería cauteloso al hacerlo en un entorno de producción. 2. Existen estrategias de implementación de "lanzamiento" totalmente diferentes con Erlang que garantizan que su código conlleva un entorno completo. 3. Python va un paso más allá con entornos virtuales; no todos los tiempos de ejecución te ayudan tanto.]

Esta última parte acerca de los entornos administrados en Linux es increíble . Y, como beneficio adicional, le permite definir dependencias mucho más generales, resolverlas automáticamente sin ningún esfuerzo adicional de su parte, no requiere escribir un paquete por distribución y puede dejar de preocuparse si un sistema es 32 o 64 bit (generalmente, de todos modos).

zxq9
fuente