2010-01-26 106 views
9

什麼是標準的或「最流行的」命名約定MSVC庫的構建。什麼是MSVC的DLL,靜態庫和導入庫正確的命名約定

例如,對於下列平臺庫foo有以下約定:

的Linux/GCC:

shared: libfoo.so 
import: --- 
static: libfoo.a 

的Cygwin/GCC:

shared: cygfoo.dll 
import: libfoo.dll.a 
static: libfoo.a 

的Windows/MinGW的:

shared: libfoo.dll 
import: libfoo.dll.a 
static: libfoo.a 

什麼應該用於MSVC buidls?據我所知,一般的名字是foo.dllfoo.lib,但你通常如何導入庫和靜態的區別?

注:我問,因爲CMake創建它們之間相當unpleasant碰撞命名進口和靜態庫爲foo.lib。見bug report。答案是 幫助我說服開發人員修復這個錯誤。其他人所說

+0

SCons的也使用_env.SharedLibrary_和_env.StaticLibrary_具有相同目標的名字時, 「創建(這)相當不愉快的衝突」。 – 2017-01-11 23:41:19

回答

4

通過擴展名區分庫和.dll。但是,您通過文件名而不是擴展名來區分導入庫和靜態庫。

在任何情況下,對於構建爲靜態庫的代碼集或存在DLL靜態庫的代碼,都不存在導入庫存在的情況。這是兩件不同的事情。

沒有單個MSVC標準文件名約定。通常,以「D」結尾的庫名稱通常是庫代碼的調試版本,msvcrtd.dll vs msvcrt.dll但除此之外,沒有標準。

5

作爲,也沒有一個標準,但也有流行的約定。我不確定如何毫不含糊地判斷什麼是最流行的慣例。另外,您提到的靜態庫和導入庫命名法,Release庫和Debug庫命名也有類似的區別,特別是在Windows上。不同的名稱,或不同的目錄位置:

兩種情況下(即靜態還是進口,和調試與發佈),可以以兩種方式之一進行處理。我通常會選擇使用不同的名稱,因爲我覺得它可以最大限度地減少錯誤類型庫的可能性,特別是在安裝或其他文件移動活動之後。

我通常使用foo.dllfoo.lib作爲Windows上的共享庫,而foo_static.lib作爲靜態庫時,我希望有共享和靜態版本。我看到其他人使用這個慣例,所以它可能是「最受歡迎」。

因此,我建議作如下補充到表:

的Windows/MSVC:

shared: foo.dll 
import: foo.lib 
static: foo_static.lib 

然後在cmake的,你既可以

add_library(foo_static STATIC foo.cpp) 

add_library(FooStatic STATIC foo.cpp) 
set_target_properties(FooStatic PROPERTIES OUTPUT_NAME "foo_static") 

如果由於某種原因,您不希望將「foo_static」用作符號庫名稱。

1

據我所知,有沒有真正的「標準」,至少沒有標準的大多數軟件將符合。

我的約定是我的名字動態和靜態.lib一視同仁,但將它們放置在不同的目錄,如果一個項目恰好同時支持靜態和動態聯動。例如:

foo-static 
    foo.lib 

foo 
    foo.lib 
    foo.dll 

