我在 macOS 下的 CLion 中工作。我有一个使用 boost 库的项目。它是用 Homebrew 安装的。一切都工作得很好,但只有 clang 编译器。
当我尝试使用 GCC(与 Brew 一起安装)构建我的项目时,我最终得到了一堆未定义的引用:
Undefined symbols for architecture x86_64:
"__ZN5boost15program_options11to_internalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE", referenced from:
__ZN5boost15program_options11to_internalINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESt6vectorIS7_SaIS7_EERKS8_IT_SaISB_EE in options_parser.cpp.o
"__ZN5boost15program_options19options_descriptionC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjj", referenced from:
__ZN22command_line_options_tC2Ev in options_parser.cpp.o
__ZN22command_line_options_tC1Ev in options_parser.cpp.o
"__ZN5boost15program_options6detail7cmdlineC2ERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE", referenced from:
__ZN5boost15program_options25basic_command_line_parserIcEC1EiPKPKc in options_parser.cpp.o
"__ZN5boost15program_optionslsERSoRKNS0_19options_descriptionE", referenced from:
__ZN22command_line_options_t5parseEiPPc in options_parser.cpp.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
我相信这是因为这些编译器的 ABI 不同。我想解决这个问题,因为我真的需要用两个编译器来构建我的项目。我决定使用 GCC 从源代码编译 boost 的第二个版本。一切正常,我安装了 GCC 构建的 boost 到
/usr/local/boost-1.81.0
.
安装后,我尝试再次使用 GCC 编译我的项目。它失败了,因为我使用 CMake 作为构建系统,默认情况下它会发现 Homebrew 安装了 boost。
CMake代码部分:
...
find_package(Boost 1.71.0 COMPONENTS program_options system REQUIRED)
target_include_directories(${PROJECT_NAME} PRIVATE ${Boost_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} Boost::program_options Boost::system)
...
我通过在我的 CMake 配置文件中设置
BOOST_ROOT=/usr/local/boost-1.81.0/lib/cmake/Boost-1.81.0/
解决了这个问题。
现在,一切都用 gcc 编译。但是有一个主要问题。当我尝试运行我的程序时,链接器给我一个错误,指出找不到符号,请参阅:
dyld[22954]: Symbol not found: __ZN5boost15program_options11to_internalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Referenced from: <85A6D422-44D6-33CA-9638-632EA8C0103B> /Users/andrew/Documents/... (path hidden)
Expected in: <FC9A85A4-F878-30AA-AA7C-3BDE86D000BC> /usr/local/Cellar/boost/1.81.0_1/lib/libboost_program_options.dylib
我相信发生这种情况是因为它试图从安装的 Homebrew 加载 boost 动态库。我通过这条线知道这一点:
Expected in: <FC9A85A4-F878-30AA-AA7C-3BDE86D000BC> /usr/local/Cellar/boost/1.81.0_1/lib/libboost_program_options.dylib
/usr/local/Cellar/boost/1.81.0_1/
是 Homebrew 的 boost 安装路径。我试图通过将 DYLD_LIBRARY_PATH
显式设置为我的自定义 boost 安装路径来解决这个问题,该路径包含使用 GCC 构建的动态库:
export DYLD_LIBRARY_PATH=/usr/local/boost-1.81.0/lib:$DYLD_LIBRARY_PATH
再次,一切正常。
这是我的问题:因为我不想每次都设置这个环境变量,有没有解决这个问题的方法,不涉及修改 CMakeLists.txt 或显式设置
DYLD_LIBRARY_PATH
?
我试过在互联网上搜索,但没有找到有用的东西。我不明白的是为什么链接器默认在 Homebrew 安装中搜索动态库,即使 CMake 在 GCC 安装的明确指定路径中找到 boost 库并将其链接到可执行文件
target_link_libraries(${PROJECT_NAME} Boost::program_options Boost::system)
?
我真的很想在不破坏系统或修改一些环境变量的情况下让这两个编译器都能工作。这对我来说非常不方便,因为我正在检查学生的实验室并且我必须使用不同的编译器构建很多。抱歉,如果我对问题的解释或我要实现的目标有点令人困惑。无论如何请随时问我。
• Ubuntu 错误:“make: *** [Makefile:947 build-gcc-12.2.0] Error 2 / make gcc failed! Aborting”
• 无法执行任何conda命令;错误:KeyError('pkgs_dirs'),原因:找不到图像
• 无法在“窗口”上执行“openDatabase”:在非安全上下文中拒绝访问 WebDatabase API
• 为 L = {a^i b^j c^k | 提供上下文无关语法i+k > j and i, j, k ≥ 0} [关闭]
• 158A - Codeforces 问题集计数错误 [关闭]
• Eyedropper API 在本地主机上工作正常,但在我将其上传到服务器时无法正常工作
• WSO2 API Manager 在发布新服务时出现 404 错误
• 在 [int(val)] 上出现“TypeError: 'NoneType' object is not subscriptable”
• InvalidAlgorithmParameterException 在某些情况下出现,而在其他情况下则不会出现