OR-tools编译链接问题:自定义CMakeLists.txt如何正确配置?
问题描述
我尝试使用下载的OR-tools二进制包进行编译,该包的测试运行正常。此外,官方cmake_or-tools框架在我的系统上可正常编译,但它强制使用不支持OpenMP的AppleClang。
当编写自定义CMakeLists.txt时,我遇到了无法解释的链接错误,例如下面的符号引用问题,请问如何正确地与OR-tools进行编译和链接?我可以提供更多链接器输出信息。
我的CMakeLists.txt内容如下:
cmake_minimum_required(VERSION 3.21) project(weights) # Build OR-tools dependencies. set(BUILD_DEPS ON) # Disable SCIP solver. set(USE_SCIP OFF) set(CMAKE_CXX_STANDARD 17) if(UNIX) option(BUILD_SHARED_LIBS "Build shared libraries(.so)." ON) else() # only support for static build on Windows. set(BUILD_SHARED_LIBS OFF) endif() if(BUILD_SHARED_LIBS) set(CMAKE_POSITION_INDEPENDENT_CODE ON) endif() find_package(Eigen3 REQUIRED) find_package(OpenMP REQUIRED) find_package (ortools PATHS "/Users/jerome/CLionProjects/glop" NO_DEFAULT_PATH REQUIRED CONFIG) add_executable(weights main.cpp) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gdwarf-3") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -gdwarf-3") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH True) target_include_directories(weights PRIVATE ${EIGEN3_INCLUDE_DIR}) target_include_directories(weights PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_compile_features(weights PUBLIC $<IF:$<CXX_COMPILER_ID:MSVC>,cxx_std_20,cxx_std_17>) target_link_libraries(weights OpenMP::OpenMP_CXX ortools::ortools)
遇到的链接错误示例:
"__ZN19operations_research8MPSolver10MakeNumVarEddRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE", referenced from: __ZN19operations_research12BasicExampleEv in main.cpp.o
解决方法
这个链接错误的核心原因是C++标准库ABI(应用二进制接口)不兼容:OR-tools二进制包编译时使用的C++标准库ABI版本,和你的项目当前使用的ABI版本不一致,导致符号名称不匹配(错误信息中的std::__cxx11::basic_string就是明显标识)。
以下是具体的解决步骤:
- 统一ABI版本:如果OR-tools是用旧版ABI编译的,在你的CMakeLists.txt中给目标添加编译定义,强制使用旧版ABI:
如果OR-tools用的是新版ABI,则确保项目中没有手动设置target_compile_definitions(weights PRIVATE _GLIBCXX_USE_CXX11_ABI=0)_GLIBCXX_USE_CXX11_ABI=0。 - 对齐C标准:确认OR-tools二进制包编译时使用的C标准版本,和你的项目设置的
CMAKE_CXX_STANDARD一致。如果OR-tools用的是C++14,就把项目的CMAKE_CXX_STANDARD改成14。 - 统一编译器:OR-tools二进制包如果是用GCC编译的,你的项目也应该使用GCC(而非AppleClang)。AppleClang和GCC的标准库ABI存在差异,容易导致链接错误。如果需要OpenMP支持,可以通过Homebrew安装GCC,然后在CMake中指定编译器:
set(CMAKE_C_COMPILER /usr/local/bin/gcc-13) set(CMAKE_CXX_COMPILER /usr/local/bin/g++-13) - 修正OR-tools路径:当前
find_package指向的是源码目录/Users/jerome/CLionProjects/glop,应该改为OR-tools编译后的安装目录(比如build/install路径),确保CMake能找到正确的配置文件和库文件。 - 清理无效配置:
BUILD_DEPS变量是编译OR-tools源码时的选项,你用的是预编译二进制包,这个变量可以直接删除,避免混淆。
内容的提问来源于stack exchange,提问作者KeynesCoeFen
相关产品推荐
相关产品推荐