反對依賴於庫目錄的選擇鏈接庫,所以它幾乎完全從構建過程的其餘部分分離(它不會出現在源如果你使用MSVC的#pragma comment(lib,"foo.lib")設施,並且它不出現在鏈接器的導入庫列表中)。

我見過很多次了。另外,我認爲基於MSVC/Windows的項目更傾向於使用單一的官方鏈接類型 - 靜態的,動態。但這只是我個人的觀察。

簡而言之: 的Windows/MSVC

shared: foo.dll 
import: foo.lib 
static: foo.lib 

您應該能夠使用通過CMake這個基於目錄的模式(從未使用過它)。另外,我不認爲這是一個'錯誤'。這僅僅是缺乏標準化。 CMAKE確實(imho)而不是建立一個僞標準,如果每個人都喜歡它不同。

2

庫沒有標準的命名約定。傳統的圖書館名稱前綴爲lib。許多鏈接器可以選擇在命令行上將lib添加到庫名稱中。

靜態和動態庫通常由其文件擴展名標識;雖然這不是必需的。所以libmath.a將是一個靜態庫,而libmath.solibmath.dll將是一個動態庫。

一個常見的命名約定是將庫的類別追加到名稱。例如,調試靜態數學庫將是'libmathd.a',或者在Windows中是'lib_math_debug'。一些商店還添加了Unicode作爲文件名屬性。

如果需要,可以將_msvc附加到庫名稱以指示庫需要或由MSVC創建(以區別於GCC和其他工具)。在處理多個平臺時,一種流行的慣例是將對象和庫放置在平臺特定的文件夾中。例如,一個./linux/文件夾將包含用於Linux的對象和庫,以及用於Microsoft Windows平臺的./msw/

這是一個樣式問題。風格問題通常被視爲宗教問題:它們都不是錯的,沒有普遍的風格,而且它們是個人的偏好。你選擇什麼系統,只需要一致。

1

正如其他人所說,沒有單一的標準文件在窗口上命名。

對於我們完整的產品基地,涵蓋了100多個exes,dll和靜態庫,我們已經成功使用了以下多年,它已經節省了很多困惑。它基本上是我多年來見過的幾種方法的混合。

簡而言之,我們所有的文件既有前綴又有後綴(不包括擴展本身)。它們都以「om」(基於我們的公司名稱)開頭,然後有1或2個字符組合,大致標識代碼區域。

該後綴解釋了它們是什麼類型的內置文件,根據包含Unicode,靜態,調試(Dll構建是默認設置並且沒有明確的後綴標識符)的構建,最多包含三個組合使用的字母。當我們開始這個系統時,Unicode並不是那麼流行,我們不得不支持Unicode和非Unicode編譯(在Windows 2000之前),現在一切都是專門構建的unicode,但我們仍然使用相同的命名法。

因此,一個典型的.lib文件的「設置」可能看起來像

omfThreadud.lib (Unicode/Debug/Dll) 
omfThreadusd.lib (Unicode/Static/Debug) 
omfThreadu.lib (Unicode/Release/Dll) 
omfThreadus.lib (Unicode/static) 

所有文件都內置到一個共同的bin文件夾,從而消除了大量的DLL地獄問題的開發商,也使調整編譯器/鏈接器設置更簡單 - 它們都使用相對路徑指向相同的位置,並且從不需要手動(或自動)複製項目所需的庫。擁有這些後綴還可以消除您對可能具有的文件類型的任何混淆,並且可以確保您無法在混合場景中將調試DLL放在發佈套件上,反之亦然。所有exes也使用類似的後綴(Unicode/Debug)並構建到同一個bin文件夾中。

同樣有一個單獨的「包含」文件夾,每個庫在include文件夾中都有一個與庫/ dll名稱相匹配的頭文件(例如omfthread.h)該文件本身#包含所有其他項被該圖書館曝光。如果你想要foo.dll中的功能,你只需#include「foo.h」;我們的圖書館在功能方面進行了高度細分 - 實際上我們沒有任何「瑞士軍刀」dll,因此包括整個功能庫都是合理的。 (這些標題中的每一個還包括其他必備標題,無論它們是我們的內部庫還是其他供應商SDK)

其中每個包含文件的內部使用宏使用#pramga將相應的庫名添加到鏈接器行,不需要擔心這一點。我們大多數庫可以靜態構建或作爲一個DLL構建,並使用#define OM_LINK_STATIC(如果已定義)來確定單個項目需要哪個(我們通常使用DLL,但在某些情況下,內置於.exe中的靜態庫部署或其他原因更有意義)

#if defined(OM_LINK_STATIC) 
#pragma comment (lib, OMLIBNAMESTATIC("OMFTHREAD")) 
#else 
#pragma comment (lib, OMLIBNAME("OMFTHREAD")) 
#endif 

這些宏(OMLIBNAMESTATIC & OMLIBNAME)使用_DEBUG確定它是什麼類型的構建和生成適當的庫名添加到鏈接線。

我們在庫的靜態& dll版本中使用通用定義來控制在dll構建中正確導出類/函數。從庫導出的每個類或函數都裝飾着這個宏(其名稱爲庫相匹配的基本名稱,但在很大程度上是不重要的)

class OMUTHREAD_DECLARE CThread : public CThreadBase 

在項目設置的DLL版本中,我們定義OMFTHREAD_DECLARE = __ declspec(dllexport),在庫的靜態庫版本中,我們將OMFTHREAD_DECLARE定義爲空的

在庫的頭文件,我們把它定義基於客戶端是如何試圖鏈接到它

#if defined(OM_LINK_STATIC) 
#define OMFTHREAD_DECLARE 
#else 
#define OMFTHREAD_DECLARE __declspec(dllimport) 
#endif 

希望使用我們的內部圖書館之一隻想補充適當的包含於一個典型的項目其stdafx.h(通常),它只是工作,如果他們需要鏈接到靜態版本,他們只是將OM_LINK_STATIC添加到他們的編譯器設置(或在stdafx.h中定義它),它再次它只是工作。

0

據我所知,目前還沒有任何關於這方面的約定。下面是我如何做到這一點的例子:

(項目){子模塊} {平臺} {結構} {編譯器運行} _ {BuildType}的.lib/DLL

完整的文件名應爲小寫只能包含預先指定下劃線的字母數字。子模塊字段(包括其前導下劃線)是可選的。

項目:保存項目名稱/標識符。優選儘可能短。即「dna」

子模塊:可選。保存模塊名稱。優選儘可能短。即「dna_audio」

平臺:標識二進制編譯的平臺。即「win32」(Windows),「winrt」,「xbox」,「android」。

架構:描述二進制編譯的架構。即「x86」,「x64」,「arm」。在那裏架構名稱對於各種位都是相同的,因此使用它的名字後面跟着位數。即。 「name16」,「name32」,「name64」

CompilerRuntime:可選。並非所有的二進制文件都鏈接到編譯器運行時,但是如果他們這樣做,它就包含在這裏。即「vc90」(Visual Studio 2008),「gcc」。適用的公寓可以包括即「vc90mt」

BuildType:可選。這可以保存字母(以任何需要的順序),每個字母都可以說明關於構建細節的一些信息。 d =調試(略如果釋放)T =靜態(省略如果動態)A = ANSI(省略如果Unicode)的

實例(假設名爲 「DNA」 項目): dna_win32_x86_vc90.lib/DLL dna_win32_x64_vc90_d.lib/DLL dna_win32_x86_vc90_sd.lib dna_audio_win32_x64_vc90.lib/DLL dna_audio_winrt_x64_vc110.lib/DLL