43 votos

Aprender a compilar las cosas desde la fuente (en Unix/Linux/OSX)

Mientras yo instale el software de paquetes (MacPorts / apt-get), donde-siempre que sea posible, a menudo me encuentro que necesitan para compilar los paquetes desde el origen. ./configure && make && sudo make install suele ser suficiente, pero a veces no funciona y cuando no, frecuentemente me atascan. Esto casi siempre se relaciona con otras dependencias de la biblioteca de alguna manera.

Me gustaría conocer el siguiente:

  • ¿Cómo puedo averiguar qué argumentos para pasar a ./configure?
  • Cómo las bibliotecas compartidas trabajar en OS X / Linux - donde viven en el sistema de ficheros, cómo ./configure && make los encuentra, lo que en realidad sucede cuando están vinculadas contra
  • ¿Cuáles son las diferencias reales entre un compartida y una biblioteca vinculada estáticamente? ¿Por qué no puedo enlazar estáticamente todo (RAM y espacio en disco son baratos estos días) y, por tanto, evitar extraña versión de la biblioteca de conflictos?
  • ¿Cómo puedo saber lo que las bibliotecas que lo he instalado, y qué versiones?
  • ¿Cómo puedo instalar más de una versión de una biblioteca sin romper mi sistema normal?
  • Si yo soy de instalar cosas desde el origen en un sistema que de otra manera se gestionan mediante los paquetes, ¿cuál es la forma más limpia de hacerlo?
  • Suponiendo que me las arreglo para compilar algo más incómoda de la fuente, ¿cómo puedo entonces paquete de seguridad para que otras personas no tengan que pasar a través de la misma aros? Especialmente en OS X....
  • ¿Cuáles son las herramientas de línea de comandos necesito dominar para ser bueno en esto? Cosas como otool, pkg-config, etc.

Estoy dispuesto a invertir un poco de tiempo y esfuerzo aquí - no necesariamente quiere respuestas directas a las preguntas anteriores, me gustaría mucho más recomendaciones de libros / tutoriales / preguntas más frecuentes que me puede leer la cual me dará el conocimiento que necesita para entender lo que realmente está pasando y, por tanto, la figura de los problemas, en mi propia.

7voto

Paul Nasrat Puntos 466

Este es un tema enorme así que vamos a empezar con las bibliotecas compartidas en Linux (ELF en Linux y Mach-O en OS X), Ulrich Drepper tiene una buena introducción a la escritura DSOs (dynamic shared objects) que cubre un poco de historia de las bibliotecas compartidas en Linux disponibles aquí, incluyendo por qué son importantes

Ulrich también se describe por qué la vinculación estática que se considera perjudicial uno de los puntos clave aquí es que las actualizaciones de seguridad. Los desbordamientos de búfer en una biblioteca común (por ejemplo, zlib) que está ampliamente relacionado de forma estática puede causar una enorme carga para las distribuciones - esto ocurrió con zlib 1.1.3 (Red Hat asesor)

ELF

El enlazador ld.de modo que la página de manual de

man ld.so

explica el básico de los caminos y de los archivos involucrados en la vinculación dinámica en tiempo de ejecución. En los modernos sistemas Linux verás las rutas adicionales añadidos a través de /etc/ld.así.conf.d/ agregado por lo general mediante un pegote incluir en /etc/ld.así.conf.

Si usted quiere ver lo que está disponible de forma dinámica a través de su ld.modo de configuración puede ejecutar

ldconfig -v -N -X

La lectura de la DSO cómo debe dar un buen nivel básico de conocimiento, para luego pasar a comprender cómo esos principios se aplican a Mach-O en OS X.

Mach-O

En OS X el formato binario es de Mach-O. Local de la documentación del sistema para el enlazador es

man dyld

El Mach formato de la documentación está disponible en Apple

UNIX herramientas de construcción

