簡體   English   中英

鏈接靜態庫時的“未定義引用”

[英]“undefined reference” when linking against a static library

g ++(Ubuntu / Linaro 4.4.4-14ubuntu5)4.4.5

我有以下名為sdpAPI.a的靜態庫。 我在嘗試將其與我的測試應用程序鏈接時遇到問題。 只是想知道我是否做錯了什么。 靜態庫是用g ++構建的;

我的目錄如下:

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

我的源代碼是這樣的:

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

我的Makefile是這樣的:

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

這些是我得到的鏈接器錯誤:

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

非常感謝任何建議,

-L指定庫路徑 ,而不是特定庫。 您可能希望-L sdp/lib -l sdpAPI指定路徑庫名稱。

雖然它會嘗試用lib.a.sl (或類似的)前綴和后綴你的庫名。

因此,根據gcc聯機幫助頁,您可能還需要將庫重命名為libsdpAPI.a

-l xyz
鏈接器搜索庫的標准目錄列表,該庫實際上是名為libxyz.a的文件。


還要記住,命令行中的事物順序很重要。 通過執行$(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET) (對象之前的庫),在列出庫的位置沒有未解析的符號,所以沒有將從該圖書館帶來。

然后,當您最終引入對象(帶有未解析的符號)時,它們將保持未解析狀態,因為之后沒有列出任何庫。

您通常應該在對象之后執行庫:

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

確保在檢查庫之前知道所有未解析的符號。

這不會捕獲所有問題(例如可以使用其他方法修復的共同依賴庫),但它會確保在查看庫之前已知對象文件中的所有未解析符號。

從上面引用的手冊頁的同一部分:

它在您編寫此選項的命令中有所不同; 鏈接器按照指定的順序搜索和處理庫和目標文件。 因此, foo.o -lz bar.o搜索庫z文件后, foo.o但在此之前bar.o 如果bar.o引用z中的函數,則可能無法加載這些函數。

  • -L用於指定庫路徑

    - Ldir 將目錄dir添加到要搜索-l的目錄列表中。

  • -l是您需要指定要鏈接的

    -l library 鏈接時搜索名為library的庫。

您可能需要-L sdp/lib/ -l sdpAPI

特別是-l和-static的不同選項究竟是如何使我困惑了很長時間的。 最后做了一個男人gcc來獲取我無法在網上找到的更多細節。 希望這也有助於其他人

-llibrary -l library鏈接時搜索名為library的庫。 (將庫作為單獨參數的第二種方法僅適用於POSIX,不建議使用。)

       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在支持動態鏈接的系統上,這可以防止與共享庫的鏈接。 在其他系統上,此選項無效。

       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將目錄dir添加到要搜索-l的目錄列表中。

你需要知道的三面旗幟:

-Ldir -lLIB -static

由於您想要與靜態庫鏈接,因此需要第三個標志。 否則,您最終將與動態庫鏈接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM