如何使用CMake将第三方.so共享库集成到多个独立Yocto项目
问题根源
你当前定义的crypto INTERFACE库仅配置了头文件搜索路径与Boost依赖,没有关联你提供的两个预编译共享库,因此上层应用链接时不会自动链接crypto.so和crypto_ic.so,就会出现未定义符号错误。
可行解决方案
第一步:修改Lib目录下的CMakeLists.txt
调整后的完整配置如下,全程无硬编码路径,符合CMake规范:
cmake_minimum_required(VERSION 3.8) project(crypto VERSION 1.0.0 LANGUAGES CXX) include(GNUInstallDirs) find_package(Boost REQUIRED) # 创建INTERFACE封装库 add_library(crypto INTERFACE) target_link_libraries(crypto INTERFACE Boost::boost) # 配置头文件路径 target_include_directories(crypto INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/inc/> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> ) # 查找预编译的共享库,BUILD阶段从本地lib目录查找,安装后从系统默认库路径查找 if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) # 仅在当前项目作为顶层项目构建时使用本地路径查找 find_library(CRYPTO_LIB NAMES crypto PATHS ${PROJECT_SOURCE_DIR}/lib NO_DEFAULT_PATH) find_library(CRYPTO_IC_LIB NAMES crypto_ic PATHS ${PROJECT_SOURCE_DIR}/lib NO_DEFAULT_PATH) else() # 作为依赖被find_package引入时,从系统默认路径查找 find_library(CRYPTO_LIB NAMES crypto REQUIRED) find_library(CRYPTO_IC_LIB NAMES crypto_ic REQUIRED) endif() # 将共享库加到INTERFACE的链接依赖中 target_link_libraries(crypto INTERFACE ${CRYPTO_LIB} ${CRYPTO_IC_LIB} ) # 后续保留你原本的config、targets、头文件安装逻辑即可 # ... 原有安装代码
第二步:Yocto配置适配
- 在
crypto库对应的bb文件中,确保安装了头文件、CMake配置文件(即你生成的crypto-config.cmake等文件)到目标系统的${libdir}/cmake/crypto/路径下 - 在Proj1、Proj2对应的bb文件中,添加依赖声明:
DEPENDS += "crypto",保证构建顺序正确,且find_package能找到你安装的cmake配置
可选优化(更规范的CMake写法)
如果希望更严谨,可以为两个预编译库创建IMPORTED目标,后续维护更方便:
# 替换上面的find_library后直接链接的逻辑 add_library(crypto::crypto SHARED IMPORTED) set_target_properties(crypto::crypto PROPERTIES IMPORTED_LOCATION ${CRYPTO_LIB} INTERFACE_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:crypto,INTERFACE_INCLUDE_DIRECTORIES> ) add_library(crypto::crypto_ic SHARED IMPORTED) set_target_properties(crypto::crypto_ic PROPERTIES IMPORTED_LOCATION ${CRYPTO_IC_LIB} INTERFACE_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:crypto,INTERFACE_INCLUDE_DIRECTORIES> ) target_link_libraries(crypto INTERFACE crypto::crypto crypto::crypto_ic)
验证
修改完成后重新构建crypto库并安装,再编译Proj1,链接时会自动带上两个共享库,未定义引用的错误会消失。
额外提示:注意检查报错中的函数名Intialize是否为拼写错误,实际库中函数为Initialize,避免低级拼写问题导致的链接错误
内容的提问来源于stack exchange,提问作者goodman
相关产品推荐
相关产品推荐

