2011-01-07 19 views
20

g ++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"niezdefiniowana odniesienia" podczas łączenia przed statycznej biblioteki

Mam następujący statycznej biblioteki o nazwie sdpAPI.a. Mam problem z połączeniem go z moją aplikacją testową. Zastanawiam się, czy robię coś nie tak. Biblioteka statyczna została zbudowana za pomocą g ++;

Mój katalog jest w następujący sposób:

/projects/unit_test/main.c 
/projects/unit_test/sdp/inc/sdpAPH.h 
/projects/unit_test/sdp/lib/sdpAPI.a 

mój kod źródłowy jest taka:

#include <stdio.h> 

#include "sdpAPI.h" 

int main(void) 
{ 
    printf("----- TEST SDP ------\n"); 

    try { 
     sdpSessionDescription sdp; 
     sdp.clear(); 
    } 
    catch(...) { 
     printf("----- TEST FAILED --------\n"); 
     return 0; 
    } 

    printf("------ TEST SUCCESSFULL ------\n"); 

    return 0; 
} 

A mój Makefile jest taka:

OBJECT_FILES = main.o 
CC = g++ 
CFLAGS = -Wall -Wextra -Wunreachable-code -ggdb -O0 
TARGET = sdp_demo 

INC_PATH = -I sdp/inc 
LIB_PATH = -L sdp/lib/sdpAPI.a 

$(TARGET): $(OBJECT_FILES) 
$(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET) 

main.o: main.c 
$(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) -c main.c 

clean: 
rm -f $(TARGET) $(OBJECT_FILES) *~ 

Są to błędy łącznikowe jestem uzyskanie:

undefined reference to `sdpSessionDescription::sdpSessionDescription()' 
undefined reference to `sdpSessionDescription::clear()' 
undefined reference to `sdpSessionDescription::~sdpSessionDescription()' 
undefined reference to `sdpSessionDescription::~sdpSessionDescription()' 

Wielkie dzięki za wszelkie sugestie,

Odpowiedz

37

-L określa ścieżkę biblioteki , a nie konkretne biblioteki. Prawdopodobnie chcesz, aby -L sdp/lib -l sdpAPI określała nazwę biblioteki jako ścieżkę i.

Mimo że spróbuje przedłożyć i podfiksować nazwę biblioteki za pomocą lib i .a lub .sl (lub podobnej).

Więc może należy również zmienić nazwę biblioteki libsdpAPI.a jak na gcc manpage:

-l xyz
          Łącznik przeszukuje standardową listę katalogów dla biblioteki, która jest faktycznie plik o nazwie libxyz.a.


Należy także pamiętać, że porządek rzeczy w sprawach wiersza poleceń. Robiąc $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET) (biblioteki przed obiektami), nie ma żadnych nierozwiązanych symboli w punkcie, w którym lista bibliotek, więc nic nie zostanie wniesiona z tej biblioteki.

Następnie, gdy w końcu wprowadzasz obiekty (z ich nierozwiązanymi symbolami), one pozostają nierozwiązane, ponieważ nie ma bibliotek wymienionych poniżej.

zwykle należy zrobić po bibliotek obiektów:

$(CC) $(CFLAGS) $(INC_PATH) $(OBJECT_FILES) $(LIB_PATH) -o $(TARGET) 

aby zapewnić wszystkie symbole nierozwiązane są znane przed sprawdzeniem biblioteki.

To nie złapie wszystkie problemy (takie jak biblioteki współzależnych, które mogą być mocowane za pomocą innych środków), ale będzie to zapewnić wszystkie nierozwiązane symbole w obiekcie pliki są znane informacje przed patrząc na bibliotekach.

Z tej samej sekcji strony człowieka cytowany powyżej:

To robi różnicę, gdzie w komendzie piszesz tę opcję; linker przeszukuje i przetwarza biblioteki i pliki obiektów w kolejności, w jakiej zostały określone. Tak więc foo.o -lz bar.o przeszukuje bibliotekę z po pliku foo.o, ale przed foo.o, ale przed foo.o. Jeśli bar.o odnosi się do funkcji w z, funkcje te mogą nie zostać załadowane.

+0

Skopiowałem bibliotekę statyczną do tego: libsdpAPI.ai edytował następujący wiersz LIB_PATH = -L sdp/lib -l sdpAPI. Jednak wciąż otrzymuję to samo niezdefiniowane odniesienie. Dzięki. – ant2009

+0

@ ant2009, ponieważ zamówienie jest ważne. Zobacz zaktualizowaną odpowiedź. – paxdiablo

+0

Dzięki, to zadziałało. Miałem to w złej kolejności. Jestem tak przyzwyczajony do wspólnego działania, że ​​nie wiedziałem o zamówieniu ze statycznym. Dzięki. – ant2009

10
  • -L służy do określenia biblioteki ścieżkę:

    - LdirDodaj katalog dir do listy katalogów do wyszukania - l.

  • -l jest to, czego potrzebujesz, aby określić, które biblioteka połączyć przeciwko:

    -lbibliotekaSzukaj biblioteki biblioteki o nazwie podczas łączenia.

Prawdopodobnie trzeba -L sdp/lib/ -l sdpAPI

+0

Ponadto, i nie wiem dlaczego, jeśli jest gdzieś udokumentowana, g ++/gcc może się zdenerwować, gdy kolejność bibliotek jest błędna. –

1

W jaki sposób dokładnie różne opcje, szczególnie -l i -static, dezorientowały mnie przez długi czas. W końcu zrobił człowiek gcc, aby uzyskać więcej szczegółów, których nie mogłem znaleźć w Internecie. Mam nadzieję, że to pomoże komuś innemu

-lbiblioteka -l biblioteka Przeszukuje bibliotekę o nazwie biblioteka podczas łączenia. (Drugi alternatywa z biblioteką jako oddzielny argumentem jest tylko dla zgodności z POSIX i nie jest zalecane.)

 It makes a difference where in the command you write this option; 
     the linker searches and processes libraries and object files in the 
     order they are specified. Thus, foo.o -lz bar.o searches library z 
     after file foo.o but before bar.o. If bar.o refers to functions in 
     z, those functions may not be loaded. 

     The linker searches a standard list of directories for the library, 
     which is actually a file named liblibrary.a. The linker then uses 
     this file as if it had been specified precisely by name. 

     The directories searched include several standard system 
     directories plus any that you specify with -L. 

     Normally the files found this way are library files---archive files 
     whose members are object files. The linker handles an archive file 
     by scanning through it for members which define symbols that have 
     so far been referenced but not defined. But if the file that is 
     found is an ordinary object file, it is linked in the usual 
     fashion. The only difference between using an -l option and 
     specifying a file name is that -l surrounds library with lib and .a 
     and searches several directories. 

-static W systemach obsługujących dynamiczne linkowanie, zapobiega to powiązanie z współdzielonych bibliotek. W innych systemach ta opcja nie ma zastosowania.

 This option will not work on Mac OS X unless all libraries 
     (including libgcc.a) have also been compiled with -static. Since 
     neither a static version of libSystem.dylib nor crt0.o are 
     provided, this option is not useful to most people. 

-Ldir Dodaj katalog dir do listy katalogów ma być przeszukiwany -l.

-1

Trzy flagi trzeba wiedzieć:

-Ldir -lLIB -static

Skoro chcesz połączyć z biblioteki statycznej, trzeba trzecią flagę. W przeciwnym razie otrzymasz link do biblioteki dynamicznej.

Powiązane problemy