如何在CMake中通过Conan链接静态PahoMqttCpp库构建oatpp独立可执行文件
解决方案
你遇到的报错是因为默认Conan安装的paho-mqtt-cpp是动态链接库,编译出来的可执行文件运行时需要加载对应的.so文件,你的容器内没有部署这个库就会触发找不到文件的错误。要生成独立可执行文件,需要把paho-mqtt相关库改成静态链接,具体配置步骤如下:
步骤1:修改conanfile.txt配置,指定安装静态版本的paho库
paho-mqtt-cpp依赖底层的paho-mqtt-c库,两个都需要设置为不生成动态库,修改后的conanfile.txt内容如下:
[requires] paho-mqtt-cpp/1.2.0 # MQTT Client [generators] cmake [options] paho-mqtt-cpp:shared=False paho-mqtt-c:shared=False
配置完成后重新执行conan install命令拉取依赖,如果你之前已经拉取过动态版本的paho库,可以加上--build=paho-mqtt-cpp --build=paho-mqtt-c参数强制重新编译静态版本:
conan install . --build=paho-mqtt-cpp --build=paho-mqtt-c
步骤2:调整CMakeLists.txt配置
推荐使用Conan提供的包目标链接库,比全局的CONAN_LIBS更精准,同时可以添加编译参数保证标准库也静态链接,避免容器内缺少对应版本标准库的问题:
修改点如下:
- 可执行文件链接库替换为Conan的paho目标包
- 添加静态链接标准库的编译参数
- 如有需要,可强制所有依赖优先链接静态版本
修改后的CMakeLists.txt示例:
cmake_minimum_required(VERSION 3.1) set(project_name my-project) ## rename your project here project(${project_name}) set(CMAKE_CXX_STANDARD 11) # 新增:静态链接gcc和stdc++库,避免容器内标准库版本不兼容 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") # 可选:优先查找静态库而非动态库 set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".so") add_library(${project_name}-lib src/AppComponent.hpp src/controller/MyController.cpp src/controller/MyController.hpp src/dto/DTOs.hpp ) ## link libs find_package(oatpp 1.2.5 REQUIRED) target_link_libraries(${project_name}-lib PUBLIC oatpp::oatpp PUBLIC oatpp::oatpp-test ) ## conan include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup(TARGETS) target_include_directories(${project_name}-lib PUBLIC src) ## add executables add_executable(${project_name}-exe src/App.cpp test/app/MyApiTestClient.hpp) # 替换${CONAN_LIBS}为具体的paho包目标 target_link_libraries(${project_name}-exe ${project_name}-lib CONAN_PKG::paho-mqtt-cpp) add_dependencies(${project_name}-exe ${project_name}-lib) add_executable(${project_name}-test test/tests.cpp test/app/TestComponent.hpp test/app/MyApiTestClient.hpp test/MyControllerTest.cpp test/MyControllerTest.hpp ) # 替换${CONAN_LIBS}为具体的paho包目标 target_link_libraries(${project_name}-test ${project_name}-lib CONAN_PKG::paho-mqtt-cpp) add_dependencies(${project_name}-test ${project_name}-lib) set_target_properties(${project_name}-lib ${project_name}-exe ${project_name}-test PROPERTIES CXX_STANDARD 11 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON ) enable_testing() add_test(project-tests ${project_name}-test)
步骤3:验证静态链接结果
编译完成后,在Linux环境下执行ldd 可执行文件路径命令查看依赖的动态库列表,如果输出中没有libpaho-mqttcpp3.so和libpaho-mqtt3c.so相关条目,就说明静态链接成功,生成的可执行文件可以直接放到同架构容器中运行。
注意:如果你的oatpp库本身是动态编译安装的,需要先重新编译安装静态版本的oatpp(编译oatpp时添加-DBUILD_SHARED_LIBS=OFF参数),否则可执行文件还是会依赖oatpp的动态库。
内容的提问来源于stack exchange,提问作者Ajinkya Bawaskar
相关产品推荐
相关产品推荐

