2011-01-07 31 views
20

g ++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"tham chiếu không xác định" khi liên kết với một thư viện tĩnh

Tôi có thư viện tĩnh sau đây gọi là sdpAPI.a. Tôi đang gặp sự cố khi cố liên kết nó với ứng dụng thử nghiệm của mình. Chỉ cần tự hỏi nếu tôi đang làm gì đó sai. Thư viện tĩnh đã được xây dựng với g ++;

thư của tôi là như sau:

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

mã nguồn của tôi là thế này:

#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; 
} 

Và Makefile của tôi là thế này:

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) *~ 

Đây là những mối liên kết lỗi tôi nhận được:

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

Rất cám ơn cho bất cứ đề nghị,

Trả lời

37

-L xác định đường dẫn thư viện , không phải là một thư viện cụ thể. Bạn có thể muốn -L sdp/lib -l sdpAPI để chỉ định cả đường dẫn tên thư viện.

Mặc dù nó sẽ cố gắng tiền tố và sau đó đặt tên thư viện của bạn bằng lib.a hoặc .sl (hoặc tương tự).

Vì vậy, bạn cũng có thể cần phải đổi tên thư viện của bạn để libsdpAPI.a theo manpage gcc:

-l xyz
          Các mối liên kết tìm kiếm một danh sách tiêu chuẩn của thư mục cho thư viện, mà thực sự là một tệp có tên là libxyz.a.


Cũng nên nhớ rằng thứ tự của sự vật trong những vấn đề dòng lệnh. Bằng cách thực hiện $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET) (thư viện trước đối tượng), không có biểu tượng chưa được giải quyết tại thời điểm bạn liệt kê thư viện, do đó không có thư nào được đưa vào từ thư viện đó.

Sau đó, khi bạn cuối cùng đưa vào các đối tượng (với biểu tượng chưa được giải quyết), chúng giữ nguyên vì không có thư viện nào được liệt kê sau đó.

Bạn thường nên làm thư viện sau khi các đối tượng:

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

để đảm bảo tất cả những biểu tượng chưa được giải quyết được biết trước khi kiểm tra các thư viện.

Điều này sẽ không bắt được tất cả các vấn đề (như các thư viện đồng phụ thuộc có thể được cố định bằng các phương tiện khác), nhưng nó sẽ đảm bảo tất cả các ký hiệu chưa được giải quyết trong các tệp đối tượng được biết trước khi xem các thư viện.

Từ phần cùng của trang người đàn ông trích dẫn ở trên:

Nó làm cho một sự khác biệt nơi trong lệnh bạn viết tùy chọn này; trình liên kết tìm kiếm và xử lý các tệp thư viện và đối tượng theo thứ tự chúng được chỉ định. Do đó, foo.o -lz bar.o tìm kiếm thư viện z sau tệp foo.o nhưng trước bar.o. Nếu bar.o đề cập đến các chức năng trong z, các chức năng đó có thể không được tải.

+0

Tôi đã sao chép thư viện tĩnh này: libsdpAPI.a và chỉnh sửa dòng sau LIB_PATH = -L sdp/lib -l sdpAPI. Tuy nhiên, tôi vẫn nhận được cùng một tham chiếu không xác định. Cảm ơn. – ant2009

+0

@ ant2009, đó là vì thứ tự quan trọng. Xem câu trả lời được cập nhật. – paxdiablo

+0

Cảm ơn, điều đó đã hiệu quả. Tôi đã có nó theo thứ tự sai. Tôi rất quen với việc chia sẻ Tôi không biết về thứ tự tĩnh. Cảm ơn. – ant2009

10
  • -L được sử dụng để xác định một thư viện đường:

    - LdirThêm thư mục dir vào danh sách các thư mục cần tìm kiếm - l.

  • -l là những gì bạn cần phải xác định những thư viện để liên kết chống lại:

    -lthư việnTìm kiếm thư viện thư viện tên là khi liên kết.

Bạn có lẽ cần -L sdp/lib/ -l sdpAPI

+0

Ngoài ra, và tôi không biết tại sao nếu nó được ghi lại ở đâu đó, g ++/gcc có thể khó chịu khi thứ tự của libs sai. –

1

Làm thế nào chính xác các tùy chọn khác nhau đặc biệt là -l và -static đã làm tôi bối rối trong một thời gian dài. Cuối cùng đã làm một người đàn ông gcc để có thêm chi tiết mà tôi đã không thể tìm thấy trực tuyến. Hy vọng điều này cũng giúp người khác quá

-llibrary -l thư viện Tìm kiếm thư viện có tên thư viện khi liên kết. (Thứ hai thay thế với các thư viện như một đối số riêng biệt chỉ dành cho POSIX tuân thủ và không được khuyến khích.)

 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 Trên các hệ thống hỗ trợ liên kết động, điều này ngăn chặn liên kết với các thư viện chia sẻ. Trên các hệ thống khác, tùy chọn này không có hiệu lực.

 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 Thêm thư mục thư mục vào danh sách các thư mục được tìm kiếm -l.

-1

Ba cờ bạn cần biết:

-Ldir -lLIB -static

Vì bạn muốn liên kết với thư viện tĩnh, bạn cần cờ thứ ba. Nếu không, bạn sẽ kết thúc với việc liên kết với một thư viện động.

Các vấn đề liên quan