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

47

Si bien instalo software desde paquetes (MacPorts / apt-get) siempre que sea posible, a menudo necesito compilar paquetes desde la fuente. ./configure && make && sudo make installgeneralmente es suficiente, pero a veces no funciona, y cuando no lo hace, a menudo me atoro. Esto casi siempre se relaciona con otras dependencias de la biblioteca de alguna manera.

Me gustaría aprender lo siguiente:

  • ¿Cómo puedo averiguar a qué argumentos pasar ./configure?
  • Cómo funcionan las bibliotecas compartidas en OS X / Linux: dónde viven en el sistema de archivos, cómo las ./configure && makeencuentra, qué sucede realmente cuando están vinculadas
  • ¿Cuáles son las diferencias reales entre una biblioteca compartida y una biblioteca vinculada estáticamente? ¿Por qué no puedo simplemente vincular estáticamente todo (la RAM y el espacio en disco son baratos en estos días) y, por lo tanto, evitar conflictos de versiones de biblioteca extraños?
  • ¿Cómo puedo saber qué bibliotecas he instalado y qué versiones?
  • ¿Cómo puedo instalar más de una versión de una biblioteca sin romper mi sistema normal?
  • Si estoy instalando cosas desde la fuente en un sistema que de otro modo se administra usando paquetes, ¿cuál es la forma más limpia de hacerlo?
  • Suponiendo que logre compilar algo de manera incómoda desde la fuente, ¿cómo puedo empaquetarlo para que otras personas no tengan que saltar por los mismos aros? Particularmente en OS X ...
  • ¿Cuáles son las herramientas de línea de comandos que necesito dominar para ser bueno en estas cosas? Cosas como otool, pkg-config, etc.

Estoy dispuesto a invertir un poco de tiempo y esfuerzo aquí: no necesariamente quiero respuestas directas a las preguntas anteriores, prefiero obtener recomendaciones sobre libros / tutoriales / preguntas frecuentes que pueda leer, lo que me dará la Necesito entender lo que realmente está sucediendo y, por lo tanto, resolver los problemas por mi cuenta.

Simon Willison
fuente

Respuestas:

40

Pido disculpas por responder directamente a todo, pero no conozco ningún tutorial útil, preguntas frecuentes, etc. Básicamente, lo que sigue son 8 años de hacer aplicaciones de escritorio (que ayudo a distribuir), frustración y búsqueda en Google:

1. ¿Cómo averiguo qué argumentos pasar a ./configure?

Practica realmente. Autotools es bastante fácil ya que es consistente. Pero hay muchas cosas por ahí usando cmake o scripts de compilación personalizados. En general, no debería tener que pasar nada para configurar, debería determinar si su sistema puede construir o no una herramienta foo.

Las herramientas de configuración y GNU buscan dependencias en /, / usr y / usr / local. Si instala algo en cualquier otro lugar (lo que hace que las cosas sean dolorosas si MacPorts o Fink instalaron la dependencia), deberá pasar un indicador para configurar o modificar el entorno del shell para ayudar a las herramientas GNU a encontrar estas dependencias.

2. Cómo funcionan las bibliotecas compartidas en OS X / Linux: dónde viven en el sistema de archivos, cómo ./configure && make las encuentra, qué sucede realmente cuando están vinculadas

En Linux, deben instalarse en una ruta que el enlazador dinámico pueda encontrar, esto está definido por la LD_LIBRARY_PATHvariable de entorno y el contenido de /etc/ld.conf. En Mac, casi siempre es lo mismo para la mayoría del software de código abierto (a menos que sea un Proyecto Xcode). Excepto que la variable env es en su DYLD_LIBRARY_PATHlugar.

Hay una ruta predeterminada en la que el vinculador busca bibliotecas. Es / lib: / usr / lib: / usr / local / lib

Puede complementar esto usando la variable CPATH, o CFLAGS o cualquier otra cantidad de variables de entorno realmente (convenientemente complicado). Sugiero CFLAGS así:

export CFLAGS = "$ CFLAGS -L / new / path"

El parámetro -L se agrega a la ruta del enlace.

Las cosas modernas usan la herramienta pkg-config. Las cosas modernas que instala también instalan un archivo .pc que describe la biblioteca y dónde está y cómo vincularla. Esto puede hacer la vida más fácil. Pero no viene con OS X 10.5, por lo que también deberá instalarlo. Además, muchos departamentos básicos no lo admiten.

El acto de vincular es simplemente "resolver esta función en tiempo de ejecución", realmente es una gran tabla de cadenas.

