嵌入式项目中如何通过CMake实现多链接库的头文件目录传递?
嵌入式C/C++项目CMake部分链接问题
需求背景
- 开发C/C++嵌入式项目,存在两个定义相同符号的已编译静态库
- 使用TI LTS1.3.0编译器,支持生成可重定位输出模块(partial linking):链接时可隐藏其他编译单元符号,输出模块无需定义所有符号,缺失部分在最终链接阶段补全
CMake构建痛点
项目基于CMake构建静态库,通过target_link_libraries管理依赖链接,当前为两个含重复符号的库生成部分链接输出模块时,遇到两个核心问题:
- 用
add_executable创建输出模块并通过target_link_libraries传入静态库时,会将所有传递依赖的静态库都编译进输出模块,不符合"仅链接指定库、缺失符号留到最终链接补全"的预期 - 无法递归获取依赖库的头文件目录:仅通过
get_target_property获取目标的INTERFACE_INCLUDE_DIRECTORIES只能拿到自身的头文件路径,无法获取其依赖库的头文件,导致编译失败
伪代码示例
# 库A的构建逻辑 function( create_libA ) add_library( libA src/A.c ) target_include_directories( libA PUBLIC /inc ) # 目录下包含A.h endfunction() # 库B的构建逻辑(依赖库A) function( create_libB LIBA ) add_library( libB src/B.c ) target_link_libraries( libB PUBLIC ${LIBA} ) target_include_directories( libB PUBLIC /inc ) # 目录下包含B.h endfunction() # 部分链接输出模块的构建:仅希望链接LIBTOBELINKEDIN,不包含libB function( build_part_module LIBB LIBTOBELINKEDIN ) add_executable( outputModuleA src/func.c ) # func.c 包含A.h # 此方式会把libA和libB都编译链接进来,不符合预期 # target_link_libraries( outputModuleA PUBLIC ${LIBB} ${LIBTOBELINKEDIN} ) # 尝试手动获取头文件,但只能拿到libB的路径,无法获取libA的,编译失败 get_target_property(libBInc ${LIBB} INTERFACE_INCLUDE_DIRECTORIES) target_include_directories(outputModuleA /inc ${libBInc}) endfunction()
额外限制
若让输出模块包含所有符号定义,虽然链接器可以处理,但由于需要将静态库放置在RAM的不同区域,必须为部分链接创建额外链接脚本,这会降低CMake的使用便捷性。目前未找到CMake原生解决方案,猜测需要递归处理依赖的方案,但缺乏相关实现经验,若target_link_libraries有类似HEADERS_ONLY的选项会更便捷。
内容的提问来源于stack exchange,提问作者NetoBF
相关产品推荐
相关产品推荐

