Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cmake 外部库依赖关系层次结构_Cmake - Fatal编程技术网

Cmake 外部库依赖关系层次结构

Cmake 外部库依赖关系层次结构,cmake,Cmake,我正在构建一个依赖于第三方库的项目,该库由相当多的库组成。这些库之间的依赖关系的DAG是明确定义的,例如,字母表示库,箭头表示依赖关系 x -> a, b y -> a, c z -> x, b // note I don't need to specify a here as it is implied by x 所以我真正想要的是能够用CMake表达这个DAG,并且能够不重复地扩展依赖关系。所以 Expand( y, z ) -> y, z, x, a, b,

我正在构建一个依赖于第三方库的项目,该库由相当多的库组成。这些库之间的依赖关系的DAG是明确定义的,例如,字母表示库,箭头表示依赖关系

x -> a, b
y -> a, c
z -> x, b   // note I don't need to specify a here as it is implied by x
所以我真正想要的是能够用CMake表达这个DAG,并且能够不重复地扩展依赖关系。所以

Expand( y, z ) -> y, z, x, a, b, c    // Note only one a
我不会再尝试扩展函数了,因为我不能想出任何优雅的东西,我不太擅长CMake

另外一个特性是检测顶级依赖项中的冗余,以便

Expand( z, x )  // x not needed as z depends on it

注意:CMake已经对内部项目库依赖项执行类似的操作,并在目标链接库中使用它,但这些库是外部的,因此CMake不知道外部依赖项树。

正如我从CMake文档中了解的那样,
target\u link\u库
不能将导入的库作为第一个参数使用。但您可以轻松地开发函数,该函数从依赖(导入)库中读取属性,并为依赖(导入)库填充相应的属性。因此,结果导入的库可以与右侧的
target\u link\u库一起使用

# _combine_targets_property(VAR PROP target1 target2 ...)
# Helper function: Collects @PROP properties (as lists) from @target1, @target2 ..,
# combines these lists into one and store into variable @VAR.
function(_combine_targets_property VAR PROP)
    set(values) # Resulted list
    foreach(t ${ARGN})
        get_property(v TARGET ${t} PROPERTY ${PROP})
        list(APPEND values ${v})
    endforeach()
    set(${VAR} ${values} PARENT_SCOPE)
endfunction()

# imported_link_libraries(t_dest target1 target2 ...)
# Make imported library target @t_dest effectively linked with @target1, @target2 ...
function(imported_link_libraries t_dest)
    # IMPORTED_LOCATION's and INTERFACE_LINK_LIBRARIES's from dependencies
    # should be appended to target's INTERFACE_LINK_LIBRARIES.
    get_property(v1 TARGET ${t_dest} PROPERTY INTERFACE_LINK_LIBRARIES)
    _combine_targets_property(v2 IMPORTED_LOCATION ${ARGN})
    _combine_targets_property(v3 INTERFACE_LINK_LIBRARIES ${ARGN})
    set(v ${v1} ${v2} ${v3})
    list(REMOVE_DUPLICATES v)
    set_property(TARGET ${t_dest} PROPERTY INTERFACE_LINK_LIBRARIES ${v})

    # INTERFACE_INCLUDE_DIRECTORIES' from dependencies
    # should be appended to corresponded target's property.
    get_property(v1 TARGET ${t_dest} PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
    _combine_targets_property(v2 INTERFACE_INCLUDE_DIRECTORIES ${ARGN})
    set(v ${v1} ${v2})
    list(REMOVE_DUPLICATES v)
    set_property(TARGET ${t_dest} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${v})

    # Process other interface properties if needed. E.g., INTERFACE_COMPILE_DEFINITIONS.
    ...
endfunction()
用法示例:

add_library(a IMPORTED)
set_target_properties(a IMPORTED_LOCATION <a_lib> INCLUDE_DIRECTORIES <a_include_dirs>)

add_library(b IMPORTED)
set_target_properties(b IMPORTED_LOCATION <b_lib> INCLUDE_DIRECTORIES <b_include_dirs>)

add_library(x IMPORTED)
set_target_properties(x IMPORTED_LOCATION <x_lib> INCLUDE_DIRECTORIES <x_include_dirs>)

imported_link_libraries(x a b)

add_executable(my_exec ...)
target_link_libraries(my_exec x)
add_库(导入的)
设置\u目标\u属性(导入的\u位置包括\u目录)
添加库(b导入)
设置\u目标\u属性(b导入的\u位置包括\u目录)
添加_库(x导入)
设置\u目标\u属性(x导入的\u位置包括\u目录)
导入的链接库(x a b)
添加可执行文件(我的可执行文件…)
目标链接库(我的exec x)
请注意,导入的目标名称不会在依赖项中跟踪,这类似于
target\u link\u libraries()
行为。此外,不会检测到重复(但会自动删除重复项)。这两个特性对于CMake来说都不是天生的,但如果您愿意,可以实现它们