3. ¿Cuáles son las diferencias reales entre una biblioteca compartida y una biblioteca vinculada estáticamente? ¿Por qué no puedo simplemente vincular estáticamente todo (la RAM y el espacio en disco son baratos en estos días) y, por lo tanto, evitar conflictos de versiones de biblioteca extraños?

Cuando se vincula a un archivo de biblioteca estática, el código se convierte en parte de su aplicación. Sería como si hubiera un archivo .c gigante para esa biblioteca y lo compilaras en tu aplicación.

Las bibliotecas dinámicas tienen el mismo código, pero cuando se ejecuta la aplicación, el código se carga en la aplicación en tiempo de ejecución (explicación simplificada).

Puede enlazar estáticamente a todo, sin embargo, lamentablemente casi ningún sistema de compilación lo facilita. Tendría que editar los archivos del sistema de compilación manualmente (por ejemplo, Makefile.am o CMakeLists.txt). Sin embargo, probablemente valga la pena aprenderlo si instala regularmente elementos que requieren diferentes versiones de bibliotecas y le resulta difícil instalar dependencias en paralelo.

El truco consiste en cambiar la línea de enlace de -lfoo a -l / path / to / static / foo.a

Probablemente pueda encontrar y reemplazar. Luego verifique que la herramienta no se vincule a .so o dylib usando ldd foo o otool -L foo

Otro problema no es que todas las bibliotecas se compilan en bibliotecas estáticas. Muchos hacen. Pero MacPorts o Debian pueden haber decidido no enviarlo.

4. ¿Cómo puedo saber qué bibliotecas he instalado y qué versiones?

Si tiene archivos pkg-config para esas bibliotecas, es fácil:

pkg-config --list-all

De lo contrario, a menudo no puedes hacerlo fácilmente. El dylib puede tener un soname (es decir, foo.0.1.dylib, el soname es 0.1) que es el mismo que la versión de la biblioteca. Sin embargo, esto no es requerido. El soname es una función de computabilidad binaria, debe cambiar la mayor parte del soname si cambia el formato de las funciones en la biblioteca. Para que pueda obtener, por ejemplo. versión 14.0.5 soname para una biblioteca 2.0. Aunque esto no es común.

Me sentí frustrado con este tipo de cosas y he desarrollado una solución para esto en Mac, y estoy hablando de eso a continuación.

5. ¿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 gusta instalar desde la fuente, y quería una herramienta que lo hiciera fácil, pero con algo de administración de paquetes. Entonces con Homebrew construyo, por ejemplo. Wget de origen, pero asegúrese de instalar en un prefijo especial:

/usr/local/Cellar/wget/1.1.4

Luego uso la herramienta homebrew para vincular todo eso en / usr / local, así que todavía tengo / usr / local / bin / wget y /usr/local/lib/libwget.dylib

Más tarde, si necesito una versión diferente de wget, puedo instalarla en paralelo y simplemente cambiar la versión que está vinculada al árbol / usr / local.

6. Si estoy instalando cosas desde la fuente en un sistema que de otro modo se administra usando paquetes, ¿cuál es la forma más limpia de hacerlo?

Creo que la forma Homebrew es más limpia, así que úsala o haz el equivalente. Instale en / usr / local / pkgs / name / version y enlace simbólico o enlace duro al resto.

Utilice / usr / local. Cada herramienta de compilación que existe busca allí dependencias y encabezados. Tu vida será mucho más fácil.

7. Suponiendo que logre compilar algo de la fuente, ¿cómo puedo empaquetarlo para que otras personas no tengan que saltar por los mismos aros? Particularmente en OS X ...

Si no tiene dependencias, puede subir el directorio de compilación y dárselo a otra persona que pueda "hacer la instalación". Sin embargo, solo puede hacer esto de manera confiable para las mismas versiones exactas de OS X. En Linux, probablemente funcionará para Linux similar (por ejemplo, Ubuntu) con la misma versión de Kernel y libc menor.

La razón por la que no es fácil distribuir archivos binarios en Unix es debido a la compatibilidad binaria. La gente de GNU y todos los demás cambian sus interfaces binarias con frecuencia.

Básicamente no distribuya binarios. Las cosas probablemente se romperán de maneras muy extrañas.

En Mac, la mejor opción es hacer un paquete de macports. Todos usan macports. En Linux hay tantos sistemas de compilación y combinaciones diferentes, no creo que haya mejor consejo que escribir una entrada de blog sobre cómo logró construir la herramienta x en una configuración extraña.

