【发布时间】:2020-01-22 09:25:36
【问题描述】:
我正在尝试将大量代码从自定义的内部工具链迁移到 Cmake。此代码由许多共享库和一些可执行文件组成。
其中一些库是相互依赖的。我们以 Lib1 和 Lib2 为例,其中 Lib1 使用来自 Lib2 的符号,而 Lib2 使用来自 Lib1 的符号。
为了创建 Lib1 DLL,我们需要从 Lib2 导出符号,而后者又需要从 Lib1 导出符号。目前我们通过两个阶段的链接解决了这个问题,如下所述:Mutual Imports
)。这为我们提供了以下步骤:
- 创建 lib1.lib 和 lib1.exp
创建 lib2.lib 和 lib2.exp - 使用 lib1.obj 和 lib2.lib/lib2.exp 创建 lib1.DLL
使用 lib2.obj 和 lib1.lib/lib1.exp 创建 lib2.DLL
我知道这是代码异味,但代码库太大,无法尝试纠正所有这些循环。所以我想使用 Cmake 得到类似的结果。我没有从文档中找到任何方法,除了只使用自定义命令会完全违背这个工具的目的。
旧版工具链执行以下调用:
# compile sources
cl lib1\SRC\lib1help.cpp ... /Fo"build\cl\lib1.obj"
cl lib2\SRC\lib2help.cpp ... /Fo"build\cl\lib2.obj"
# create lib + exp symbols
lib /DEF build\cl\lib1.obj /OUT:build\link1\lib1.lib
lib /DEF build\cl\lib2.obj /OUT:build\link1\lib2.lib
# create mutual dependant dll using exp
link build\cl\lib1.obj build\link1\lib2.lib /DLL /OUT:build\link2\lib1.dll
link build\cl\lib2.obj build\link1\lib1.lib /DLL /OUT:build\link2\lib2.dll
到目前为止,我有以下 CmakeLists.txt:
add_library(lib2 SHARED lib2/src/lib2help.cpp)
add_library(lib1 SHARED lib1/src/lib1help.cpp)
target_include_directories(lib1 PUBLIC lib1/include/)
target_compile_definitions(lib1 PRIVATE __LIB1)
target_link_libraries(lib1 PRIVATE lib2)
target_include_directories(lib2 PUBLIC lib2/include/)
target_compile_definitions(lib2 PRIVATE __LIB2)
target_link_libraries(lib2 PRIVATE lib1)
这给了我以下结果:
[cmake] CMake Error: The inter-target dependency graph contains the following strongly connected component (cycle)
[cmake] "lib2" of type SHARED_LIBRARY
[cmake] depends on "lib1" (weak)
[cmake] "lib1" of type SHARED_LIBRARY
[cmake] depends on "lib2" (weak)
你们知道我可以使用 Cmake 实现这个的方法吗?
目前我计划只针对 Windows 系统,但与操作系统无关的系统会很棒!
谢谢
【问题讨论】:
-
为每个库创建两个目标 - 一个
SHARED和一个STATIC? -
CMake 自然不支持相互依赖的共享库。它可以帮助您完成工作流程的第 1 步和第 3 步(创建静态库和共享库),但您需要使用适当的
add_custom_command或add_custom_target手动执行第 2 步。至于与操作系统无关的方式,你几乎不能这样做。我担心linux的加载器根本不支持相互依赖的共享库。另请参阅that question。