首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >允许Cmake中的相互依赖

允许Cmake中的相互依赖
EN

Stack Overflow用户
提问于 2019-09-21 19:04:32
回答 1查看 1.1K关注 0票数 2

我正在尝试将大量的代码从自定义内部工具链迁移到Cmake。这段代码由许多共享库和一些可执行文件组成。

其中一些库是相互依存的。让我们以Lib1和Lib2为例,其中Lib1使用Lib2的符号,Lib2使用Lib1的符号。

为了创建Lib1动态链接库,我们需要从Lib2导出符号,而后者又需要从Lib1导出符号。目前,我们通过分两个阶段链接来解决这个问题,如下所述:相互进口)。这给了我们以下步骤:

  1. 创建lib1.lib和lib1.exp 创建lib2.lib和lib2.exp
  2. 使用lib1.obj和lib2.lib/lib2.exp创建lib1.DLL 使用lib2.obj和lib1.lib/lib1.exp创建lib2.DLL

我知道这是一种代码味道,但是代码库太大了,无法尝试纠正所有这些循环。所以我想用Cmake得到一个类似的结果。我没有从文档中找到任何方法来做到这一点,除了使用完全不符合此工具目的的自定义命令之外。

遗留工具链执行以下调用:

代码语言:javascript
复制
# 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:

代码语言:javascript
复制
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)

这给了我以下结果:

代码语言:javascript
复制
[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系统,但操作系统不可知论将是很棒的!

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-22 10:27:50

我非常专注于创建一个共享库,所以我没有探索STATIC+SHARED的方法。感谢@arrowd@tsyvaref的建议。

我使用下面的CmakeLists.txt让它工作

代码语言:javascript
复制
add_library(lib1_obj OBJECT src/lib1help.cpp)
target_include_directories(lib1_obj PUBLIC include/)
target_include_directories(lib1_obj PRIVATE $<TARGET_PROPERTY:lib2_obj,INCLUDE_DIRECTORIES>)
target_compile_definitions(lib1_obj PRIVATE __LIB1)

add_library(lib1_static STATIC $<TARGET_OBJECTS:lib1_obj>)
target_link_libraries(lib1_static PUBLIC lib2_static)
set_target_properties(lib1_static PROPERTIES STATIC_LIBRARY_OPTIONS "/DEF") 
set_target_properties(lib1_static PROPERTIES OUTPUT_NAME lib1)

add_library(lib1_shared SHARED $<TARGET_OBJECTS:lib1_obj>)
target_link_libraries(lib1_shared PRIVATE lib1_static)
set_target_properties(lib1_shared PROPERTIES RUNTIME_OUTPUT_NAME lib1)

add_library(lib1 ALIAS lib1_shared) 

完全相同的文件用于lib2,当然,除了交换名称之外。我不确定这是最好的方法,但我现在已经足够高兴了。下面是正在发生的事情:

  • 将源代码编译到对象库中
  • 将相互依赖项库链接为静态库,并使用"/DEF“创建导出文件
  • 重命名静态库输出,以方便它们用于链接器。
  • 使用预先创建的.obj、.lib和.exp链接共享库
  • 将共享库dll重命名为更容易使用

在这里,我们可以使用依赖沃克查看每个DLL的内容:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58043280

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档