Ubuntu下CMake引入预编译CasADI库运行时符号查找错误求助
解决CasADI SX符号运行时未定义符号问题
问题根源
你遇到的_ZN6casadi6MatrixINS_6SXElemEE4_symERKSsRKNS_8SparsityE未定义符号错误,本质是你的编译环境与预编译CasADI库的C++ ABI(应用二进制接口)不匹配。即使添加了-D_GLIBCXX_USE_CXX11_ABI=0,也可能因为选项作用范围不对、预编译库本身的ABI与你指定的不一致,或GCC版本兼容性问题导致失效。
解决方案
1. 精准设置编译选项作用范围
全局add_definitions可能无法确保所有编译单元都应用ABI选项,改为针对目标设置:
将主CMakeLists中的add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)替换为:
target_compile_definitions(main PRIVATE -D_GLIBCXX_USE_CXX11_ABI=0)
这能保证你的main程序编译时强制使用旧版ABI,与预编译库保持一致。
2. 验证预编译库的ABI类型
用nm命令检查CasADI库的符号,确认其ABI版本:
nm -D ${CMAKE_BINARY_DIR}/external/external/casadi/src/casadi-3.5.5/casadi/lib/libcasadi.so | grep _ZN6casadi6MatrixINS_6SXElemEE4_sym
- 如果输出符号与报错的完全一致,说明库用旧ABI编译,继续保留
-D_GLIBCXX_USE_CXX11_ABI=0; - 如果符号名包含
__cxx11后缀,说明库用新ABI,需移除该编译选项。
3. 匹配GCC版本的CasADI部署方式
你使用的GCC 11.1.0与CasADI 3.5.5预编译包的编译环境(大概率是GCC 9及以下)差异较大,兼容性不佳,建议二选一:
- 自行编译CasADI源码:下载CasADI源码包,编译时添加
-D_GLIBCXX_USE_CXX11_ABI=0,确保与你的环境完全匹配; - 升级CasADI版本:选择3.6.x及以上版本,其对高版本GCC的支持更完善。
4. 修正CMake依赖管理逻辑
原配置中用execute_process手动构建外部项目的方式不可靠,改为CMake原生的ExternalProject依赖管理,同时避免硬编码路径:
修正后的主CMakeLists.txt
cmake_minimum_required(VERSION 3.16) project(untitled) set(CMAKE_CXX_STANDARD 17) # 引入预编译CasADI包 include(ExternalProject) ExternalProject_Add( casadi-3.5.5 URL https://github.com/casadi/casadi/releases/download/3.5.5/casadi-linux-py39-v3.5.5-64bit.tar.gz CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" PREFIX ${CMAKE_BINARY_DIR}/external/casadi ) # 构建主程序目标 add_executable(main main.cpp) target_compile_definitions(main PRIVATE -D_GLIBCXX_USE_CXX11_ABI=0) # 确保CasADI下载完成后再编译主程序 add_dependencies(main casadi-3.5.5) ExternalProject_Get_Property(casadi-3.5.5 SOURCE_DIR) find_package(casadi REQUIRED HINTS ${SOURCE_DIR}/casadi) # 链接CasADI库 target_link_libraries(main casadi)
同时可以删除单独的external/CMakeLists.txt,因为依赖管理已集成到主配置中。
测试验证
执行以下命令重新构建:
mkdir build && cd build cmake .. make ./main
此时程序应能正常创建SX符号,不再抛出未定义符号错误。
内容的提问来源于stack exchange,提问作者annieone
相关产品推荐
相关产品推荐

