2012-08-02 64 views
9

我正在使用Embarcadero RAD Studio 2010(C++)。項目文件(.cbproj)有五個不同的標籤,其中包含.bpis或.libs的列表。我想了解一些有關鏈接器如何使用這些庫文件列表的信息(使用或不使用運行時包時)。瞭解.cbproj文件中的軟件包導入

LinkPackageImports

LinkPackageStatics

AllPackageLibs

PackageLibs

PackageImports
我想我已經明白這最後一個。它包含可從IDE中的「項目屬性」設置的運行時軟件包列表。

這個問題的動機是我試圖從我的應用程序中消除不必要的依賴關係。 .cbproj中的這五個標籤每個似乎都包含任意不同的庫和bpis。我知道一些我不需要的圖書館,以及一些我認爲不需要的圖書館。從某些列表中刪除某些庫似乎沒有任何作用,而從其他列表中刪除其他庫會導致鏈接器錯誤的形式[ILINK32 Error] Fatal: Unable to open file 'FILENAME.OBJ'

我正在慢慢解決所有鏈接器問題,但它確實有助於確切知道當我在這五個列表中的一個列表中包含一個庫名時,我告訴鏈接器要做的事。

回答

16

我確定這些信息必須存在某處,但我一直無法在任何論壇或文檔中找到它。我從我自己的實驗中推斷出了所有這些,但是我很感謝來自更官方來源的反饋。

PackageImport - 這在IDE的Project Options中顯示爲「Runtime packages」列表。如果您在IDE中的「運行時包」列表中添加或刪除任何內容,則會更新此標記以反映該內容。如果該標記爲空或從cbproj文件中缺失,它將自動填充與RAD Studio中安裝的所有設計時包相關的所有運行時包的列表。從命令行構建時,此標記不起作用。 IDE似乎只使用PackageImport標記來計算它實際要鏈接的庫。

在這個列表中放置一個庫並不(自己)創建任何新的依賴;您實質上是在告訴IDE「如果您必須鏈接任何這些庫,請動態鏈接它們,而不是靜態鏈接」。

AllPackageLibs - 這是IDE認爲項目成功鏈接所需的所有庫的列表。從命令行構建時,此標記不起作用。如果對項目進行了更改(例如添加文件),則IDE將嘗試重新計算AllPackageLibs的內容。它從它在項目文件中找到的#pragma link中計算出來。 (我在這個項目註釋掉所有#pragma link S和注意到,當我做了一個項目修改AllPackageLibs沒有重新填充確定這一點。)

LinkPackageStatics - 如果IDE找到一個庫,做AllPackageLibs不是出現在PackageImports中,它決定靜態鏈接該庫。在這種情況下,IDE會自動將庫名稱複製到LinkPackageStatics。如果從IDE構建,此標記將始終由AllPackageLibs和PackageImports重新計算,因此手動添加的任何內容都將被鏈接器忽略。但是,如果從命令行構建,則此標記(.libs或.bpis)中的所有文件都將鏈接並顯示在ilink32命令行的「objfiles」部分。

LinkPackageImports - 如果IDE發現在AllPackageLibs庫,確實出現在PackageImports,它決定動態鏈接該庫。在這種情況下,IDE會將庫名稱(帶有.bpi擴展名)複製到LinkPackageImports。如果從IDE構建,此標記將始終由AllPackageLibs和PackageImports重新計算,因此手動添加的任何內容都將被鏈接器忽略。但是,如果從命令行構建,此標記(.libs或.bpis)中的所有文件都將被鏈接,並將出現在ilink32命令行的'libfiles'部分。

PackageLibs - 任何在PackageLibs(或的.libs .bpis)將由IDE(不管什麼PackageImports包含)直接添加到LinkPackageStatics。這些庫被添加到來自AllPackageLibs的庫前面的LinkPackageStatics。命令行構建不受此標記的影響。

無論何時您希望IDE爲您修改LinkPackageStatics或LinkPackageImports,您都需要先在IDE中構建項目;然後對項目選項做一個小改動(並撤消它);然後保存該項目。此時,IDE會將LinkPackageStatics或LinkPackageImports寫出到cbproj中,以便您的項目可以在命令行上鍊接。

鏈接庫的其他方法 - 還有幾種方法可以指定鏈接的文件,而不涉及這四個標籤。您可以直接將.lib添加到項目中(右鍵單擊項目|添加...),或者可以將行#pragma comment (lib, "libraryname.lib")插入到與項目一起編譯的文件之一中。

如果直接將.lib添加到項目中,它將出現在命令行中,並鏈接到所有其他庫。如果使用#pragma comment技巧,庫不會出現在命令行上,並且您將無法看到它已鏈接(除使用tdump並查看導出)。

摘要

當從命令行連接,(這五個的),其具有任何影響的唯一cbproj標籤LinkPackageStatics(LIBS添加到objfiles部)和LinkPackageImports(LIBS添加到libfiles部分)。這些標記的內容由IDE從AllPackageLibs和PackageImports計算,但如果需要從命令行進行鏈接,則可以在.cbproj中手動設置它們。

從IDE鏈接時,通常需要IDE爲您管理您的庫。如果您需要添加IDE不會自動檢測的庫,則應該在外部編輯器中打開.cbproj文件,並將缺少的庫添加到AllPackageLibs標記中。如果要使庫動態鏈接,還應該將庫名添加到「使用運行時包構建」列表(又名PackageImports)中。

如果要確保動態鏈接所有庫,請查看.cbproj文件中的LinkPackageStatics標籤。如果任何圖書館都在該列表中,則它們正在靜態關聯。要解決這個問題,請將這些庫的名稱複製到PackageLibs標記中(並將它們的擴展名更改爲bpi);然後刪除LinkPackageStatics標籤。

+0

這太棒了。謝謝 – 2012-12-11 17:38:23

0

男人,我希望你已經找到了解決你的問題的方法,但是我認爲你只需要禁用Build With Runtime Packages,禁用Use Dynamic RTL並且從Debug改爲Release版本,對於你正在使用的所有項目http://bcbjournal.org/articles/vol4/0009/Building_stand-alone_EXEs.htm?PHPSESSID=08f2084c32d5fce05f13518fef23f358)。

如果你有,你不能改變它,像一些二進制文件(DLL,LIB ...)某些組件,您將與上禁用的選項一些依賴是仍然如果他們先前與他們建造...

我建議您在構建之前從項目中刪除所有* .obj和* .exe(除非它們是作爲第三方模塊的必備條件提供的)...某些較舊的C++ Builder版本有一些構建問題已解決就這樣。

+1

是的,IDE *試圖*很難爲您鏈接所有正確的庫,但有時它只是不正確,您必須自己將這個庫添加到cbproj文件中。 – 2012-09-10 19:23:29