boost庫命名規則

Boost官網的《Geting Started On Windows》(http://www.boost.org/doc/libs/1_38_0/more/getting_started/windows.html)提到了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運行時庫)自動告訴編譯器將哪個文件送給鏈接器。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章