El común de la configure, make, make install proceso es generalmente proporcionado por GNU autotools que tiene un libro en línea que cubre parte de la historia de la configuración de/construcción de split y el GNU toolchain. Autoconf utiliza las pruebas para determinar la disponibilidad de la función en el objetivo de construir el sistema, que utiliza macros M4 idioma de esta unidad. Automake es básicamente un método de plantillas para los Makefiles, la plantilla en general, siendo llamado Makefile.soy el que las salidas de un archivo Makefile.en que la salida de autoconf (el script de configuración) se convierte en un archivo Makefile.

El GNU hola el programa actúa como un buen ejemplo para la comprensión de la GNU toolchain - y el manual incluye autotools documentación.

5voto

Aaron Brady Puntos 101

Bien, ./configure --help le dará una gran cantidad de información, para GNU autotools generado configurar los archivos. La mayoría de que se trata --/--sin habilitar las características (esto puede tomar un parámetro extra, como "compartido" para decir donde encontrar la biblioteca).

Otros importantes son --prefix (cuyo valor por defecto es /usr/local/ la mayoría del tiempo) para decir dónde instalar (si usted está construyendo paquetes normalmente se desea esta como --prefix=/usr o tal vez --prefix=/opt/YourPackage).

En Linux, /lib, /usr/lib y /usr/local/lib son generalmente de buscar mi gcc, y se incluye en ldconfig la configuración predeterminada. A menos que usted tenga una buena razón, esto es donde usted quiere que sus bibliotecas. /etc/ld.así.conf de mayo de lista de entradas adicionales, sin embargo.

configurar y asegúrese de encontrar por solo intentar ejecutar "gcc-l" y ver si hay errores. Usted puede agregar "-L" a tu CFLAGS parámetro para añadir rutas de búsqueda.

Usted puede tener varias versiones instaladas, y el software vinculado con una versión anterior va a estar unidos en contra de ella (ejecutar ldd para averiguar la unión en Linux), pero la nueva compila generalmente objetivo la última versión de una librería dinámica en su sistema.

La mayoría del software asume la dinámica de las bibliotecas, especialmente si se usa libtool, así que usted puede encontrar no trivial de las aplicaciones no construir correctamente de forma estática.

ls-l es su mejor apuesta para encontrar bibliotecas instaladas.

Y que es de donde soy de información; cómo jugar bien con los paquetes: no lo sé. Cuando sea posible, trato y envolver las cosas en un paquete para evitar el problema.

2voto

Mark Davidson Puntos 350

Para responder un poco de tu pregunta he encontrado una buena manera el otro día para ver lo que las bibliotecas se han instalado y las versiones (Esto es en Linux Debian así que se debe trabajar con otras versiones).

dpkg --list

Usted debe obtener una lista muy larga con una salida como esta

