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
的开发者选择静态库而不是动态库可能是有原因的。
如果您在libDependentA
和libDependentB
中都使用来自libIndependent
的符号并且您没有libIndependent
的源代码,简短的回答是您不能直接使用。静态库通常使用与共享库不同的标志/定义集构建(最明显的是导出符号 dllexport
/ dllimport
如您所述)。您可以通过def file 从libDependentA
导出一些libIndependent
符号。但通常库中只存在 dll 中使用的符号 (libDependentA
),您可能会遇到各种其他问题。
但是,您可以创建一个共享库包装器libIndependentWrapper.dll
,在其中为您需要的libIndependent
中的每个函数创建一个包装器函数。包装函数将具有带有dllexport
/ dllimport
的新标头。
【讨论】:
我已经想到了包装方法。太麻烦了。我想我应该看看我们能不能得到 .dll。以上是关于Cmake、.lib、dll 并避免在二进制文件中有多个 .lib 副本的主要内容,如果未能解决你的问题,请参考以下文章
CMAKE设置INSTALL工程,分别设置头文件Lib和DLL的输出路径