c++ - requisitos - ¿Existe una forma inteligente de saber el nombre de la biblioteca a la que se debe vincular en el momento de la compilación?(Linux/Kubuntu)
kubuntu 18.04 requisitos (4)
Por favor, tenga paciencia conmigo. Tengo muchas ganas de saber ya que tengo curiosidad por la respuesta:
¿Existe una forma inteligente de saber el nombre de la biblioteca a la que se debe vincular en el momento de la compilación?
Permítame darle un ejemplo que ilustra perfectamente la razón de mi pregunta.
Soy un novato de C ++. Estoy aprendiendo sobre compilación, vinculación y bibliotecas como boost. Acabo de descubrir boost / filesystem y quería probarlo. Después de haber tenido problemas para compilar, usé el siguiente código minimalista:
int main()
{
std::cout<<"Hello";
return 0;
}
// file boost_example.cpp
#include "boost/filesystem.hpp"
#include <iostream>
Intenté compilarlo, pero como soy un novato, cometí un error de novato: ¡olvidé enlazarlo a la biblioteca adecuada!
g++ boost_example.cpp -o run
Para ser precisos, experimenté el problema explicado en este capítulo de este excelente libro .
Sabía que tenía instalado boost (me dijeron que lo instale para compilar otro proyecto). Intenté copiar desde el Makefile de ese otro proyecto, pero lo siguiente no funcionó:
g++ boost_example.cpp -o run -lbooster
g++ boost_example.cpp -o run -lboost Tratando de hacer una suposición basada en la línea #include en el código, intenté lo siguiente sin éxito:
g++ boost_example.cpp -o run -lboost_filesystem En ese momento, había comenzado a buscar en la web frenéticamente. Odio los motores de búsqueda porque la mayoría de las veces, no encuentras lo que estás buscando. Encontré lo siguiente pero no me ayudaron sino a perder mi tiempo:
Impulsar el problema de enlace de la biblioteca en kubuntu
Errores del enlazador C ++ / Boost
Como soy un tipo de persona RTFM, en realidad había comprobado la documentación oficial de la biblioteca que quería usar: http://www.boost.org/doc/libs/1_43_0/libs/filesystem/doc/index.htm pero No encontré ninguna información de compilación.
En algún momento, me inspiré para comprobar qué había instalado realmente en mi sistema:
$ locate boost_file
/usr/lib/libboost_filesystem-mt.a
/usr/lib/libboost_filesystem-mt.so
/usr/lib/libboost_filesystem-mt.so.1.38.0
Por lo tanto, he encontrado el nombre propio de la biblioteca para vincular. Lo siguiente funcionó:
g++ boost_example.cpp -o run -lboost_filesystem-mt
Ahora, además de usar (posiblemente) el trabajo de adivinanza inteligente y buscar en la web, ¿hay alguna forma más inteligente de encontrar el nombre de la biblioteca a la que enlazar? Nunca hubiera adivinado el nombre de la biblioteca boost_filesystem-mt
dado el encabezado "boost/filesystem.hpp"
.
Lo que es peor: boost_filesystem-mt no se menciona en ninguna parte del sitio oficial. (Supongo que depende de la distribución / embalaje).
Una vez más, siempre hago un punto de RTFM antes de hacer una pregunta, y encontré este capítulo del libro mencionado anteriormente , así que revisé lo que podía encontrar en mi sistema en / usr / lib /:
$ ls /usr/lib/boost
/usr/lib/libboost_date_time-mt.a /usr/lib/libboost_prg_exec_monitor-mt.so.1.38.0
/usr/lib/libboost_date_time-mt.so /usr/lib/libboost_program_options-mt.a
/usr/lib/libboost_date_time-mt.so.1.38.0 /usr/lib/libboost_program_options-mt.so
/usr/lib/libbooster.a /usr/lib/libboost_program_options-mt.so.1.38.0
/usr/lib/libbooster.so /usr/lib/libboost_python-mt.a
/usr/lib/libbooster.so.0 /usr/lib/libboost_python-mt-py25.a
/usr/lib/libbooster.so.0.0.0 /usr/lib/libboost_python-mt-py25.so
/usr/lib/libboost_filesystem-mt.a /usr/lib/libboost_python-mt-py25.so.1.38.0
/usr/lib/libboost_filesystem-mt.so /usr/lib/libboost_python-mt-py26.a
/usr/lib/libboost_filesystem-mt.so.1.38.0 /usr/lib/libboost_python-mt-py26.so
/usr/lib/libboost_graph-mt.a /usr/lib/libboost_python-mt-py26.so.1.38.0
/usr/lib/libboost_graph-mt.so /usr/lib/libboost_python-mt.so
/usr/lib/libboost_graph-mt.so.1.38.0 /usr/lib/libboost_regex-mt.a
/usr/lib/libboost_iostreams-mt.a /usr/lib/libboost_regex-mt.so
/usr/lib/libboost_iostreams-mt.so /usr/lib/libboost_regex-mt.so.1.38.0
/usr/lib/libboost_iostreams-mt.so.1.38.0 /usr/lib/libboost_serialization-mt.a
/usr/lib/libboost_math_c99f-mt.a /usr/lib/libboost_serialization-mt.so
/usr/lib/libboost_math_c99f-mt.so /usr/lib/libboost_serialization-mt.so.1.38.0
/usr/lib/libboost_math_c99f-mt.so.1.38.0 /usr/lib/libboost_signals-mt.a
/usr/lib/libboost_math_c99l-mt.a /usr/lib/libboost_signals-mt.so
/usr/lib/libboost_math_c99l-mt.so /usr/lib/libboost_signals-mt.so.1.38.0
/usr/lib/libboost_math_c99l-mt.so.1.38.0 /usr/lib/libboost_system-mt.a
/usr/lib/libboost_math_c99-mt.a /usr/lib/libboost_system-mt.so
/usr/lib/libboost_math_c99-mt.so /usr/lib/libboost_system-mt.so.1.38.0
/usr/lib/libboost_math_c99-mt.so.1.38.0 /usr/lib/libboost_thread-mt.a
/usr/lib/libboost_math_tr1f-mt.a /usr/lib/libboost_thread-mt.so
/usr/lib/libboost_math_tr1f-mt.so /usr/lib/libboost_thread-mt.so.1.38.0
/usr/lib/libboost_math_tr1f-mt.so.1.38.0 /usr/lib/libboost_unit_test_framework-mt.a
/usr/lib/libboost_math_tr1l-mt.a /usr/lib/libboost_unit_test_framework-mt.so
/usr/lib/libboost_math_tr1l-mt.so /usr/lib/libboost_unit_test_framework-mt.so.1.38.0
/usr/lib/libboost_math_tr1l-mt.so.1.38.0 /usr/lib/libboost_wave-mt.a
/usr/lib/libboost_math_tr1-mt.a /usr/lib/libboost_wave-mt.so
/usr/lib/libboost_math_tr1-mt.so /usr/lib/libboost_wave-mt.so.1.38.0
/usr/lib/libboost_math_tr1-mt.so.1.38.0 /usr/lib/libboost_wserialization-mt.a
/usr/lib/libboost_prg_exec_monitor-mt.a /usr/lib/libboost_wserialization-mt.so
/usr/lib/libboost_prg_exec_monitor-mt.so /usr/lib/libboost_wserialization-mt.so.1.38.0
Y ahora me estoy rascando la cabeza muy fuerte, porque realmente no sé cómo correlacionar lo anterior con la lista de bibliotecas boost .
Pido disculpas por este largo ejemplo, pero ilustra perfectamente mi problema:
Además de conjeturas, búsquedas en la web, preguntas a otras personas, prueba y error, etc ... ¿hay alguna forma más inteligente de encontrar el nombre de la biblioteca a la que debería vincularse? ¿No se supone que ese tipo de cosas deben documentarse en alguna parte?
Estoy realmente interesado en saber la respuesta en cuanto a boost, pero mi pregunta es más genérica y es aplicable a cualquier biblioteca.
Por cierto, tengo una pregunta muy similar con respecto al nombre de los paquetes de linux (ya sean .deb o .rpm). Si me dicen que compile el software que necesito, por ejemplo, PRCE o FooBar, ¿cómo sé exactamente el nombre del paquete que debo instalar? Sé cómo usar apt-cache (para Kubuntu debs) pero algunos nombres de paquetes no son intuitivos y a menudo termino instalando paquetes que realmente no necesito ...
A veces utilizo un método de fuerza bruta, pero debe saber qué directorios buscar para la biblioteca que necesita (los sospechosos habituales son / lib, / usr / lib y / usr / local / lib). He creado un script de shell al que llamo "gnm" (abreviatura de "grep nm", las dos utilidades que utiliza) con los siguientes contenidos. Si crea un archivo de texto de este tipo, recuerde hacerlo ejecutable (chmod + x gnm).
#!/bin/sh
if [ $# -lt 2 ] ; then
echo Usage: $0 pattern file[s]
exit
fi
pattern=$1
shift
while [ $# -gt 0 ] ; do
nm $1 | grep $pattern > /dev/null
if [ $? -eq 0 ] ; then
echo $1
fi
shift
done
Cuando busco una biblioteca que define un símbolo en particular, emito un comando parecido a:
gnm symbol /usr/lib/*.a
Por ejemplo, la fuente que mencionaste me da los siguientes errores de enlace:
boost_example.cpp:(.text+0x38): undefined reference to `boost::system::get_system_category()''
boost_example.cpp:(.text+0x44): undefined reference to `boost::system::get_generic_category()''
boost_example.cpp:(.text+0x50): undefined reference to `boost::system::get_generic_category()''
boost_example.cpp:(.text+0x5c): undefined reference to `boost::system::get_generic_category()''
boost_example.cpp:(.text+0x68): undefined reference to `boost::system::get_system_category()''
así que uso el comando:
gnm get_system_category /usr/lib/*.a
que informa:
/usr/lib/libboost_filesystem.a
/usr/lib/libboost_system.a
Probar el primero de estos resultados con los mismos errores, pero el segundo funciona:
g++ boost_example.cpp -lboost_system -o run
No sé por qué necesitaba la biblioteca del sistema donde necesitaba el sistema de archivos; Tal vez diferentes versiones de Boost.
Acabo de encontrar la forma más inteligente y más oficial (en mi sistema) para descubrir la bandera de enlace. Lo que sigue solo es válido para impulsar una distribución derivada de Debian o Debian (como Kubuntu en mi caso). Las otras respuestas pueden ser más genéricas para cualquier biblioteca en cualquier sistema.
Dependiendo de la versión de boost instalada, puede tener el siguiente archivo en su distribución similar a Debian:
/usr/share/doc/libboost1.38-doc/README.Debian
parte de la cual lee:
-------- The following table shows which components use a library (shared or static) and the corresponding "-l" flag. Note that only the multithreaded version of the libraries is shipped. Component Link Flag Library Type --------- --------- ------------ Boost.Date_Time -lboost_date_time-mt static shared Boost.Filesystem -lboost_filesystem-mt static shared Boost.Graph -lboost_graph-mt static shared Boost.IOStreams -lboost_iostreams-mt static shared Boost.Math -lboost_math_c99-mt static shared -lboost_math_c99f-mt static shared -lboost_math_c99l-mt static shared Boost.MPI -lboost_mpi-mt static shared Boost.Program_options -lboost_program_options-mt static shared Boost.Python -lboost_python-mt-py24 static shared -lboost_python-mt-py25 static shared Boost.Regex -lboost_regex-mt static shared Boost.Serialization -lboost_serialization-mt static shared -lboost_wserialization-mt static shared Boost.Signals -lboost_signals-mt static shared Boost.System -lboost_system-mt static shared Boost.Test -lboost_prg_exec_monitor-mt static shared -lboost_unit_test_framework-mt static shared Boost.Thread -lboost_thread-mt static shared Boost.Wave -lboost_wave-mt static shared
¡Solo había que encontrar el lugar adecuado para la documentación!
http://www.boost.org/doc/libs/1_53_0/doc/html/bbv2/installation.html Lea acerca de la instalación allí, todo muy claro.
- Una posibilidad es verificar la lista de archivos del paquete rpm / deb. En un sistema Ubuntu, esto podría hacerse emitiendo el siguiente comando:
dpkg -L libboost-filesystem-dev
Otra posibilidad es usar pkg-config. Es un programa que ayuda a determinar los indicadores de compilación para ciertas bibliotecas (aunque no es compatible con el impulso en Ubuntu)
Puede usar Autoconf: here se puede encontrar una macro que verifica el aumento. El uso de Autoconf ayuda a mantener su plataforma / distribución de fuentes independiente.