如何在CMake中链接自行编译的libgpiod C++绑定库
解决libgpiod C++绑定库的自包含构建与链接问题
我需要把libgpiod的C++绑定库链接到项目里,研究了好几天都没搞定。希望把这个仓库作为子模块引入,构建后和项目链接,这样生成的二进制文件(包括模块的二进制)能移植到没网的目标设备上。现在虽然能下载预编译包,但更想实现自包含构建。
项目结构
dependencies/ ├─ libgpiod/ CMakeLists.txt main.cpp
原CMake配置
cmake_minimum_required(VERSION 3.16.3) project(my_project VERSION 0.1.0) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(GPIOD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libgpiod) set(GPIOD_BIN ${CMAKE_CURRENT_BINARY_DIR}/dependencies/libgpiod) set(GPIOD_LIB_DIR ${GPIOD_BIN}/lib) set(GPIOD_INCLUDE_DIR ${GPIOD_BIN}/include) ExternalProject_Add(libgpiod-project PREFIX ${GPIOD_BIN} SOURCE_DIR ${GPIOD_DIR} CONFIGURE_COMMAND ${GPIOD_DIR}/autogen.sh --enable-tools=no --prefix=${GPIOD_BIN} --enable-bindings-cxx BUILD_COMMAND make && make install # INSTALL_COMMAND make install BUILD_BYPRODUCTS ${GPIOD_LIB_DIR}/libgpiodcxx.so ) add_executable(my_project main.cpp) target_link_libraries(my_project PRIVATE # todo what to link against? )
解决方案
关键修改点
- 让可执行文件依赖libgpiod的构建目标,确保编译顺序正确
- 明确指定libgpiod的头文件搜索路径
- 同时链接C++绑定库
libgpiodcxx及其依赖的底层C库libgpiod - 通过导入库目标让CMake更好地管理依赖关系
修改后的完整CMakeLists.txt
cmake_minimum_required(VERSION 3.16.3) project(my_project VERSION 0.1.0) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(GPIOD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libgpiod) set(GPIOD_BIN ${CMAKE_CURRENT_BINARY_DIR}/dependencies/libgpiod) set(GPIOD_LIB_DIR ${GPIOD_BIN}/lib) set(GPIOD_INCLUDE_DIR ${GPIOD_BIN}/include) ExternalProject_Add(libgpiod-project PREFIX ${GPIOD_BIN} SOURCE_DIR ${GPIOD_DIR} CONFIGURE_COMMAND ${GPIOD_DIR}/autogen.sh --enable-tools=no --prefix=${GPIOD_BIN} --enable-bindings-cxx BUILD_COMMAND make INSTALL_COMMAND make install BUILD_BYPRODUCTS ${GPIOD_LIB_DIR}/libgpiod.so ${GPIOD_LIB_DIR}/libgpiodcxx.so ) # 创建导入库目标,统一管理库文件 add_library(libgpiod SHARED IMPORTED) add_library(libgpiodcxx SHARED IMPORTED) # 设置导入库的属性 set_target_properties(libgpiod PROPERTIES IMPORTED_LOCATION ${GPIOD_LIB_DIR}/libgpiod.so INTERFACE_INCLUDE_DIRECTORIES ${GPIOD_INCLUDE_DIR} ) set_target_properties(libgpiodcxx PROPERTIES IMPORTED_LOCATION ${GPIOD_LIB_DIR}/libgpiodcxx.so INTERFACE_INCLUDE_DIRECTORIES ${GPIOD_INCLUDE_DIR} INTERFACE_LINK_LIBRARIES libgpiod ) # 确保导入库在libgpiod构建完成后再被使用 add_dependencies(libgpiod libgpiod-project) add_dependencies(libgpiodcxx libgpiod-project) add_executable(my_project main.cpp) # 链接C++绑定库 target_link_libraries(my_project PRIVATE libgpiodcxx)
额外说明
- 自包含构建验证:构建完成后,
${GPIOD_BIN}目录下会生成完整的头文件和库文件。移植到目标设备时,需要将libgpiod.so和libgpiodcxx.so复制到设备的系统库路径(如/usr/lib),或者通过LD_LIBRARY_PATH环境变量指定库的所在目录。 - 交叉编译适配:如果需要针对嵌入式设备交叉编译,需在
CONFIGURE_COMMAND中添加交叉编译工具链参数,例如--host=arm-linux-gnueabihf,确保生成对应架构的库文件。
内容的提问来源于stack exchange,提问作者Moritz
相关产品推荐
相关产品推荐

