目錄
2.2.1 連結庫依賴項(Link Library Dependencies) 8
2.2.2 忽略匯入庫(Ignore Import Library) 9
第1章 VC++6.0
一個VC++6.0專案(Workspace),可以由多個工程(Project)構成。如下圖所示。此專案由App、Mod1、Mod2A、Mod2B四個工程組成。
圖1.1
1.1 設定依賴關係
假定上圖四個工程的依賴關係圖如下所示。
圖1.2
上圖表示:Mod2A會呼叫Mod1裡的某些函式,即Mod2A依賴於Mod1。總共有5個依賴關係。可以在VC++6.0裡設定工程依賴關係,其操作如下:
單擊【Project】【Dependencies...】選單項
圖1.3
顯示介面如下
圖1.4
上圖表示工程App依賴於Mod1、Mod2A、Mod2B。可以更換App為Mod1、Mod2A、Mod2B,依次設定這些工程的依賴項。
1.2 編譯順序
設定了工程的依賴項,編譯時編譯器會自動編排編譯順序。編譯某個工程前,確保其依賴項已經被編譯。
如編譯圖1.2中的App時,編譯器會首先編譯好Mod1、Mod2A、Mod2B;而編譯Mod2A或Mod2B之前,會首先編譯好Mod1。最終的編譯順序就是:Mod1、Mod2A、Mod2B、App(Mod2A和Mod2B的編譯順序不是確定的,哪個先編譯都可以)。
1.3 自動連線
設定了工程的依賴項,編譯時編譯器會自動連線依賴項。如圖1.2中,連線App時,會自動連線Mod1.lib、Mod2A.lib、Mod2B.lib;連線Mod2A時,會自動連線Mod1.lib。
1.4 靜態庫
要特別注意靜態庫的自動連線,否則編譯時可能會產生錯誤。
1.4.1 嵌入
可以把靜態庫看做obj檔案的集合。
假如:Mod1是靜態庫工程,它有1.cpp、2.cpp兩個原始檔,編譯後生成的Mod1.lib,其結構為:
圖1.5
假如:Mod2A是靜態庫工程,它有2A1.cpp、2A2.cpp兩個原始檔。因為它自動連線Mod1.lib。因此生成的Mod2A.lib,其結構為:
圖1.6
從上圖可以看到:Mod1.lib的內容被嵌入到Mod2A.lib。
1.4.2 替換
假如:Mod2B是靜態庫工程,它有1.cpp、2B.cpp兩個原始檔。因為它自動連線Mod1.lib。因此生成的Mod2B.lib,其結構為:
圖1.7
對上圖的解釋:編譯Mod2B時,Mod2B.lib會包含兩個obj檔案:2B.obj和1.obj。連線Mod1.lib時,會再增加1.obj和2.obj。此時,會有兩個1.obj。最終生成的Mod2B.lib只有三個obj檔案,其中的1.obj是Mod1.lib裡的obj檔案。也就是說:Mod2B裡的1.obj被替換了。
以圖1.2為例,如果Mod1、Mod2A、Mod2B均為靜態庫,則此三者之間無需設定依賴關係。在編譯App時,會自動連線Mod1.lib、Mod2A.lib、Mod2B.lib。
第2章 VC++2005
一個解決方案(Solution),可以由多個工程(Project)構成。如下圖所示。
圖2.1
2.1 設定依賴關係
英文版請單擊【Project】【Dependencies...】選單項,如下圖所示:
圖2.2 英文版
中文版請單擊【專案】【專案依賴項】選單項,如下圖所示:
圖2.3 中文版
顯示介面如下。可在該介面下設定工程之間的依賴關係,其操作方法與VC++6.0的操作方法類似。
圖2.4
2.2 自動連線
設定了工程依賴項後,編譯時編譯器會自動編排編譯順序,也會自動連線依賴項。比VC++6.0更加先進的是:VC++2005能夠對自動連線依賴項進行控制。
2.2.1 連結庫依賴項(Link Library Dependencies)
以圖1.2為例,編譯App時,會自動連線依賴項:Mod1.lib、Mod2A.lib、Mod2B.lib。如果不想讓App自動連線這些庫,可以設定App的"Link Library Dependencies"(連結庫依賴項)屬性為 No,如下面兩張圖所示:
圖2.5 英文版設定
圖2.6 中文版設定
2.2.2 忽略匯入庫(Ignore Import Library)
假如Mod1是動態庫,則編譯Mod2A、Mod2B、App時,均會自動連線Mod1的匯入庫Mod1.lib。如果設定Mod1的Ignore Import Library屬性為Yes,則編譯Mod2A、Mod2B、App時,將不再自動連線匯入庫Mod1.lib。
Ignore Import Library(忽略匯入庫)的設定如圖2.5和圖2.6所示。
2.3 靜態庫
假如Mod1、Mod2A、Mod2B均為靜態庫,則編譯Mod2A、Mod2B時,預設情況下VC++2005將不會再嵌入Mod1.lib至Mod2A.lib和Mod2B.lib。
如果需要把Mod1.lib嵌入到Mod2A.lib,則需修改Mod2A工程的Use Library Dependency Inputs(使用庫依賴項輸入)屬性,如圖2.5和圖2.6所示。
設定該項為Yes,則生成Mod2A.lib時,連線的不是Mod1.lib,而是生成Mod1.lib所需的obj檔案。即直接連線Mod1工程的obj檔案。相當於把Mod1.lib嵌入到Mod2A.lib。
設定該項為No,則生成Mod2A.lib時,連線的是Mod1.lib,但不會把Mod1.lib嵌入到Mod2A.lib。
第3章 VC++2010
3.1 引用工程
VC++2010也可以設定工程依賴項,但是它僅僅用來控制各個工程的編譯順序,不再自動連線依賴項。如果仍希望自動連線依賴項,請使用"引用工程"的功能。滑鼠右鍵單擊某個工程,彈出選單中單擊【References...】選單項。
圖3.1
下圖中,單擊"Add New Reference..."按鈕,可以增加一個引用;單擊"Remove Reference"可以刪除選中的引用;每個被引用的工程將有Link Library Dependencies(連結庫依賴項)和Use Library Dependency Inputs(使用庫依賴項輸入)兩個重要的選項。
圖3.2
注意:VC++2010的設定更加精準。如:
VC++2005裡設定App的Link Library Dependencies為True則連線App時將自動連線Mod1.lib、Mod2A.lib、Mod2B.lib。反之,則不會自動連線Mod1.lib、Mod2A.lib、Mod2B.lib。簡單的說就是:要麼全部自動連線,要麼全不自動連線。
VC++2010裡App引用了幾個工程就需要設定幾次Link Library Dependencies。如:設定引用工程Mod1的Link Library Dependencies為True,則連線App時會自動連線Mod1.lib。反之,則不會自動連線Mod1.lib。
VC++2010比VC++2005的設定更加精準,但是設定的工作量也隨之加大。
設定工程之間的引用關係後,工程之間的依賴關係將被自動生成。如下圖所示:
圖3.3
注意:如果App引用了Mod1,則Mod1前的複選框將被勾中且無法改變其狀態。也就是說一旦App引用了Mod1,那麼App必定依賴於Mod1,這是無法修改的。