2012-12-07 42 views
6

'tanımsız referansı' error:boost testi - Ben iki basit dosyaları var

runner.cpp:

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

ve test1.cpp:

#define BOOST_TEST_DYN_LINK 
#ifdef STAND_ALONE 
# define BOOST_TEST_MODULE Main 
#endif 
#include <boost/test/unit_test.hpp> 

BOOST_AUTO_TEST_SUITE(Foo) 

BOOST_AUTO_TEST_CASE(TestSomething) 
{ 
    BOOST_CHECK(true); 
} 

BOOST_AUTO_TEST_SUITE_END() 

Ben, derlemek için kullanarak:

$ g++ -I/e/code/boost_1_52_0 -o runner -lboost_unit_test_framework runner.cpp test1.cpp 

Aşağıdaki hatayı alıyorum:

C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text+0x8c): multiple definition of `main' 
c:/pdev/mingw/bin/../lib/gcc/i686-pc-mingw32/4.7.2/../../../libboost_unit_test_framework.a(unit_test_main.o):unit_test_main.cpp:(.text.startup+0x0): first defined here 
c:/pdev/mingw/bin/../lib/gcc/i686-pc-mingw32/4.7.2/../../../libboost_unit_test_framework.a(unit_test_main.o):unit_test_main.cpp:(.text.startup+0x14): undefined reference to `init_unit_test_suite(int, char**)' 
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text+0x52): undefined reference to `_imp___ZN5boost9unit_test9framework17master_test_suiteEv' 
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text+0xb0): undefined reference to `_imp___ZN5boost9unit_test14unit_test_mainEPFbvEiPPc' 
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text$_ZN5boost9unit_test13test_observerD2Ev[__ZN5boost9unit_test13test_observerD2Ev]+0xe): undefined reference to `_imp___ZTVN5boost9unit_test13test_observerE' 
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text$_ZN5boost9unit_test13test_observerC2Ev[__ZN5boost9unit_test13test_observerC2Ev]+0xe): undefined reference to `_imp___ZTVN5boost9unit_test13test_observerE' 
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text$_ZN5boost9unit_test15unit_test_log_tC1Ev[__ZN5boost9unit_test15unit_test_log_tC1Ev]+0x22): undefined reference to `_imp___ZTVN5boost9unit_test15unit_test_log_tE' 
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x88): undefined reference to `_imp___ZN5boost9unit_test15unit_test_log_t14set_checkpointENS0_13basic_cstringIKcEEjS4_' 
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x136): undefined reference to `_imp___ZN5boost10test_tools9tt_detail10check_implERKNS0_16predicate_resultERKNS_9unit_test12lazy_ostreamENS5_13basic_cstringIKcEEjNS1_10tool_levelENS1_10check_typeEjz' 
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x21d): undefined reference to `_imp___ZN5boost9unit_test9ut_detail24auto_test_unit_registrarC1ENS0_13basic_cstringIKcEE' 
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x284): undefined reference to `_imp___ZN5boost9unit_test9ut_detail24auto_test_unit_registrarC1EPNS0_9test_caseEm' 
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x2a4): undefined reference to `_imp___ZN5boost9unit_test9ut_detail24auto_test_unit_registrarC1Ei' 
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text$_ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[__ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE]+0x1d): undefined reference to `_imp___ZN5boost9unit_test9ut_detail24normalize_test_case_nameENS0_13basic_cstringIKcEE' 
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text$_ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[__ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE]+0x5b): undefined reference to `_imp___ZN5boost9unit_test9test_caseC1ENS0_13basic_cstringIKcEERKNS0_9callback0INS0_9ut_detail6unusedEEE' 
collect2.exe: error: ld returned 1 exit status 

Yükseltme 1.52.0 ile MinGW üzerinde g ++ 4.7.2 kullanıyorum.

test1.cpp derlemeyi denerken aynı hataları alıyorum - "çoklu ana tanım" ifadesi dışında.

Resmi belgelerini epey bir süreliğine izledim, ancak bağlantı seçenekleriyle ilgili ayrıntılı bilgi eksikliği. Ben unit_test_framework yanı sıra, destek libs derlenmiş, ben de prg_exec_monitor ve test_exec_monitor var; belki de bunları bir şekilde bağlamalıyım? Birçok kombinasyon denedim, ancak hepsi bir çeşit tanımlanmamış referans bağlayıcı hatasıyla sonuçlandı. boost oluşturulan kütüphanelerin

tam listesi - Ben proje kök hepsini vardır: @llonesmiz yardımıyla

libboost_prg_exec_monitor-mgw47-mt-1_52.a 
libboost_prg_exec_monitor-mgw47-mt-1_52.dll 
libboost_prg_exec_monitor-mgw47-mt-1_52.dll.a 
libboost_prg_exec_monitor-mgw47-mt-d-1_52.a 
libboost_prg_exec_monitor-mgw47-mt-d-1_52.dll 
libboost_prg_exec_monitor-mgw47-mt-d-1_52.dll.a 
libboost_test_exec_monitor-mgw47-mt-1_52.a 
libboost_test_exec_monitor-mgw47-mt-d-1_52.a 
libboost_unit_test_framework-mgw47-mt-1_52.a 
libboost_unit_test_framework-mgw47-mt-1_52.dll 
libboost_unit_test_framework-mgw47-mt-1_52.dll.a 
libboost_unit_test_framework-mgw47-mt-d-1_52.a 
libboost_unit_test_framework-mgw47-mt-d-1_52.dll 
libboost_unit_test_framework-mgw47-mt-d-1_52.dll.a 
+1

