使用VS2008 SP1和CMake 2.8.x将多个静态.lib文件链接成一个单一的.lib文件

7
使用cmake将目标文件链接到lib.xxxx.a文件 相关,但不完全相同,我使用 CMake 2.8.x 在 Windows 上构建了几个静态库,使用的是 VS2008 SP1。是否可以仅通过 CMake 将所有现有静态库中的 .obj 文件重新链接为一个更大的单体库,最好是通过 add_library CMake 函数或其他类似结构实现?
我认为答案是否定的,因此我考虑通过自定义命令来滚动我的方法,通过通常的 add_custom_command + add_custom_target 方法,手动构建库,通过在调用 LINK.EXE 时提供所有其他库的 .obj 文件来完成。但我看到该方法存在一些问题:
  1. 我找不到一个 CMake 变量来指示 LINK.EXE 可执行文件的完全限定路径。然后,我必须使用脆弱的启发式方法来推导出 LINK.EXE 的路径:这种方法是脆弱的,因为不同的 Visual Studio 版本可能会将 LINK.EXE 文件定位在不同的目录中,而我需要它能在 32 位和 64 位 Windows 编译条件下工作,并且对 VS2008 和未来编译器修订之间的升级具有弹性。
  2. 我需要找到一种在构建时而不是在 CMake 时间找到其他静态库的所有 .obj 文件的方式,因为在 CMake 时间上,这些 .obj 文件当然不存在(并非总是存在)。出于构建性能的原因,我不想从 .lib 文件中提取 .obj 文件以便将它们添加到 LINK.EXE 命令行,所以在这种情况下,使用 FILE(GLOB...) 结构将是我的最佳备选方案。
  3. 可能可以通过简单地调用 LINK.EXE 来实现:LINK.EXE /OUT:monolithic.lib lib1.lib lib2.lib ...,但可能并不是所有的 .obj 文件都会被包含 (编辑:我已经确认 LINK.EXE 会省略来自 lib1.lib lib2.lib ... 的某些 .obj 文件,并且没有诊断消息解释为什么,因此这种方法行不通);关于使用 LINK.EXE 的这种方式的在线文档也不是很清楚。任何人有过使用 LINK.EXE 的经验吗?

谢谢,

Brent

附注:我知道如何使用CMake创建DLL,但我特别不想在此时使用DLL。

1个回答

11
创建一个带有虚拟源文件的静态库"merged",并将要合并的库添加到STATIC_LIBRARY_FLAGS中,这样它们将成为lib.exe的附加输入。示例如下:
ADD_LIBRARY(merged STATIC dummy.c)
SET_TARGET_PROPERTIES(merged PROPERTIES STATIC_LIBRARY_FLAGS "full\path\to\lib1.lib full\path\to\lib2.lib")
MySQL内部使用这种方法,这里有一个更通用的跨平台静态库合并宏。可以在这里找到http://www.mail-archive.com/cmake@cmake.org/msg28670/libutils.cmake

在 http://www.mail-archive.com/cmake@cmake.org/msg28670/libutils.cmake 链接中定义的 MERGE_STATIC_LIBS 宏非常接近我要实现的内容。警告:该链接指向一个特定于 MySQL 的文件,因此必须将其普遍化,以便在实践中可行。 - bgoodr
上述的libutils.cmake确实不能独立工作,因为它引用了可配置的merge_archives_unix.cmake.in文件。该文件可从http://www.mail-archive.com/cmake@cmake.org/msg28670/merge_archives_unix.cmake.in获取。 - Vladislav Vaintroub

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接