如何处理CMake中的递归依赖项 [英] How do you handle recursive dependencies in CMake

查看:84
本文介绍了如何处理CMake中的递归依赖项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有软件包A,B和C.软件包B使用软件包A,软件包C使用软件包B.我创建共享库.

Say I have packages A, B, and C. Package B uses package A and package C uses package B. I create shared libraries.

所以在程序包B中,我做类似的事情

So in package B I do something like

    find_package(A)
    ...
    if(${A_FOUND})
    target_link_libraries(B ${A_LIBRARIES})
    endif()

我在C包中做

    find_package(B)
    ...
    if(${B_FOUND})
    target_link_libraries(C ${B_LIBRARIES})
    endif()

    add_executable(main main.cpp)
    target_link_libraries(main C)

其中$ {B_LIBRARIES}仅包含B.编译器现在会抱怨

where ${B_LIBRARIES} contains only B. The compiler will now complain

    /usr/bin/ld: cannot find -lA
    collect2: error: ld returned 1 exit status

只要将A安装在C的link_directories之外的地方,我想知道什么是正确的处理方法.对我来说,在C中使用 find_package(A)(可能有效)似乎不太好.特别是对我来说,因为我事先不知道B是否依赖A.它还可能取决于其他程序包.

as long as A is installed in a place that is not in the link_directories of C. I was wondering what is the correct way of handling this. For me using find_package(A) in C (which would work) doesn't seem to be the nice. For me especially, because I don't know in advance if B depends on A or not. It might also depend on a different package.

推荐答案

此处的问题是 $ {A_LIBRARIES} 应该包含绝对路径.诸如Trilinos之类的软件包提供了 $ {Trilinos_LIBRARY_DIRS} 之类的东西,您应该通过这样做将其包括在内

The problem here is that ${A_LIBRARIES} should contain absolute paths. Packages like Trilinos provide something like ${Trilinos_LIBRARY_DIRS}, which you should include in by doing

link_directories(${Trilinos_LIBRARY_DIRS})

但是,根据 https://cmake,这是错误的.org/cmake/help/v3.0/command/link_directories.html . find_package(Trilinos)应该返回库的绝对路径,因此我不必这样做.我通过做类似的事情来解决了这个问题

This, however, is wrong according to https://cmake.org/cmake/help/v3.0/command/link_directories.html . find_package(Trilinos) should return absolute paths to the libraries, so I should not have to do this. I fixed this by doing something like

set(library_directories ${Trilinos_LIBRARY_DIRS})
list(APPEND library_directories ${Trilinos_TPL_LIBRARY_DIRS})

set(library_dependencies ${Trilinos_LIBRARIES})
list(APPEND library_dependencies ${Trilinos_TPL_LIBRARIES})

set(found_library_dependencies)
foreach(lib ${library_dependencies})
  set(found_${lib})
  if(IS_ABSOLUTE ${lib})
    set(found_${lib} ${lib})
  else()
    find_library(found_${lib} ${lib} ${library_directories})
  endif()
  list(APPEND found_library_dependencies ${found_${lib}})
  message(STATUS "Using ${lib}")
  message(STATUS "Found in ${found_${lib}}")
endforeach(lib)

我在这里列出了软件包的列表,因此我可以对所有从Trilinos复制了此错误行为的软件包进行此操作.

I made a list of the packages here so I can do this for all my packages which all copied this wrong behaviour from Trilinos.

回到原来的问题.我仍然必须在 $ {B_INCLUDE_DIRS} 中包含 $ {A_INCLUDE_DIRS} ,因此 C 可以找到 A的头文件包含在 B 的头文件中,但是我可以接受.但是, $ {B_LIBRARIES} 现在不必包含 $ {A_LIBRARIES} ,因为它们是作为共享库构建的.而这正是我想要的.

Coming back on the original problem. I do still have to include the ${A_INCLUDE_DIRS} in ${B_INCLUDE_DIRS}, so C can find the header files of A that are included in header files of B, but I can live with this. However, ${B_LIBRARIES} now does not have to include ${A_LIBRARIES}, since they were built as shared libraries. And that is exactly what I was looking for.

这篇关于如何处理CMake中的递归依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