(yani g ++ -I/e/code/boost_1_52_0 -o runner runner.cpp test1.cpp -lboost_unit_test_framework'). Link [here] (http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html). Ayrıca, -I/e/code/boost_1_52_0'nize benzer bir '-L/path/to/library 'eklemeniz de mümkündür. –

+1

[Bu cevap] (http: // stackoverflow.com/a/2907582/1252091) yaptığınız şeye çok benziyor. –

+0

@llonesmiz gerçekten, nesneler çalıştıktan sonra lib'i yerleştirir. -L.'ye de ihtiyaç duyuluyor ve lib'in -lboost_unit_test_framework-mgw47-mt-1_52' olarak geçmesi gerekiyor. '-lboost_unit_test_framework' olarak geçilmesi, bağlantı hatalarıyla sonuçlanıyor. Ancak, lib'i bulamadığından şüphelendiğimde, -lfoo gibi bir şey verdim ve böyle bir lib varlığından şikayet etmedi. Varsayılan MinGW lib yolları hakkında [bu sayfa] (http://www.mingw.org/wiki/HOWTO_Specify_the_Location_of_External_Libraries_for_use_with_MinGW) ile görüştükten sonra, bu klasörlerden birinde başka bir 'libboost_unit_test_framework.a' vardı. –

cevap

18

, bazı konulara belirlendi. 1.Kitaplıkların, bunları kullanan nesneler ve kaynaklardan sonra belirtilmesi gerekir .

olarak here tarif:

The traditional behavior of linkers is to search for external functions from left to right in the libraries specified on the command line. This means that a library containing the definition of a function should appear after any source files or object files which use it. This includes libraries specified with the short-cut -l option, as shown in the following command:

$ gcc -Wall calc.c -lm -o calc (correct order)

With some linkers the opposite ordering (placing the -lm option before the file which uses it) would result in an error,

$ cc -Wall -lm calc.c -o calc (incorrect order)
main.o: In function 'main':
main.o(.text+0xf): undefined reference to 'sqrt'

because there is no library or object file containing sqrt after ‘calc.c’. The option -lm should appear after the file ‘calc.c’

2. Kütüphane yolları açıkça belirtilmelidir. Herhangi bir lib yolu belirtilmemişse, linker varsayılan klasörlerin serilerindeki lib'leri arayabilir, böylece farklı bir kütüphane yükler ve daha sonra amaçlanmıştır. Bu benim durumumda ne oldu - Ben boost_unit_test_framework bağlamak istedim, ancak link belirtmek çünkü linker geçerli klasörde bakacağını varsayalım. Bu, çalışma zamanında ne olur, sonuçta - dll, exe ile aynı klasörde ise, onu bulacaktır.

ibboost_unit_test_framework-mgw47-mt-1_52.dll adı verilen olduğundan, linker lib'i bulacağından biraz garip buldum. için bir lib olmayan bağlantı kurmaya çalıştığımda, linker şikayet etti, bu yüzden bu bir sorunu ve MinGW linker bu ekleri yok sayar. Bazı araştırmalardan sonra, this article about MinGW library paths'u buldum. MinGW libs için arama yapan klasörler gcc -print-search-dirs çıkışında bulunabilir.

gcc -print-search-dirs | sed '/^lib/b 1;d;:1;s,/[^/.][^/]*/\.\./,/,;t 1;s,:[^=]*=,:;,;s,;,; ,g' | tr \; \\012 | grep -v '^ */' 

Bu o klasörlerin güzel bir liste yazdırır: makale Ayrıca çıkışın mantıklı bazı bash sihirli içeriyor. gcc, değil değil, varsayılan olarak, libs için geçerli dizine bakın. Bunların her birine baktım ve yüklenen lib dosyasını bulun - libboost_unit_test_framework.a, statik bir lib.

3. Static bağlayan dinamik karşı

Ben boost_unit_test_framework statik veya dinamik bağlantılı isteyip belirtmedi:

Bu ışığa kayda değer başka bir sorun getiriyor. Bu durumda , gcc prefers dynamic linking: -

Yani, ne oldu gcc yılında libboost_unit_test_framework.dll aradık olmasıdır

Because of these advantages gcc compiles programs to use shared libraries by default on most systems, if they are available. Whenever a static library ‘libNAME.a’ would be used for linking with the option -lNAME the compiler first checks for an alternative shared library with the same name and a ‘.so’ extension.

(., eşdeğer dll olan Windows üzerinde so Unix dinamik kütüphaneleri için uzantısıdır) hepsi varsayılan klasörlerdir, ancak bulamadı. Daha sonra libboost_unit_test_framework.a'u aradı ve bunu statik olarak bağladı. Bu, kaynakların #define BOOST_TEST_DYN_LINK ve olduğu için bağlantı hatalarıyla sonuçlandı ve bu nedenle lib'in dinamik olarak bağlı olmasını bekler.

statik veya dinamik bağlama zorlamak için, -Wl,-Bstatic ve -Wl,-Bdynamic bağlayıcı seçenekleri devreye girer, here tanımladı.

ben dinamik bağlama istiyorum bağlayıcı söylersem: bağlayıcı dll bulmak mümkün olmayacaktır çünkü bu, başarısız olur

$ g++ -I/e/code/boost_1_52_0 runner.cpp test1.cpp -o runner -Wl,Bdynamic -lboost_unit_test_framework 

.

4.Özet

sorunları vardı: lib yolu degildim bağlama

  • türü belirtilmedi
  • kullanmıştır kaynaklardan önce belirtilen

    1. kütüphaneler
    2. belirtilmemiş kütüphanenin adı doğru değil

    Final, çalışma komutu: Eğer kaynağı sonra kütüphaneler (-lwhatever) koymak veya dosyaları nesne gerekir ++ g ile

    $ g++ -I/e/code/boost_1_52_0 -o runner runner.cpp test1.cpp -L. -Wl,-Bdynamic -lboost_unit_test_framework-mgw47-mt-1_52 
    
  • +0

    Mükemmel cevap. Pek çok ana tanım problemi de mi çözüldü? Yakın gelecekte benzer bir şeyi kullanmayı planlıyorum ve eminim ki bu büyük bir yardım olacak. –

    +0

    @llonesmiz, evet öyleydi. Hala neden oluştuğundan emin değilim; yeni lib'ler ile yeniden üretilemedi. –

    +0

    Dizininiz, her kitaplığın iki sürümünü gösterir. Biri adının ortasında bir -d-'ile ve bir olmadan. Örneğin, "libboost_unit_test_framework-mgw47-mt-1_52.a" ve "libboost_unit_test_framework-mgw47-mt-d-1_52.a". Hangisini kullanacağını nasıl bildin? – Brick

    İlgili konular