Si realiza una descripción del paquete (para macports o homebrew), cualquiera puede instalar ese paquete y también resuelve los problemas de dependencia. Sin embargo, esto a menudo no es fácil, y tampoco es fácil incluir su receta de macports en el árbol principal de macports. Además, macports no admite tipos de instalación exóticos, ofrecen una opción para todos los paquetes.

Una de mis metas futuras con Homebrew es hacer que sea posible hacer clic en un enlace en un sitio web (por ejemplo, homebrew: // blah y descargará ese script de Ruby, instalará los departamentos para ese paquete y luego compilará la aplicación. Pero sí, aún no está hecho, pero no es demasiado complicado teniendo en cuenta el diseño que elegí.

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

otool es realmente solo útil después. Te dice a qué se vinculan los binarios construidos. Cuando está descubriendo las dependencias de una herramienta que tiene que construir, es inútil. Lo mismo ocurre con pkg-config ya que ya habrá instalado la dependencia antes de poder usarla.

Mi cadena de herramientas es, lea los archivos README e INSTALL, y realice una configuración --help. Observe el resultado de la compilación para verificar que esté sano. Analiza cualquier error de compilación. Tal vez en el futuro, pregunte en serverfault :)

Max Howell
fuente
2
Interesante, Homebrew se parece mucho a Portage (el administrador de paquetes de Gentoo Linux). Suena como un buen trabajo.
David Z
12

Este es un gran tema, así que comencemos 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 de DSO (objetos compartidos dinámicos) que cubre algo de la historia de las bibliotecas compartidas en Linux disponibles aquí incluyendo por qué son importantes

Ulrich también describe por qué los enlaces estáticos se consideran dañinos. Uno de los puntos clave aquí son las actualizaciones de seguridad. El búfer se desborda en una biblioteca común (por ejemplo, zlib) que está ampliamente vinculada estáticamente puede causar una gran sobrecarga para las distribuciones, esto ocurrió con zlib 1.1.3 ( aviso de Red Hat )

DUENDE

La página de manual de linker ld.so

man ld.so 

explica las rutas y archivos básicos involucrados en el enlace dinámico en tiempo de ejecución. En los sistemas Linux modernos, verá rutas adicionales agregadas a través de /etc/ld.so.conf.d/, agregadas generalmente a través de una inclusión global en /etc/ld.so.conf.

Si desea ver lo que está disponible dinámicamente a través de su configuración ld.so, puede ejecutar

ldconfig -v -N -X

Leer el DSO debe proporcionarle un buen nivel básico de conocimiento para luego comprender cómo se aplican esos principios a Mach-O en OS X.

Macho

En OS X, el formato binario es Mach-O. La documentación del sistema local para el vinculador es

man dyld

La documentación en formato Mach está disponible en Apple

Herramientas de compilación UNIX

El común configure, make, make installproceso generalmente es proporcionada por GNU autotools que tiene un libro en línea que cubre algunos de la historia de la configure / división de construcción y las herramientas GNU. Autoconf usa pruebas para determinar la disponibilidad de características en el sistema de compilación de destino, usa el lenguaje de macro M4 para manejar esto. Automake es básicamente un método de plantilla para Makefiles, la plantilla generalmente se llama Makefile.am que genera un Makefile.in que la salida de autoconf (el script de configuración) se convierte en un Makefile.

El programa hello GNU actúa como un buen ejemplo para comprender la cadena de herramientas GNU, y el manual incluye documentación de herramientas automáticas.


fuente
10

Simon! Se como te sientes; También luché con esta parte del aprendizaje de Linux. Basado en mis propias experiencias, escribí un tutorial sobre algunos de los elementos que aborda (¡principalmente como una referencia para mí!): Http://easyaspy.blogspot.com/2008/12/buildinginstalling-application-from.html . Creo que apreciarás mi nota sobre lo simples que son construir / instalar aplicaciones Python. :)

Espero que esto ayude! Y feliz compilando.

Tim Jones


Construyendo / Instalando una aplicación desde la fuente en Ubuntu Linux

Si bien los repositorios de Ubuntu están repletos de excelentes aplicaciones, en un momento u otro seguramente encontrará esa herramienta "imprescindible" que no está en los repositorios (o que no tiene un paquete Debian) o necesita un versión más nueva que en los repositorios. ¿Qué haces? Bueno, ¡tienes que construir la aplicación desde la fuente! No se preocupe, realmente no es tan complicado como parece. ¡Aquí hay algunos consejos, basados ​​en mis experiencias de pasar de ser un aficionado de rango! (Mientras uso Ubuntu para este ejemplo, los conceptos generales deberían ser aplicables a la mayoría de las distribuciones de Unix / Linux, como Fedora e incluso a la plataforma Cygwin en Windows).

