使用 MSVC 生成混合静态库
Producing a hybrid static library with MSVC
据我了解,Visual Studio 库项目在编译后使用两个单独的进程,具体取决于 "General/Configuration type" 设置:
如果选择 "static library",所有目标文件将捆绑在一起成为最终的 .lib
文件,一个 静态库 .
如果选择 "dynamic library",所有目标文件连同依赖项一起链接在一起,并捆绑到最终的 .dll
文件中,一个 动态库。同时,将所有的__declspec(dllexport)
符号收集起来,用于生成一个.lib
文件,导入库.
我想创建一个 foo.lib
/foo.dll
对,其中 foo.lib
是 foo.dll
和 [=67 的导入库=] 一个独立的静态库。我考虑了以下线索:
创建两个单独的项目,FooLib
和 FooDll
,以及 use lib.exe
in a post-build step to merge both .lib
files。这听起来像是最简单的选择,但需要将本来应该是一个有凝聚力的模块分成两半。
创建单个DLL项目,让默认构建进程创建foo.dll
及其导入库。然后添加自定义构建步骤以手动收集目标文件并使用 lib 将它们捆绑到导入库中。这听起来很乱,我不确定重复项会做什么。
我试过弄乱 .def
文件,但即使在 dumpbin
生成的 lib 文件之后,我还是对其行为感到有些困惑。此外,它需要一个明确的错位符号列表,这是不切实际的。
是否有更简单的方法来实现混合 .lib
/.dll
组合?否则,我应该遵循哪条线索?
背景
该模块将在多个 .dll
和一个 .exe
链接在一起时使用。我需要在运行时的结果进程中有一半数据的单个实例(这是通过 .dll
实现的,因为它只会加载一次),而另一半被复制到每个 .dll
或 exe
并在其中初始化(由 .lib
实现)。
据我所知,您不能为此创建单个 .lib,但是您可以使用 msvc 的 #pragma comment(lib, ) 来实现几乎相同的事情,您只需拥有多个 #pragma comment( lib, ) 一个用于动态 .lib,一个用于静态。
我终于走上了我在问题中列出的第一条路线:创建两个项目,一个静态库和一个动态库,并合并它们的输出。这最终比预期的要容易:我只需要将 DLL 的导入库注册为静态库的 "Librarian" 构建步骤的依赖项,并设置项目引用以获得正确的构建顺序。
FooDll.vcxproj
:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- snip snip snip -->
<PropertyGroup>
<TargetName>Foo</TargetName>
</PropertyGroup>
<ItemDefinitionGroup>
<Link>
<ImportLibrary>$(OutDir)FooDll.lib</ImportLibrary>
</Link>
</ItemDefinitionGroup>
<!-- snip snip -->
</Project>
Foo.vcxproj
:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- snip snip snip -->
<ItemDefinitionGroup>
<Lib>
<AdditionalDependencies>$(OutDir)FooDll.lib;$(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<!-- snip snip -->
<ItemGroup>
<ProjectReference Include="..\FooDll\FooDll.vcxproj" />
</ItemGroup>
<!-- snip -->
</Project>
最终结果是 Foo.dll
/Foo.lib
对,后者既是独立的静态库又是 Foo.dll
.
的导入库
我仍然需要跨越两个项目,但这很简单,我很满意。
据我了解,Visual Studio 库项目在编译后使用两个单独的进程,具体取决于 "General/Configuration type" 设置:
如果选择 "static library",所有目标文件将捆绑在一起成为最终的
.lib
文件,一个 静态库 .如果选择 "dynamic library",所有目标文件连同依赖项一起链接在一起,并捆绑到最终的
.dll
文件中,一个 动态库。同时,将所有的__declspec(dllexport)
符号收集起来,用于生成一个.lib
文件,导入库.
我想创建一个 foo.lib
/foo.dll
对,其中 foo.lib
是 foo.dll
和 [=67 的导入库=] 一个独立的静态库。我考虑了以下线索:
创建两个单独的项目,
FooLib
和FooDll
,以及 uselib.exe
in a post-build step to merge both.lib
files。这听起来像是最简单的选择,但需要将本来应该是一个有凝聚力的模块分成两半。创建单个DLL项目,让默认构建进程创建
foo.dll
及其导入库。然后添加自定义构建步骤以手动收集目标文件并使用 lib 将它们捆绑到导入库中。这听起来很乱,我不确定重复项会做什么。我试过弄乱
.def
文件,但即使在dumpbin
生成的 lib 文件之后,我还是对其行为感到有些困惑。此外,它需要一个明确的错位符号列表,这是不切实际的。
是否有更简单的方法来实现混合 .lib
/.dll
组合?否则,我应该遵循哪条线索?
背景
该模块将在多个 .dll
和一个 .exe
链接在一起时使用。我需要在运行时的结果进程中有一半数据的单个实例(这是通过 .dll
实现的,因为它只会加载一次),而另一半被复制到每个 .dll
或 exe
并在其中初始化(由 .lib
实现)。
据我所知,您不能为此创建单个 .lib,但是您可以使用 msvc 的 #pragma comment(lib, ) 来实现几乎相同的事情,您只需拥有多个 #pragma comment( lib, ) 一个用于动态 .lib,一个用于静态。
我终于走上了我在问题中列出的第一条路线:创建两个项目,一个静态库和一个动态库,并合并它们的输出。这最终比预期的要容易:我只需要将 DLL 的导入库注册为静态库的 "Librarian" 构建步骤的依赖项,并设置项目引用以获得正确的构建顺序。
FooDll.vcxproj
:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- snip snip snip -->
<PropertyGroup>
<TargetName>Foo</TargetName>
</PropertyGroup>
<ItemDefinitionGroup>
<Link>
<ImportLibrary>$(OutDir)FooDll.lib</ImportLibrary>
</Link>
</ItemDefinitionGroup>
<!-- snip snip -->
</Project>
Foo.vcxproj
:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- snip snip snip -->
<ItemDefinitionGroup>
<Lib>
<AdditionalDependencies>$(OutDir)FooDll.lib;$(AdditionalDependencies)</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<!-- snip snip -->
<ItemGroup>
<ProjectReference Include="..\FooDll\FooDll.vcxproj" />
</ItemGroup>
<!-- snip -->
</Project>
最终结果是 Foo.dll
/Foo.lib
对,后者既是独立的静态库又是 Foo.dll
.
我仍然需要跨越两个项目,但这很简单,我很满意。