MSVC dll、静态库和导入库的正确命名约定是什么
MSVC 库构建的标准或“最流行”命名约定是什么。
例如,对于以下平台,库 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 构建应该使用什么?据我所知,通常的名称是foo.dll
和foo.lib
,但是你通常如何区分导入库和静态库呢?
注意:我问是因为CMake
创建了相当令人不快的冲突将导入库和静态库都命名为foo.lib
。请参阅错误报告。答案是 帮助我说服开发人员修复这个错误。
What is standard or "most-popular" naming convention for MSVC library builds.
For example, for following platforms library foo
has these conventions:
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
What should be used for MSVC buidls? As far as I know, usually names are foo.dll
and foo.lib
, but how do you usually distinguish between import library and static one?
Note: I ask because CMake
creates quite unpleasant collision between them naming both import and static library as foo.lib
. See bug report. The answer would
help me to convince the developers to fix this bug.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以通过扩展名来区分库和 .dll。但是您可以通过文件名来区分导入库和静态库,而不是扩展名。
不会存在针对构建为静态库的一组代码存在导入库的情况,或者存在针对 dll 的静态库的情况。这是两件不同的事情。
没有单一的 MSVC 标准文件名约定。通常,以“D”结尾的库名称通常是库代码的调试版本,
msvcrtd.dll
与msvcrt.dll
但除此之外,还有没有标准。You distinguish between a library and a .dll by the extension. But you distinguish between a import library and a static library by the filename, not the extension.
There will be no case where an import library exists for a set of code that was built to be a static library, or where a static library exists for a dll. These are two different things.
There is no single MSVC standard filename convention. As a rule, a library name that ends in "D" is often a debug build of library code,
msvcrtd.dll
vsmsvcrt.dll
but other than that, there are no standards.正如其他人提到的,没有标准,但有流行的约定。我不确定如何明确判断什么是最受欢迎的约定。除了您询问的静态库与导入库的命名法之外,发布库与调试库的命名之间也存在类似的区别,尤其是在 Windows 上。
这两种情况(即静态与导入,以及调试与发布)都可以通过以下两种方式之一进行处理:不同的名称或不同的目录位置。我通常选择使用不同的名称,因为我觉得这样可以最大限度地减少以后弄错库类型的机会,特别是在安装或其他文件移动活动之后。
当我愿意时,我通常使用
foo.dll
和foo.lib
作为 Windows 上的共享库,并使用foo_static.lib
作为静态库有共享版本和静态版本。我见过其他人使用这个约定,所以它可能是“最流行的”。因此,我建议在您的表中添加以下内容:
Windows/MSVC:
然后在 cmake 中,您可以
或者
如果由于某种原因您不想使用“foo_static”作为符号库名称。
As mentioned by others, there are no standards, but there are popular conventions. I'm unsure how to unambiguously judge what is the most popular convention. In addition the nomenclature for static vs. import libraries, which you asked about, there is also an analogous distinction between the naming of Release libraries vs. Debug libraries, especially on Windows.
Both cases (i.e. static vs. import, and debug vs. release) can be handled in one of two ways: different names, or different directory locations. I usually choose to use different names, because I feel it minimizes the chance of mistaking the library type later, especially after installation or other file moving activities.
I usually use
foo.dll
andfoo.lib
for the shared library on Windows, andfoo_static.lib
for the static library, when I wish to have both shared and static versions. I have seen others use this convention, so it might be the "most popular".So I would recommend the following addition to your table:
Windows/MSVC:
Then in cmake, you could either
or
if for some reason you don't wish to use "foo_static" as the symbolic library name.
库没有标准的命名约定。传统的库名称以
lib
为前缀。许多链接器都可以选择在命令行上将lib
添加到库名称前面。静态库和动态库通常通过文件扩展名来标识;尽管这不是必需的。因此,
libmath.a
将是静态库,而libmath.so
或libmath.dll
将是动态库。常见的命名约定是将图书馆的类别附加到名称后。例如,调试静态数学库将为“libmathd.a”,或者在 Windows 中为“lib_math_debug”。有些商店还添加 Unicode 作为文件名属性。
如果需要,您可以将
_msvc
附加到库名称中,以指示该库需要或由 MSVC 创建(以区别于 GCC 和其他工具)。使用多个平台时的流行惯例是将对象和库放置在特定于平台的文件夹中。例如,./linux/
文件夹将包含适用于 Linux 的对象和库,类似的./msw/
则适用于 Microsoft Windows 平台。这是风格问题。风格问题常常被当作宗教问题来对待:它们都没有错,没有普遍的风格,它们是个人偏好。无论您选择什么系统,只要保持一致即可。
There is no standard naming convention for libraries. Traditional library names are prefixed with
lib
. Many linkers have options to prependlib
to a library name on the command line.The static and dynamic libraries are usually identified by their file extension; although this is not required. So
libmath.a
would be a static library whereaslibmath.so
orlibmath.dll
would be a dynamic library.A common naming convention is to append the category of the library to the name. For example, a debug static math library would be 'libmathd.a' or in Windows, 'lib_math_debug'. Some shops also add Unicode as a filename attribute.
If you want, you can append
_msvc
to the library name to indicate the library requires or was created by MSVC (to differentiate from GCC and other tools). A popular convention when working with multiple platforms, is to place the objects and libraries in platform specific folders. For example a./linux/
folder would contain objects and libraries for Linux and similarly./msw/
for Microsoft Windows platform.This is a style issue. Style issues are often treated like religious issues: none of them are wrong, there is no universal style, and they are an individual preference. What ever system you choose, just be consistent.
据我所知,没有真正的“标准”,至少没有大多数软件符合的标准。
我的约定是对动态和静态
.lib
进行同等命名,但如果项目碰巧同时支持静态和动态链接,则将它们放在不同的目录中。例如:要链接的库取决于库目录的选择,因此它几乎与构建过程的其余部分完全解耦(如果您使用 MSVC 的
#pragma comment(lib ,"foo.lib")
设施,并且它不会出现在链接器的导入库列表中)。我已经见过好几次了。另外,我认为基于 MSVC/Windows 的项目往往更倾向于使用单一的官方链接类型 - 静态、或动态。但这只是我个人的观察。
简而言之:
Windows/MSVC
您应该能够将这种基于目录的模式与 CMAKE 结合使用(从未使用过)。另外,我不认为这是一个“错误”。这只是缺乏标准化。如果每个人都有不同的喜好,CMAKE(恕我直言)建立伪标准是正确的做法。
As far as I know, there's no real 'standard', at least no standard most software would conform to.
My convention is to name my dynamic and static
.lib
equally, but place them in different directories if a project happens to support both static and dynamic linkage. For example:The library to link against depends on the choice of the library directories, so it's almost totally decoupled from the rest of the build process (it won't appear in-source if you use MSVC's
#pragma comment(lib,"foo.lib")
facility, and it doesn't appear in the list of import libraries for the linker).I've seen this quite a few times. Also, I think that MSVC/Windows based projects tend to stick more often with a single, official linkage type - either static, or dynamic. But that's just my personal observation.
In short:
Windows/MSVC
You should be able to use this directory-based pattern with CMAKE (never used it). Also, I don't think it's a 'bug'. It's merely lack of standardization. CMAKE does (imho) the right thing not to establish a pseudo-standard if everyone likes it differently.
正如其他人所说,Windows 上的文件命名没有单一的标准。
对于涵盖 100 个 exe、dll 和静态库的完整产品库,我们已经成功使用以下内容多年,并且它避免了很多混乱。它基本上是我多年来见过的几种方法的混合。
简而言之,我们所有的文件都有前缀和后缀(不包括扩展名本身)。它们都以“om”(基于我们公司名称)开头,然后有 1 或 2 个字符组合,大致标识代码区域。
后缀解释了它们是什么类型的内置文件,并且最多包含三个组合使用的字母,具体取决于构建,其中包括 Unicode、静态、调试(Dll 构建是默认的,没有显式后缀标识符)。当我们开始这个系统时,Unicode 还没有那么流行,我们必须支持 Unicode 和非 unicode 构建(Windows 2000 操作系统之前),现在一切都是专门构建的 unicode,但我们仍然使用相同的命名法。
因此,典型的 .lib 文件“集”可能看起来像
所有文件都内置到一个公共 bin 文件夹中,这为开发人员消除了许多 dll 地狱问题,也使调整编译器/链接器设置变得更简单 - 它们都使用相对路径指向同一位置,并且不需要手动(或自动)复制项目所需的库。拥有这些后缀还可以消除您可能拥有的文件类型的任何混乱,并保证您不会出现将调试 dll 放在发行套件上的混合情况,反之亦然。所有 exe 也使用类似的后缀 (Unicode/Debug) 并构建到相同的 bin 文件夹中。
同样有一个“include”文件夹,每个库在包含文件夹中都有一个与库/dll 名称匹配的头文件(例如 omfthread.h) 该文件本身 #includes 该文件公开的所有其他项目图书馆。如果您想要 foo.dll 中的功能,这会变得更简单,您只需 #include "foo.h";我们的库按照功能领域进行了高度细分 - 实际上我们没有任何“瑞士军刀”dll,因此包含库的整个功能是有意义的。 (每个标头还包含其他必备标头,无论它们是我们的内部库还是其他供应商 SDK)
每个包含文件内部都使用宏,这些宏使用 #pramga 将适当的库名称添加到链接器行,因此单个项目不需要关心这个。我们的大多数库都可以静态构建或作为 DLL 构建,并且 #define OM_LINK_STATIC (如果已定义)用于确定单个项目想要哪个(我们通常使用 DLL,但在某些情况下,静态库内置于 .exe 中)对于部署或其他原因更有意义)
这些宏(OMLIBNAMESTATIC 和 OMLIBNAME)使用 _DEBUG 确定它是什么类型的构建并生成正确的库名称以添加到链接器行。
我们在 static & 中使用通用定义。库的 dll 版本,用于控制 dll 构建中类/函数的正确导出。从库导出的每个类或函数都用此宏进行修饰(其名称与库的基本名称匹配,尽管这在很大程度上不重要)
在项目设置的 DLL 版本中,我们定义 OMFTHREAD_DECLARE=__declspec(dllexport),我们将 OMFTHREAD_DECLARE 定义为空的库的静态库版本。
在库头文件中,我们根据客户端尝试链接到它的方式来定义它
想要使用我们的内部库之一的典型项目只需将适当的包含添加到其 stdafx.h (通常)并且它就可以工作,如果他们需要链接到静态版本,他们只需将 OM_LINK_STATIC 添加到编译器设置中(或在 stdafx.h 中定义它),然后它就可以正常工作了。
As the others have said, there is no single standard to file naming on windows.
For our complete product base which covers 100's of exes, dlls, and static libs we have used the following successfully for many years now and it has saved a lot of confusion. Its basically a mixing of several methods I've seen used throughout the years.
In a nutshell all our files of both a prefix and suffix (not including the extension itself). They all start with "om" (based on our company name), and then have a 1 or 2 character combination that roughly identifies the area of code.
The suffix explains what type of built-file they are and includes up to three letters used in combination depending on the build which includes Unicode, Static, Debug (Dll builds are the default and have no explicit suffix identifier). When we started this system Unicode was not so prevalent and we had to support both Unicode and Non-unicode builds (pre Windows 2000 os), now everything is exclusively built unicode but we still use the same nomenclature.
So a typical .lib "set" of files might look like
All files are built-in into a common bin folder, which eliminates a lot of dll-hell issues for developers and also makes it simpler to adjust compiler/linker settings - they all point to the same location using relative paths and there is never any need for manual (or automatic) copying of the libraries a project needs. Having these suffixes also eliminates any confusion as to what type of file you may have, and guarantees you can't have a mixed scenario where you put down the debug dll on a release kit or vice-versa. All exes also use a similar suffix (Unicode/Debug) and build into the same bin folder.
There is likewise one single "include" folder, each library has one header file in the include folder that matches the name of the library/dll (for example omfthread.h) That file itself #includes all the other items that are exposed by that library. This keeps its simpler if you want functionality that is in foo.dll you just #include "foo.h"; our libraries are highly segmented by areas of functionality - effectively we don't have any "swiss-army knife" dlls so including the libraries entire functionality makes sense. (Each of these headers also include other prerequisite headers whether they be our internal libraries or other vendor SDKs)
Each of these include files internally uses macros that use #pramga's to add the appropriate library name to the linker line so individual projects don't need to be concerned with that. Most of of our libraries can be built statically or as a DLL and #define OM_LINK_STATIC (if defined) is used to determine which the individual project wants (we usually use the DLLs but in some cases static libraries built-in into the .exe make more sense for deployment or other reasons)
These macros (OMLIBNAMESTATIC & OMLIBNAME) use _DEBUG determine what type of build it is and generate the proper library name to add to the linker line.
We use a common define in the static & dll versions of a library to control proper exporting of the class/functions in dll builds. Each class or function exported from the library is decorated with this macro (the name of which matches the base name for the library, though that is largely unimportant)
In the DLL version of the project settings we define OMFTHREAD_DECLARE=__declspec(dllexport), in the static library version of the library we define OMFTHREAD_DECLARE as empty.
In the libraries header file we define it based on how the client is trying to link to it
A typical project that wants to use one of our internal libraries would just add the appropriate include to their stdafx.h (typically) and it just works, if they need to link against the static version they just add OM_LINK_STATIC to their compiler settings (or define it in the stdafx.h) and it again it just works.
据我所知,目前还没有这方面的任何约定。以下是我如何做到这一点的示例:
{Project}{SubModule}{Platform}{Architecture}{CompilerRuntime}_{BuildType}.lib/dll
完整文件名应为只能是小写,并且只能包含带有预先指定的下划线的字母数字。子模块字段(包括其前导下划线)是可选的。
项目:保存项目名称/标识符。最好尽可能短。即“dna”
子模块:可选。保存模块名称。最好尽可能短。即“dna_audio”
平台:标识编译二进制文件的平台。即“win32”(Windows)、“winrt”、“xbox”、“android”。
架构:描述编译二进制文件的架构。即“x86”、“x64”、“手臂”。当不同位数的体系结构名称相同时,使用其名称后跟位数。 IE。 “name16”、“name32”、“name64”
编译器运行时:可选。并非所有二进制文件都链接到编译器运行时,但如果链接到编译器运行时,它也会包含在此处。即“vc90”(Visual Studio 2008)、“gcc”。如果可以包含适用的公寓,即“vc90mt”
构建类型:可选。它可以容纳字母(以任何所需的顺序),每个字母都讲述一些有关构建细节的信息。 d=debug(如果发布,则省略) t=static(如果动态,则省略) 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
As far as I know there still aren't any conventions with regards to this. Here's an example of how I do it:
{Project}{SubModule}{Platform}{Architecture}{CompilerRuntime}_{BuildType}.lib/dll
The full filename shall be lowercase only and shall only contain alphanumerics with predesignated underscores. The submodule field, including its leading underscore, is optional.
Project: holds project name/identifier. Preferably as short as possible. ie "dna"
SubModule: optional. holds module name. Preferably as short as possible. ie "dna_audio"
Platform: identifies the platform the binary is compiled for. ie "win32" (Windows), "winrt", "xbox", "android".
Architecture: describes the architecture the binary is compiled for. ie "x86", "x64", "arm". There where architecture names are equal for various bitnesses use its name followed by the bitness. ie. "name16", "name32", "name64"
CompilerRuntime: optional. Not all binaries link to a compiler runtime, but if they do, it's included here. ie "vc90" (Visual Studio 2008), "gcc". Where applicable apartment can be included ie "vc90mt"
BuildType: optional. This can hold letters (in any order desired), each which tell something about the build-specifics. d=debug (omitted if release) t=static (omitted if dynamic) a=ansi (omitted if unicode)
Examples (assuming a project named "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