El proceso básico de construcción (compilación) de la mayoría de las aplicaciones desde el origen sigue esta secuencia: configure -> compile -> install. Los comandos típicos de Unix / Linux para hacer estas cosas son: config-> make-> make install. En algunos casos, incluso encontrará páginas web que muestran que todo esto se puede combinar en un solo comando:

$ config && make && make install

Por supuesto, este comando supone que no hay problemas en ninguno de estos pasos. ¡Aquí es donde entra la diversión!

Empezando

Si no ha compilado una aplicación desde la fuente en su sistema antes, probablemente necesitará configurarla con algunas herramientas de desarrollo generales, como el gccconjunto de compiladores, algunos archivos de encabezado comunes (piense en esto como un código que ya se ha escrito por otra persona que utiliza el programa que está instalando) y la herramienta de creación. Afortunadamente, en Ubuntu, hay un metapaquete llamado build-essentialque instalará esto. Para instalarlo (¡o simplemente asegúrese de que ya lo tiene!), Ejecute este comando en la terminal:

$ sudo apt-get install build-essential

Ahora que tiene la configuración básica, descargue los archivos de origen de la aplicación y guárdelos en un directorio para el que tenga permisos de lectura / escritura, como su directorio de "inicio". Por lo general, estos estarán en un archivo con una extensión de archivo de .tar.gzo .tar.bz2. El .tarsimplemente significa que se trata de un "archivo de cinta", que es un conjunto de archivos que conserva su estructura de directorio relativo. El .gzrepresenta gzip (GNU zip), que es un formato de compresión populares de Unix / Linux. Del mismo modo, .bz2significa bzip2, que es un formato de compresión más nuevo que proporciona una mayor compresión (tamaño de archivo comprimido más pequeño) que gzip.

Después de descargar el archivo fuente, abra una ventana de terminal (Terminal del sistema desde el menú de Ubuntu) y cambie al directorio donde guardó su archivo. (Lo usaré ~/downloaden este ejemplo. Aquí, '~' es un acceso directo a su directorio "principal"). Use el comando tar para extraer los archivos del archivo comprimido descargado:

Si su archivo es un archivo gzip (por ejemplo, termina con .tar.gz), use el comando:

            $ tar -zxvf filename.tar.gz

Si su archivo es un archivo bzip2 (por ejemplo, termina con .tar.bz2), use el comando:

            $ tar -jxvf filename.tar.gz

Sugerencia: Si no desea tener que recordar todos los modificadores de línea de comandos para extraer archivos, le recomiendo obtener una (o ambas) de estas utilidades: dtrx (¡mi favorita!) O deco (más popular). Con cualquiera de estas utilidades, simplemente ingrese el nombre de la utilidad (dtrx o deco) y el nombre del archivo, y hace todo el resto. Ambos "saben" cómo manejar la mayoría de los formatos de archivo con los que es probable que se encuentren y tienen un excelente manejo de errores.

Al construir desde la fuente, hay dos tipos comunes de errores que es probable que encuentre:

  1. Los errores de configuración se producen cuando ejecuta el script de configuración (generalmente denominado config o configure) para crear un archivo MAKE que sea específico para su configuración.
  2. Los errores del compilador ocurren cuando ejecuta el comando make (después de que se haya generado el archivo make) y el compilador no puede encontrar el código que necesita.

Veremos cada uno de estos y discutiremos cómo resolverlos.

Configuración y errores de configuración

Después de extraer el archivo de archivo de código fuente, en el terminal, debe cambiar al directorio que contiene los archivos extraídos. Normalmente, este nombre de directorio será el mismo que el nombre del archivo (sin la extensión .tar.gzo .tar.bz2). Sin embargo, a veces el nombre del directorio es solo el nombre de la aplicación, sin ninguna información de versión.

En el directorio de origen, busque un READMEarchivo y / o un INSTALLarchivo (o algo con nombres similares). Estos archivos generalmente contienen información útil sobre cómo compilar / compilar la aplicación e instalarla, incluida información sobre dependencias. Las "dependencias" son solo un nombre elegante para otros componentes o bibliotecas que se requieren para compilar con éxito.

Una vez que haya leído el archivo READMEy / o INSTALL(y, con suerte, haya examinado cualquier documentación en línea relevante para la aplicación), busque un archivo ejecutable (tiene el permiso "x" establecido en el archivo) llamado configo configure. A veces, el archivo puede tener una extensión, como .sh(por ejemplo, config.sh). Este suele ser un script de shell que ejecuta algunas otras utilidades para confirmar que tiene un entorno "sensato" para la compilación. En otras palabras, verificará para asegurarse de que tiene todo lo que necesita instalado.

Consejo: Si se trata de una aplicación basada en Python, en lugar de un archivo de configuración, debe encontrar un archivo con el nombre setup.py. Las aplicaciones de Python suelen ser muy simples de instalar. Para instalar esta aplicación, como root (por ejemplo, ponga sudo delante del siguiente comando en Ubuntu), ejecute este comando:

    $ python setup.py install

Eso debería ser todo lo que necesitas hacer. Puede omitir el resto de este tutorial y proceder directamente a usar y disfrutar su aplicación.

Ejecute el script de configuración en la terminal. Por lo general, puede (¡y debería!) Ejecutar su script de configuración con su cuenta de usuario habitual.

$ ./config

El script mostrará algunos mensajes para darle una idea de lo que está haciendo. A menudo, el script le dará una indicación de si tuvo éxito o falló y, si falló, alguna información sobre la causa de la falla. Si no recibe ningún mensaje de error, puede suponer que todo salió bien.

Si no encuentra ninguna secuencia de comandos que parezca una secuencia de comandos de configuración, normalmente significa que la aplicación es muy simple y es independiente de la plataforma. Esto significa que puede simplemente pasar al siguiente paso de compilación / compilación, ya que lo proporcionado Makefiledebería funcionar en cualquier sistema.

Un ejemplo

En este tutorial, voy a usar el lector RSS basado en texto llamado Newsbeuter como ejemplo para los tipos de errores que puede encontrar al crear su aplicación. Para Newsbeuter, el nombre del script de configuración es config.sh. En mi sistema, cuando ejecuto config.sh, se producen los siguientes errores:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ ./config.sh
Checking for package sqlite3... not found

You need package sqlite3 in order to compile this program.
Please make sure it is installed.

Al investigar un poco, descubrí que, de hecho, la sqlite3aplicación estaba instalada. Sin embargo, ya que estoy tratando de construir desde la fuente, este es un consejo que lo que config.shrealmente está buscando son las bibliotecas de desarrollo (encabezados) sqlite3. En Ubuntu, la mayoría de los paquetes tienen un paquete de desarrollo asociado que termina en -dev. (Otras plataformas, como Fedora, a menudo usan un sufijo de paquete -develpara los paquetes de desarrollo).

Para encontrar el paquete apropiado para el sqlite3paquete de desarrollo, podemos usar la apt-cacheutilidad en Ubuntu (y, de manera similar, la yumutilidad en Fedora):

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-cache search sqlite

Este comando devuelve una lista bastante grande de resultados, por lo que tenemos que hacer un poco de trabajo de detective para determinar cuál es el paquete apropiado. En este caso, el paquete apropiado resulta ser libsqlite3-dev. Tenga en cuenta que a veces el paquete que estamos buscando tendrá el libprefijo, en lugar del mismo nombre del paquete más -dev. Esto se debe a que a veces solo estamos buscando una biblioteca compartida que pueda ser utilizada por muchas aplicaciones diferentes. Para instalar libsqlite3-dev, ejecute el comando típico apt-get install en la terminal:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-get install libsqlite3-dev

Ahora, tenemos que config.shvolver a ejecutar para asegurarnos de que hemos resuelto este problema de dependencia y que no tenemos más problemas de dependencia. (Si bien no lo mostraré aquí, en el caso de Newsbeuter, también tuve que instalar el libcurl4-openssl-devpaquete). Además, si instala un paquete de desarrollo (como libsqlite3-dev) y el paquete de la aplicación asociada (por ejemplo, sqlite3) ya instalado, la mayoría de los sistemas instalarán automáticamente el paquete de aplicación asociado al mismo tiempo.

Cuando la configuración se ejecute correctamente, el resultado será que creará uno o más archivos de creación. Estos archivos suelen tener un nombre Makefile(recuerde que el caso del nombre del archivo es importante en Unix / Linux!). Si el paquete de compilación incluye subdirectorios, como src, etc., cada uno de estos subdirectorios también contendrá un Makefile.

Errores de compilación y compilación

