2012-08-12 9 views
7

Duplicar posible:
Why does the order of '-l' option in gcc matter?¿Por qué mi programa no se puede vincular cuando cambio el orden de los argumentos de g ++?

estoy empezando a aprender el marco de pruebas unitarias Boost. Tengo un conjunto de pruebas mínimas:

#define BOOST_TEST_MAIN 
#define BOOST_TEST_DYN_LINK 
#include <boost/test/unit_test.hpp> 

BOOST_AUTO_TEST_CASE(test1) { 
    BOOST_CHECK(2 == 1); 
} 

Primero compilar la fuente:

g++ -c src/tests.cc -o src/tests.o 

Con esto se completa sin errores. Luego puedo vincular de la siguiente manera:

g++ -o tests src/tests.o -lboost_unit_test_framework 

Esto también se completa sin errores. El binario resultante se ejecuta con los resultados esperados. Sin embargo, si intercambiar el orden de src/tests.o y -lboost_unit_test_framework, consigo errores de enlace:

g++ -o tests -lboost_unit_test_framework src/tests.o 
 
src/tests.o: In function `main': 
tests.cc:(.text+0x29): undefined reference to `boost::unit_test::unit_test_main(bool (*)(), int, char**)' 
src/tests.o: In function `test1::test_method()': 
tests.cc:(.text+0x9d): undefined reference to `boost::unit_test::unit_test_log_t::set_checkpoint(boost::unit_test::basic_cstring, unsigned int, boost::unit_test::basic_cstring)' 
tests.cc:(.text+0x146): undefined reference to `boost::test_tools::tt_detail::check_impl(boost::test_tools::predicate_result const&, boost::unit_test::lazy_ostream const&, boost::unit_test::basic_cstring, unsigned int, boost::test_tools::tt_detail::tool_level, boost::test_tools::tt_detail::check_type, unsigned int, ...)' 
src/tests.o: In function `__static_initialization_and_destruction_0(int, int)': 
tests.cc:(.text+0x24d): undefined reference to `boost::unit_test::ut_detail::auto_test_unit_registrar::auto_test_unit_registrar(boost::unit_test::test_case*, unsigned long)' 
src/tests.o: In function `boost::unit_test::unit_test_log_t::unit_test_log_t()': 
tests.cc:(.text._ZN5boost9unit_test15unit_test_log_tC2Ev[_ZN5boost9unit_test15unit_test_log_tC5Ev]+0x21): undefined reference to `vtable for boost::unit_test::unit_test_log_t' 
src/tests.o: In function `boost::unit_test::make_test_case(boost::unit_test::callback0 const&, boost::unit_test::basic_cstring)': 
tests.cc:(.text._ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[boost::unit_test::make_test_case(boost::unit_test::callback0 const&, boost::unit_test::basic_cstring)]+0x1d): undefined reference to `boost::unit_test::ut_detail::normalize_test_case_name(boost::unit_test::basic_cstring)' 
tests.cc:(.text._ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[boost::unit_test::make_test_case(boost::unit_test::callback0 const&, boost::unit_test::basic_cstring)]+0x5d): undefined reference to `boost::unit_test::test_case::test_case(boost::unit_test::basic_cstring, boost::unit_test::callback0 const&)' 
src/tests.o: In function `boost::unit_test::unit_test_log_t::~unit_test_log_t()': 
tests.cc:(.text._ZN5boost9unit_test15unit_test_log_tD2Ev[_ZN5boost9unit_test15unit_test_log_tD5Ev]+0xb): undefined reference to `vtable for boost::unit_test::unit_test_log_t' 
collect2: ld returned 1 exit status 

¿Por qué el orden de mis argumentos causan errores de enlace?

+0

@AndreyT: Gracias por el hallazgo, votando para cerrar. –

Respuesta

11

Cuando GCC realiza la vinculación, las bibliotecas se tratan de forma especial: Sólo los símbolos que faltan en los ficheros objeto que vino antes de la biblioteca en la lista de línea de comandos se completa desde la biblioteca. Si tiene más archivos de objetos después de una biblioteca, los símbolos que faltan de ese objeto no se buscan en la biblioteca.

En pocas palabras, enumere primero los archivos de objetos y las bibliotecas al final.

+0

Por cierto, este cambio probablemente ocurrió en una versión reciente de gcc, estoy bastante seguro de que en gcc 4.4 el orden de las bibliotecas en la línea de comando no importaba (o gcc era más indulgente). –

+3

@MatteoItalia Este comportamiento existe desde al menos gcc 3.1.1 http://gcc.gnu.org/onlinedocs/gcc-3.1.1/gcc/Link-Options.html#Link%20Options. – log0

+0

@Ugo: es curioso, porque tuve algunos archivos makefiles que dejaron de funcionar por ese motivo solo después de actualizar desde gcc 4.4. : S –

3

El comportamiento tradicional de los vinculadores es buscar funciones externas de izquierda a derecha en las bibliotecas especificadas en la línea de comandos. Esto significa que una biblioteca que contiene la definición de una función debe aparecer después de cualquier archivo fuente o archivo de objeto que lo use. Esto incluye las bibliotecas especificadas con la opción -l atajo, como se muestra en el siguiente comando:

http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html

Cuestiones relacionadas