2016-04-20 17 views
3

我正在學習ARToolKit和CMake。我正在嘗試製作一個CMake例程來複制ARToolKit在其Makefile文件中做的事情。我發現這一點:爲什麼靜態庫正在被用於兩次編譯工作?

LIBS= -lARgsub_lite -lARvideo -lAR -lARICP -lAR -lglut -lGLU -lGL -lX11 -lm -lpthread -ljpeg -ldc1394 -lraw1394 

$(BIN_DIR)/simpleLite: simpleLite.o $(OBJS) 
cc -o $(BIN_DIR)/simpleLite simpleLite.o $(OBJS) $(LDFLAG) $(LIBS) 

我注意到-lAR在聲明兩次。我決定複製這個在我的CMake文件中,也宣佈了兩次。

set(ART_STATICS libARgsub_lite.a libARvideo.a libAR.a libARICP.a libAR.a) 
link_directories(${ART_DIR}/lib) 

它的工作原理。但是如果我刪除最後一個是重複的,那麼程序會抱怨它無法從libAR庫中找到函數。 (確切地說它是libAR的matrix.h中的矩陣函數)爲什麼?訂單是否重要?或者libARICP.a可能在libAR.a中「消耗」某些東西,因此您必須再次聲明它?對不起,我不明白鏈接靜態庫的內部運作...

+0

是的,訂單很重要。這些庫之間可能存在依賴關係,因此必須以這種方式進行處理。 –

+0

您應該考慮使用-start-group和--end-group來指定循環依賴關係,而不是重複。 –

回答

2

我覺得這是一個比喻特別有用的解釋,你問有關(Source):

  • 想到一個存檔圖書館作爲一個書架,有一些書(分開的.o文件)。
  • 某些書籍可能會將您轉到其他書籍(通過未解析的符號),這些書籍可能位於同一書架上,也可能位於不同的書架上。

館員來到第一書架有兩個列表(在 您的鏈接線的第一個歸檔庫) - 的事情,她仍然需要 (未解決的符號)列表,而她已經擁有的東西的清單(符號 已經定義)。

通常,她已經擁有crt0.o(通過編譯器驅動程序添加到鏈接行中),它​​指向main。所以她的「需求」列表主要包含 。通常,她將有main.o爲好,這意味着她不再需要 爲主,但可能需要malloc的,免費的,printf的,等

現在她開始掃描一個書架在時間尋找書籍 定義她需要的符號。如果一本書在 「需要」列表中定義了其中一個符號,她從書架上取出該書,從「需要」列表中刪除該書中定義的所有符號,將所有已定義的 符號添加到「有」列表中,並將該書和 尚未包含在「有」列表中的所有符號添加到「需要」列表中。

如果一本書沒有定義當前在「需要」列表中的任何符號, 她不會接受它(儘管本書稍後可能會派上用場)。

如果她剛拿的一本書定義了一個她已經擁有的符號,那就是 「多重定義的符號」問題。

如果她從當前書架上拿過書籍,她再次重新掃描書架 ,尋找更多書籍(因爲她只是 花費的書籍可能需要當前書架上的其他書籍)。

一旦有沒有更多的書,她所需要的電流貨架上,她是 與架子做的,她不會返回它(除非與之對應的 庫被列在命令行上幾個 次) 。

如果搜索命令行中列出的所有書架(如 以及它是由編譯器驅動程序加入libc中)後,她仍然在「需要」列表 條目,有一個「未定義的符號」錯誤。很顯然,如果你的許多生物學書籍都提到化學書籍,並且你有生物學論文寫作,那麼你最好在化學書籍之前開始在生物學書架上搜索 。

有時,兩個歸檔庫是相互依賴的:來自一個 的對象依賴於來自另一個的對象,反之亦然。

這意味着,有聯這樣的庫不正確的順序, 這兩個庫是結構不良,並且,爲了 成功鏈接的可執行文件,則可能需要同時列出這些 庫幾次,如:

gcc main.o -lfoo -lbar -lfoo -lbar -lfoo 

在使用GNU LD一個可以使用--start基團和 --end組命令行選項的系統來解決這樣的圖書館間的依賴關係。