Cmake、.lib、dll 并避免在二进制文件中有多个 .lib 副本

Posted

技术标签:

【中文标题】Cmake、.lib、dll 并避免在二进制文件中有多个 .lib 副本【英文标题】:Cmake, .lib, dll and avoiding multiple .lib copies inside binary 【发布时间】:2014-04-04 04:20:16 【问题描述】:

总而言之,我想要避免在多个 .dll 中出现重复的 .lib 文件,因为生成的 .dll 将在 .exe 文件中一起使用,这使得 .lib 文件中的全局状态重复。

具体问题

我有一个包含 3 个库和一个 .exe 的项目:

libDependentA.dll libDependentB.dll libIndependent.lib -- 静态库

依赖如下:

libDependentA.dll -- 依赖于-> libIndependent.lib libDependentB.dll -- 依赖于-> libIndependent.lib

我有一个 .exe。依赖于 libDependentA.dll 和 libDependentB.dll

这会将我的 .lib 的两个副本复制到 .exe 中,这就是导致问题的原因。

解决方案?

首选解决方案。不知道是否可能,当谷歌搜索没有信息时。

libIndependent.lib 中创建一个 .dll。我怎样才能做到这一点?我无法通过add_libary(newdllfromlib SHARED) 在cmake 中的.lib 文件中创建一个dll。它没有源文件依赖项,我尝试将target_link_libraries 放入 newdllfromlib。有没有不使用空源文件或其他技巧的简单方法?

使libDependentB.dll 仅依赖于libDependentA.dll 并从libDependentB.dll 中删除libIndependent.lib。我怎么能在cmake中做到这一点?这里的问题似乎是 cmake 传递到所有其他地方libIndependent.lib,包括 .exe,如果它出现在target_link_libraries(libDependentA... 中。如果我添加LINK_PRIVATE,那么我无法在cmake 中设置我想要的配置,因为我必须再次将libIndependent.lib 链接到libDependentB.dll。无论如何要这样做?

【问题讨论】:

你有libIndependent.lib的源文件吗? 只是标题。我现在就在上面,但是,无论如何,我怎么能 dllexport 符号?无论如何,我不应该更改源头代码。 如何将所有静态库包装到一个 dll 中,例如调用 core.dll,然后让所有 dll 与 core.dll 链接? @Andre 静态库没有 dllexported(标头不包含符号导出)。这行得通吗?实际上有哪些众所周知的方法可以避免链接到 .dll 的 .lib 文件中出现重复符号? 不,这行不通,这就是为什么我以评论而不是答案的形式回复。但是你可以在你的 core.dll 中创建一个 dllexported “passthrough wrapper”。 【参考方案1】:

从链接的静态库中复制 .dll 中的符号是静态库应该做的。如果静态库libIndependent 是第三方代码,那么libIndependent 的开发者选择静态库而不是动态库可能是有原因的。

如果您在libDependentAlibDependentB 中都使用来自libIndependent 的符号并且您没有libIndependent 的源代码,简短的回答是您不能直接使用。静态库通常使用与共享库不同的标志/定义集构建(最明显的是导出符号 dllexport / dllimport 如您所述)。您可以通过def file 从libDependentA 导出一些libIndependent 符号。但通常库中只存在 dll 中使用的符号 (libDependentA),您可能会遇到各种其他问题。

但是,您可以创建一个共享库包装器libIndependentWrapper.dll,在其中为您需要的libIndependent 中的每个函数创建一个包装器函数。包装函数将具有带有dllexport / dllimport 的新标头。

【讨论】:

我已经想到了包装方法。太麻烦了。我想我应该看看我们能不能得到 .dll。

以上是关于Cmake、.lib、dll 并避免在二进制文件中有多个 .lib 副本的主要内容,如果未能解决你的问题,请参考以下文章

CMAKE设置INSTALL工程,分别设置头文件Lib和DLL的输出路径

VS2019+cmake 方式添加ffmpeg库文件,cmake添加lib文件dll文件,包含目录示例

如何在 CMake 项目中使用外部 DLL

Cygwin下用CMake编译库

Mac平台 使用CMake编译iOS lib

windows下cmake生成动态链接库dll