Ahora, estamos listos para compilar la aplicación. Esto a menudo se llama construcción y el nombre se toma prestado del proceso del mundo real de construir algo. Las diversas "piezas" de la aplicación, que generalmente son múltiples archivos de código fuente, se combinan para formar la aplicación general. La utilidad make administra el proceso de compilación y llama a otras aplicaciones, como el compilador y el enlazador, para que realmente hagan el trabajo. En la mayoría de los casos, simplemente ejecuta make (con su cuenta de usuario habitual) desde el directorio donde ejecutó la configuración. (En algunos casos, como compilar aplicaciones escritas con la biblioteca Qt, necesitará ejecutar otra aplicación de "envoltura" como qmake en su lugar. Nuevamente, revise siempre los documentos READMEy / o INSTALLdocumentos para obtener más detalles).

Al igual que con el script de configuración anterior, cuando ejecuta make (o la utilidad similar) en el terminal, mostrará algunos mensajes sobre lo que se está ejecutando y cualquier advertencia y error. Por lo general, puede ignorar las advertencias, ya que son principalmente para los desarrolladores de la aplicación y les están diciendo que hay algunas prácticas estándar que se están violando. Por lo general, estas advertencias no afectan la función de la aplicación. Por otro lado, los errores del compilador deben ser tratados. Con Newsbeuter, cuando ejecuté make, las cosas salieron bien por un tiempo, pero luego recibí un error:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ make
...
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/configparser.o -c src/configparser.cpp
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/colormanager.o -c src/colormanager.cpp
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:5:18: error: stfl.h: No such file or directory
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:33: error: ISO C++ forbids declaration of \u2018stfl_form\u2019 with no type
./include/stflpp.h:33: error: expected \u2018;\u2019 before \u2018*\u2019 token
./include/stflpp.h:34: error: ISO C++ forbids declaration of \u2018stfl_ipool\u2019 with no type
./include/stflpp.h:34: error: expected \u2018;\u2019 before \u2018*\u2019 token
make: *** [src/colormanager.o] Error 1

El proceso de creación se detendrá tan pronto como se encuentre el primer error. El manejo de errores del compilador a veces puede ser un negocio complicado. Tienes que mirar los errores para obtener algunas pistas sobre el problema. Por lo general, el problema es que faltan algunos archivos de encabezado, que generalmente tienen una extensión de .ho .hpp. En el caso del error anterior, está claro (¡o debería estarlo!) Que el problema es que stfl.hno se puede encontrar el archivo de encabezado. Como muestra este ejemplo, desea ver las primeras líneas del mensaje de error y avanzar para encontrar la causa subyacente del problema.

Después de mirar la documentación de Newsbeuter (¡lo que debería haber hecho antes de comenzar, pero esta parte del tutorial no sería muy significativa!), Descubrí que requiere una biblioteca de terceros llamada STFL. Entonces, ¿qué hacemos en este caso? Bueno, esencialmente repetimos exactamente el mismo proceso para esa biblioteca requerida: obtenga la biblioteca y ejecute el proceso de configuración-construcción-instalación para ella y, luego, reanude la construcción de la aplicación deseada. Por ejemplo, en el caso de STFL, tuve que instalar el libncursesw5-devpaquete para que se compilara correctamente. (Por lo general, no es necesario rehacer el paso de configuración en nuestra aplicación original después de instalar otra aplicación requerida, pero tampoco está de más).

Después de instalar con éxito el kit de herramientas STFL, el proceso de creación de Newsbeuter se ejecutó correctamente. El proceso de creación generalmente continúa donde lo deja (en el punto del error). Por lo tanto, los archivos que ya se hayan compilado correctamente no se volverán a compilar. Si desea volver a compilar todo, puede ejecutar make clean all para eliminar los objetos compilados y luego ejecutar make nuevamente.

Instalando

Una vez que el proceso de compilación se complete con éxito, estará listo para instalar la aplicación. En la mayoría de los casos, para instalar la aplicación en las áreas comunes del sistema de archivos (por ejemplo, /usr/bino /usr/share/bin, etc.), deberá ejecutar la instalación como root. La instalación es realmente el paso más simple en todo el proceso. Para instalar, en la terminal ejecute:

$ make install

Verifique la salida de este proceso en busca de errores. Si todo fue exitoso, debería poder ejecutar el nombre del comando en la terminal y se iniciará. (Agregue & al final de la línea de comando, si es una aplicación GUI, o no podrá usar la sesión de terminal hasta que la aplicación termine de ejecutarse).

Cuando crea una aplicación desde el origen, generalmente no agregará un ícono o acceso directo a los menús de la GUI en Ubuntu. Deberá agregar esto manualmente.

Y ese es básicamente el proceso, aunque potencialmente iterativo, para construir e instalar una aplicación desde la fuente en Ubuntu. ¡Después de haber hecho esto solo algunas veces, se convertirá en una segunda naturaleza para ti!

Tim Jones
fuente
Tim, me hubiera gustado leer tu tutorial, pero el enlace que publicaste no funciona.
gareth_bowles
6

Bueno, ./configure --help le dará mucha información sobre los archivos de configuración generados por las herramientas automáticas GNU. La mayor parte se reduce a --with / - sin habilitar funciones (estas pueden tomar un parámetro adicional, como "compartido" para decir dónde encontrar la biblioteca).

Otros importantes son --prefix (que por defecto es / usr / local / la mayor parte del tiempo) para decir dónde instalarlo (si está creando paquetes, generalmente quiere esto como --prefix = / usr o quizás --prefix = / opt / YourPackage).

En Linux, / lib, / usr / lib y / usr / local / lib generalmente se buscan en mi gcc, y se incluyen en la configuración predeterminada de ldconfig. A menos que tenga una buena razón, aquí es donde quiere sus bibliotecas. Sin embargo, /etc/ld.so.conf puede enumerar entradas adicionales.

configurar y hacer encontrarlos simplemente intentando ejecutar "gcc -l" y ver si se produce un error. Puede agregar "-L" a su parámetro CFLAGS para agregar rutas adicionales para la búsqueda.

Puede tener múltiples versiones instaladas, y el software vinculado a una versión anterior permanecerá vinculado a él (ejecute ldd para descubrir el enlace en Linux), pero las nuevas compilaciones generalmente apuntan a la última versión de una biblioteca dinámica en su sistema.

La mayoría del software asume libs dinámicas, especialmente si usa libtool, por lo que puede encontrar que las aplicaciones no triviales no se compilan correctamente estáticamente.

ls -l es tu mejor opción para encontrar bibliotecas instaladas.

Y ahí es donde estoy sin información; Cómo jugar bien con los paquetes: no sé. Cuando es posible, trato de envolver las cosas en un paquete para evitar el problema.

Aaron Brady
fuente
4

"¿Cómo averiguo qué argumentos pasarle a ./configure?"

generalmente: ./configure --help le dirá lo que quiere allí.

"¿Cómo puedo saber qué bibliotecas he instalado y qué versiones?"

Eso depende del sistema. Una forma es simplemente hacer una, find /|grep libname|lessya que generalmente los archivos de la biblioteca tienen la versión en el nombre del archivo.

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

De nuevo, depende del sistema y la biblioteca. sudo make altinstallcreará un nombre versionado para ti. Sin embargo, los archivos de la biblioteca generalmente se versionan ellos mismos Tenga en cuenta sin embargo; Dado que las versiones a menudo crean enlaces simbólicos a un nombre "normalizado", esto puede romper las cosas.

"Si estoy instalando cosas desde la fuente en un sistema que de otro modo se administra usando paquetes, ¿cuál es la forma más limpia de hacerlo?"

Usar los parámetros --prefix en ./configure y colocarlos en algún lugar /optes una buena práctica a seguir.

Descargo de responsabilidad: de ninguna manera soy un experto, pero he estado usando Linux durante más de 5 años desde la línea cmd (slackware, CentOS, redhat, ubuntu, misceláneos otros y OS X).

Phillip B Oldham
fuente
4

Para responder un poco a su pregunta, el otro día encontré una buena manera de ver qué bibliotecas ha instalado y las versiones (esto está en Linux Debian, por lo que también debería funcionar con otras versiones).

dpkg --list

Deberías obtener una lista realmente larga con algunos resultados como este

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
Mark Davidson
fuente
4

Simon

1.) ./configure --help proporciona una buena cantidad de información. Sugiero echarle un vistazo. Generalmente tiene opciones para compilar bibliotecas estáticas / vinculadas dinámicamente cuando sea apropiado.

2.) Las bibliotecas viven en la ruta del enlazador dinámico. Esto generalmente se establece en /etc/ld.so.conf. El vinculador busca las bibliotecas apropiadas de forma muy similar a la variable de entorno PATH que coincide con la primera encontrada.

3.) Eso generalmente genera problemas, ya que hay que volver a compilar todo cuando cambia la versión de una biblioteca. Si realiza algunas búsquedas, probablemente encontrará muchas razones por las que la vinculación estática es una mala idea. No lo he hecho en tanto tiempo que realmente no puedo dar más detalles aquí.

4.) Esto es un poco difícil. Debe verificar la ruta de la biblioteca para asegurarse de que las bibliotecas generalmente tienen un enlace simbólico a la versión instalada.

por ejemplo, libssh2.so.1 -> libssh2.so.1.0.0

En general, las personas administran las bibliotecas y los programas que instalan, ya sea lanzando sus propios paquetes de Debian o utilizando alguna otra técnica. Administro el software instalado usando stow ( http://www.gnu.org/software/stow/ ) que es muy simple e instala la biblioteca usando enlaces simbólicos. Me resulta más fácil ya que no tengo que construir / instalar / probar un paquete deb / rpm.

5.) Varias versiones de bibliotecas se pueden instalar normalmente en directorios de bibliotecas. Las bibliotecas vinculadas a ejecutables permanecerán vinculadas a las versiones con las que se vincularon. ejecutar ldd en un ejecutable le dirá a qué bibliotecas está vinculado el ejecutable.

6.) Como mencioné anteriormente, rodar sus propios paquetes de Debian o usar Stow es probablemente la solución más limpia.

7.) Realmente no puedo hablar por Mac OSX pero para Linux el sistema de empaquetado de la distribución es la mejor manera.

8.) Probablemente se resolverá mucha frustración usando ldd y descubriendo a qué versión está vinculado algo o qué biblioteca que está vinculada a un ejecutable no se puede encontrar. pkg-config lo ayudará mucho, pero solo para el software que lo usa. No es parte del sistema de construcción de herramientas automáticas predeterminado, aunque es popular en estos días.

Ian Lewis
fuente
4

Las bibliotecas estáticas no son una buena idea: si necesita actualizar la biblioteca (para solucionar un problema de seguridad, por ejemplo), deberá volver a compilar todo lo que dependa de esa biblioteca.

No me gusta la idea de "hacer que la instalación" pueda jugar con mi sistema, pero como han dicho otros, generalmente es mucho menos doloroso instalar cosas en / usr / local en lugar de usar --prefix para instalar en otro lugar. Entonces, he elegido / usr / local a mi usuario habitual (no privilegiado). De esa manera, "make install" está prácticamente garantizado para no meterse con archivos importantes del sistema. (Obviamente, esto no funcionará en sistemas multiusuario. Sin embargo, es ideal para servidores virtuales).

ithinkihaveacat
fuente
4

Aunque no estaba explícitamente en su lista de preguntas, usted menciona en su prefacio:

./configure && make && sudo make install generalmente es suficiente, pero a veces no funciona, y cuando no lo hace, a menudo me atoro.

Cuando me quede atascado en Debian o Ubuntu, usaré auto-apt que instalará automáticamente los paquetes que contienen los archivos que configurar no puede encontrar.

Ver:

Otra herramienta que puede encontrar útil es CheckInstall, agrega aplicaciones instaladas con make installsu lista de paquetes instalados: https://help.ubuntu.com/community/CheckInstall

Swoogan
fuente
3

Para OS X:

  • ¿Cómo averiguo qué argumentos pasar a ./configure?

./configure --help

  • ¿Cuáles son las diferencias reales entre una biblioteca compartida y una biblioteca vinculada estáticamente? ¿Por qué no puedo simplemente vincular estáticamente todo (la RAM y el espacio en disco son baratos en estos días) y, por lo tanto, evitar conflictos de versiones de biblioteca extraños?

El uso de bibliotecas compartidas le permite actualizar la biblioteca sin volver a compilar todo lo que hace uso de ella.

  • Cómo funcionan las bibliotecas compartidas en OS X / Linux: dónde viven en el sistema de archivos, cómo ./configure && make las encuentra, qué sucede realmente cuando están vinculadas

Las bibliotecas del sistema viven en / usr / lib.

Las bibliotecas que compila usted mismo viven en / usr / local / lib (/ usr / local es el indicador de prefijo predeterminado para ./configure).

Las variables de entorno DYLD_FALLBACK_LIBRARY_PATH y LD_LIBRARY_PATH le permiten especificar en qué carpetas buscar, por lo que / usr / local / lib debería estar allí al comienzo de la lista.

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

Instale todo en / usr / local: con las variables de entorno anteriores, la versión en / usr / local / lib tiene prioridad sobre la versión en / usr / lib en su entorno.

  • Si estoy instalando cosas desde la fuente en un sistema que de otro modo se administra usando paquetes, ¿cuál es la forma más limpia de hacerlo?

Instalar a / usr / local. En Ubuntu, primero intento usar checkinstall para crear un paquete deb.

  • Suponiendo que logre compilar algo de manera incómoda desde la fuente, ¿cómo puedo empaquetarlo para que otras personas no tengan que saltar por los mismos aros? Particularmente en OS X ...

Documentar los pasos de compilación en una publicación de blog, diría.

Alf Eaton
fuente