Boost庫命名規則
以 libboost_regex-vc71-mt-d-1_34.lib 為例:
- lib
字首:除了Microsoft Windows之外,每一個Boost庫的名字都以此字串開始。在Windows上,只有普通的靜態庫使用lib字首;匯入庫和DLL不使用。 - boost_regex
庫名稱:所有boost庫名檔案以boost_開頭。 - -vc71
Toolset 標記:標識了構建該庫所用的toolset和版本。 - -mt
Threading 標記:標識構建該庫啟用了多執行緒支援。不支援多執行緒的庫沒有-mt。 - -d
ABI標記:編碼了影響庫和其他編譯程式碼互動的細節。對於每一種特性,向標記中新增一個字母:Key Use this library when: s 靜態連結到C++標準庫和編譯器執行時支撐庫 g 使用標準庫和執行時支撐庫的除錯版本 y 使用Python的特殊除錯構建 d 構建程式碼的除錯版本 p 使用STLPort標準庫而不是編譯器提供的預設庫 n 使用STLPort已被棄用的“native iostreams” - -1_34
版本標記:完整的Boost釋出號,下劃線代替點。例如,1.31.1版本將被標記為“-1_31_1”。 - .lib
副檔名:取決於作業系統。在大多數unix平臺上,.a是靜態庫,.so是共享庫。在Windows上,.dll表示共享庫,.lib是靜態或匯入庫。
下表是對Regex庫編譯後的檔名:
檔名 | 含義 | 編譯使用該庫的程式時應使用的編譯選項 |
libboost_regex-vc90-mt-sgd-1_38.lib | 靜態庫,多執行緒,除錯版本 使用靜態除錯版本C執行時庫(LIBCMTD.LIB和LIBCPMTD.LIB) |
/MTd |
libboost_regex-vc90-mt-s-1_38.lib | 靜態庫,多執行緒 使用靜態版本C執行時庫(LIBCMT.LIB和LIBCPMT.LIB) |
/MT |
libboost_regex-vc90-mt-gd-1_38.lib | 靜態庫,多執行緒,除錯版本 使用動態除錯版本C執行時庫(MSVCRTD.LIB和MSVCPRTD.LIB) | /MDd |
libboost_regex-vc90-mt-1_38.lib | 靜態庫,多執行緒 使用動態版本C執行時庫(MSVCRT.LIB和MSVCPRT.LIB) |
/MD |
boost_regex-vc90-mt-gd-1_38.lib | 匯入庫(boost_regex-vc90-mt-gd-1_38.dll),多執行緒,除錯版本 | |
boost_regex-vc90-mt-1_38.lib | 匯入庫(boost_regex-vc90-mt-1_38.dll)多執行緒 |
需要注意的是,連結時,所使用的Regex庫檔名必須和編譯選項匹配,否則會造成如下連結錯誤:
LINK : warning LNK4098: defaultlib '×××××' conflicts with use of other libs; use /NODEFAULTLIB:library
原因是,當編譯時,cl.exe(也就是VC的編譯器)會根據上述編譯選項在編譯成的obj檔案中植入相應的defaultlib檔名(使用DUMPBIN /DIRECTIVE***,lib可以檢視),如/MT對應的就是LIBCMT.LIB(C)和LIBCPMT.LIB(C++標準庫)。當連結器處理該obj檔案時,會從檔案中取出該defaultlib檔名,將其放在命令列庫列表的最後以供使用。對於靜態庫的處理也是如此,靜態庫也是由一些obj檔案組成的,每個obj檔案中也根據當時的編譯選項被植入了相應的defaultlib。當連結器處理靜態庫時,也會將涉及到的obj檔案中的defaultlib放在命令列庫列表的最後。假設,我們的程式使用/MT編譯,那個對應的defaultlib就是LIBCMT.LIB(C)和LIBCPMT.LIB(C++標準庫)。而使用的是libboost_regex-vc90-mt-sgd-1_38.lib,它對應的defaultlib就是LIBCMTD.LIB和LIBCPMTD.LIB。連結過程中,連結器會發現採用了不同的執行時庫,所以會出現上述錯誤。
幸運的是,Visual C++支援自動連結,當包含Regex的標頭檔案時,Regex會根據當前工程的編譯選項(不同的編譯選項會定義不同的巨集,具體參見上一篇C執行時庫)自動告訴編譯器將哪個檔案送給連結器。
Boost.Regex預設使用的靜態連結方式,如果希望使用動態連結方式,如何實現呢? 定義巨集BOOST_REGEX_DYN_LINK。要注意,一定要在包含regex標頭檔案之前定義該巨集: