You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何递归获取CMake依赖目标属性以收集Android APK所需共享库

解决方案

核心思路是实现一个递归收集所有依赖目标的自定义CMake函数,遍历所有依赖提取ANDROID_NATIVE_LIB_DEPENDENCIES属性后合并到顶层目标的属性中,无需使用全局属性即可适配多顶层目标场景。

首先定义通用的递归依赖收集函数,可放在顶层CMakeLists的公共配置段:

# 递归获取目标的所有链接依赖(含间接依赖)
function(get_all_dependencies TARGET OUTPUT_VAR)
    # 防止重复处理同一个目标,规避循环依赖导致的死循环
    set(VISITED_TARGETS "" CACHE INTERNAL "Visited targets for dependency collection" FORCE)

    function(_collect_deps CURRENT_TARGET)
        if(NOT TARGET ${CURRENT_TARGET} OR ${CURRENT_TARGET} IN_LIST VISITED_TARGETS)
            return()
        endif()
        list(APPEND VISITED_TARGETS ${CURRENT_TARGET})
        set(VISITED_TARGETS ${VISITED_TARGETS} CACHE INTERNAL "Visited targets for dependency collection" FORCE)

        # 获取当前目标的直接链接依赖
        get_target_property(DIRECT_DEPS ${CURRENT_TARGET} LINK_LIBRARIES)
        foreach(DEP ${DIRECT_DEPS})
            # 过滤非目标类的链接项(比如-lpthread这类系统库、生成器表达式等)
            if(TARGET ${DEP})
                _collect_deps(${DEP})
            endif()
        endforeach()
    endfunction()

    _collect_deps(${TARGET})
    # 移除目标自身,仅返回依赖列表
    list(REMOVE_ITEM VISITED_TARGETS ${TARGET})
    set(${OUTPUT_VAR} ${VISITED_TARGETS} PARENT_SCOPE)
endfunction()

在顶层应用目标的CMake配置段调用该函数即可完成属性合并:

if(ANDROID)
    # 1. 递归获取MyApp的所有依赖目标(示例中的Lib1、Lib2、Lib3都会被收集)
    get_all_dependencies(MyApp ALL_DEPS)

    # 2. 遍历所有依赖,收集ANDROID_NATIVE_LIB_DEPENDENCIES属性值
    set(ALL_NATIVE_LIBS "")
    foreach(DEP ${ALL_DEPS})
        get_target_property(DEP_LIBS ${DEP} ANDROID_NATIVE_LIB_DEPENDENCIES)
        if(DEP_LIBS)
            list(APPEND ALL_NATIVE_LIBS ${DEP_LIBS})
        endif()
    endforeach()

    # 3. 去重后赋值给顶层目标的原生依赖属性
    if(ALL_NATIVE_LIBS)
        list(REMOVE_DUPLICATES ALL_NATIVE_LIBS)
        set_target_properties(MyApp PROPERTIES ANDROID_NATIVE_LIB_DEPENDENCIES "${ALL_NATIVE_LIBS}")
    endif()
endif()

该方案优势:

  • 完美适配多顶层目标场景,每个顶层目标单独调用一次函数即可,不同目标的依赖不会互相混淆
  • 无需修改子依赖库的CMake配置,子依赖仍正常使用原生ANDROID_NATIVE_LIB_DEPENDENCIES属性即可,侵入性极低
  • 自动处理任意层级的嵌套依赖,你示例中的Lib3的属性会被正常识别收集

内容的提问来源于stack exchange,提问作者rdowell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 10:36:05