ii  libssl0.9.8    0.9.8c-4etch5  SSL shared libraries
ii  libssp0        4.1.1-21       GCC stack smashing protection library
ii  libstdc++5     3.3.6-15       The GNU Standard C++ Library v3
ii  libstdc++5-3.3 3.3.6-15       The GNU Standard C++ Library v3 (development
ii  libstdc++6     4.1.1-21       The GNU Standard C++ Library v3

0voto

Max Howell Puntos 471

Me disculpo por responder directamente a todo, pero yo no conozco a ninguna útiles tutoriales, preguntas frecuentes, etc. Básicamente lo que sigue es de 8 años desde la creación de aplicaciones de escritorio (que me ayudan a distribuir), la frustración y buscando en google:

Cómo puedo averiguar qué argumentos a pasar ./configurar?

La práctica realmente. Autotools es lo suficientemente fácil como que es coherente. Pero hay un montón de cosas por ahí el uso de cmake, o la costumbre de construir secuencias de comandos. Por lo general, usted no debería tener que pasar de nada a configurar, se debe averiguar si su sistema puede construir foo-herramienta o no.

Configurar y herramientas de GNU todos los busque en /, /usr y /usr/local para las dependencias. Si instala nada en cualquier otro (que hace las cosas dolorosas si la dependencia fue instalado por MacPorts o Fink), usted tendrá que pasar una bandera para configurar o modificar el entorno del shell para ayudar a las herramientas de GNU encontrar estas dependencias.

Cómo las bibliotecas compartidas trabajar en OS X / Linux - donde viven en el sistema de ficheros, cómo ./configure && make encuentra, lo que en realidad sucede cuando están vinculadas contra

En Linux que necesitan para ser instalado a un camino en el que el enlazador dinámico puede encontrar, esta es definida por la LD_LIBRARY_PATH variable de entorno y el contenido de /etc/ld.conf. En Mac es el mismo para la mayoría de los software de código abierto casi siempre (a menos que sea un Proyecto de Xcode). Excepto el env variable DYLD_LIBRARY_PATH lugar.

Hay una ruta de acceso predeterminada que el enlazador busca de las bibliotecas. Es /lib:/usr/lib:/usr/local/lib

Se puede complementar con el CPATH variable, o CFLAGS o cualquier número de otras variables de entorno realmente (muy bien complicado). Sugiero CFLAGS así:

exportación CFLAGS="$CFLAGS-L/nuevo/path"

El parámetro-L añade a la ruta de enlace.

Moderno cosas utiliza el pkg-config de la herramienta. Moderno cosas de instalar también instala un .archivo de pc que describe la biblioteca y de dónde es y cómo se conectan a ella. Esto puede hacer la vida más fácil. Pero no viene con OS X 10.5 por lo que tendrás que instalar también. También un montón de básica deps no lo apoyan.

El acto de vinculación es sólo "resolver esta función en tiempo de ejecución", realmente es una gran cadena de la tabla.

¿Cuáles son las diferencias reales entre un compartida y una biblioteca vinculada estáticamente? ¿Por qué no puedo enlazar estáticamente todo (RAM y espacio en disco son baratos estos días) y, por tanto, evitar extraña versión de la biblioteca de conflictos?

Cuando usted se conecta a una biblioteca estática archivo el código se convierte en parte de su aplicación. Sería como si fuera un gigante .archivo c para que la biblioteca y los compiló en su aplicación.

Dinámica de las bibliotecas tienen el mismo código, pero cuando se ejecute la aplicación, el código se carga en la aplicación en tiempo de ejecución (explicación simplificada).

Usted puede enlazar estáticamente a todo, sin embargo, tristemente casi cualquier construir sistemas que facilitan esta tarea. Tendrías que modificar el sistema de generación de archivos de forma manual (por ejemplo. Makefile.soy, o CMakeLists.txt). Sin embargo, esto es probablemente vale la pena aprender si usted regularmente instalar cosas que requieren diferentes versiones de las bibliotecas y usted está encontrando la instalación de dependencias en paralelo difícil.

El truco es cambiar el enlace de la línea de-lfoo a-l/ruta/a/static/foo.un

Usted probablemente puede encontrar y reemplazar. Después de comprobar que la herramienta no se vinculan a la .así que o dylib usando ldd foo o otool-L foo

Otro problema es que no todas las bibliotecas compilar las bibliotecas estáticas. Muchos lo hacen. Pero luego MacPorts o Debian podría haber decidido no enviar.

¿Cómo puedo saber lo que las bibliotecas que lo he instalado, y qué versiones?

Si usted tiene pkg-config archivos de las bibliotecas es fácil:

pkg-config --list-todos los

De lo contrario, con frecuencia no se puede fácilmente. El dylib puede tener un soname (es decir. foo.0.1.dylib, el soname es de 0,1) que es el mismo que el de la biblioteca de la versión. Sin embargo, esto no es necesario. El soname es un binario de la computabilidad característica, usted tiene que golpear la mayor parte de la soname si cambia el formato de las funciones en la biblioteca. Así que usted puede conseguir, por ejemplo. versión 14.0.5 soname para un 2.0 de la biblioteca. Aunque esto no es común.

Me frustré con este tipo de cosas y han desarrollado una solución para esto en Mac, y me refiero a lo siguiente.

¿Cómo puedo instalar más de una versión de una biblioteca sin romper mi sistema normal?

Mi solución a esto está aquí: http://github.com/mxcl/homebrew/

Me gustaría instalar desde el código fuente, y quería una herramienta para que sea fácil, pero con un poco de gestión de paquetes. Así que con Homebrew que voy a construir, por ejemplo. wget a mí mismo desde el origen, pero asegúrese de instalar a un prefijo especial:

/usr/local/Bodega/wget/1.1.4

Luego uso el homebrew herramienta para enlace simbólico en /usr/local, así que todavía tengo en /usr/local/bin/wget y /usr/local/lib/libwget.dylib

Más tarde, si tengo una versión diferente de wget puedo instalar en paralelo y acaba de cambiar la versión a la que está vinculado en el directorio /usr/local árbol.

Si estoy instalando cosas desde el origen en un sistema que de otra manera se gestionan mediante los paquetes, ¿cuál es la forma más limpia de hacerlo?

Creo que el Homebrew manera es más limpio, por lo que el uso, o el equivalente. Se instalan en /usr/local/pkgs/nombre/versión y un enlace simbólico o enlace duro que el resto.

Hacer uso de /usr/local. Cada herramienta de construcción que existe en busca allí para las dependencias y los encabezados. Tu vida será mucho más fácil.

Suponiendo que me las arreglo para compilar algo más incómoda de la fuente, ¿cómo puedo entonces paquete de seguridad para que otras personas no tengan que pasar a través de la misma aros? Especialmente en OS X....

Si no tiene ninguna dependencia puede tar el directorio de compilación y dar a alguien que puede hacer "make install". Sin embargo, sólo puede hacerlo de forma confiable para el exacto las mismas versiones de OS X. En Linux es probable que el trabajo de similares Linux (por ejemplo. Ubuntu) con la misma versión del Kernel y de la libc de la versión secundaria.

La razón por la que no es fácil de distribuir los binarios en Unix es debido a la compatibilidad binaria. El GNU personas, y todos los demás a cambiar sus interfaces binarias a menudo.

Básicamente no distribuir los binarios. Cosas que probablemente va a romper en muy extrañas maneras.

En Mac, la mejor opción es hacer una macports paquete. Todo el mundo utiliza macports. En Linux hay muchos diferentes sistemas de construcción y combinaciones, creo que no hay ningún asesorar mejor que escribir una entrada de blog acerca de cómo se logró la construcción de x herramienta y extraña configuración.

Si usted hace una descripción del paquete (por macports o homebrew), a continuación, cualquier persona puede instalar ese paquete, y que resuelve los problemas de dependencia. Sin embargo muchas veces esto no es fácil, y tampoco es fácil para obtener su macports receta incluida en el principal macports árbol. También macports no admite exóticos tipos de instalación, ofrecen una opción para todos los paquetes.

Una de mis metas a futuro con Homebrew es hacer posible que haga clic en un enlace en un sitio web (por ejemplo. homebrew://bla, y va a descargar el script de Ruby, instale el deps para que el paquete y, a continuación, crear la aplicación. Pero sí, aún no lo han hecho, pero no es muy difícil teniendo en cuenta el diseño que elegí.

¿Cuáles son las herramientas de línea de comandos necesito dominar para ser bueno en esto? Cosas como otool, pkg-config, etc.

otool sólo es realmente útil más adelante. Se nos dice que el binario compilado de enlaces. Cuando usted está pensando de las dependencias de una herramienta que tenemos que construir, es inútil. Lo mismo es cierto de pkg-config como usted ya ha instalado la dependencia antes de poder usarlo.

Mi herramienta de la cadena es, leer los archivos README e INSTALL, y hacer una configure --help. Observar la acumulación de salida para comprobar que es la correcta. Analizar los errores de compilación. Quizás en el futuro, pregunta en serverfault :)

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: