You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在GitHub Action的macos-12环境中用vcpkg+CMake构建C++二进制失败

问题描述

某C++项目在Linux、Windows环境下构建正常,但在GitHub Action的macos-12环境中执行构建时出现链接错误,报错信息如下:

/usr/local/bin/g++-11  -isysroot /Applications/Xcode_13.4.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/Calculator_Test.dir/src/speedtest.cpp.o CMakeFiles/Calculator_Test.dir/src/tests.cpp.o -o Calculator_Test  ../libCalculator.a ../vcpkg_installed/x64-osx/debug/lib/libCatch2d.a ../vcpkg_installed/x64-osx/debug/lib/manual-link/libCatch2Maind.a ../vcpkg_installed/x64-osx/debug/lib/libCatch2d.a 
Undefined symbols for architecture x86_64:
  "__ZN5Catch24translateActiveExceptionB5cxx11Ev", referenced from:
      __ZN5Catch9Benchmark9Benchmark3runINSt6chrono3_V212steady_clockEEEvv in speedtest.cpp.o
  "__ZN5Catch9Benchmark6Detail15analyse_samplesEdjN9__gnu_cxx17__normal_iteratorIPdSt6vectorIdSaIdEEEES8_", referenced from:
      __ZN5Catch9Benchmark6Detail7analyseINSt6chrono8durationIdSt5ratioILl1ELl1000000000EEEEN9__gnu_cxx17__normal_iteratorIPS7_St6vectorIS7_SaIS7_EEEEEENS0_14SampleAnalysisIT_EERKNS_7IConfigENS0_11EnvironmentISG_EET0_SN_ in speedtest.cpp.o

执行CMake配置命令无异常:

cmake --preset=${{ matrix.preset }} -B build -DCalculator_Test=1 -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11 -DCMAKE_VERBOSE_MAKEFILE=1

其中preset用于指定vcpkg提供的CMAKE_TOOLCHAIN_FILE和生成器为Unix Makefiles。

项目CMakeLists.txt相关配置如下:

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

...
 
find_package(Catch2 CONFIG REQUIRED)

target_link_libraries(Calculator_Test
    PRIVATE
        Calculator
        Catch2::Catch2 Catch2::Catch2WithMain
)

执行构建命令cmake --build build时失败。

问题原因与修复方案

核心原因

  1. 编译器ABI不兼容:GitHub Action的macOS环境中,vcpkg默认使用系统原生的Clang编译Catch2依赖库,但项目指定用GCC-11编译代码。Clang和GCC在C标准库的ABI(应用二进制接口)上存在差异,导致链接时无法找到匹配的符号(报错中的B5cxx11后缀是C11 ABI的标识,两者生成的符号格式不匹配)。
  2. 重复链接库:从链接命令可见libCatch2d.a被重复链接,这是CMake目标Catch2::Catch2和Catch2::Catch2WithMain间接引入的,但不是核心问题,核心还是编译器不匹配。

修复方案

方案一:统一使用Clang编译(推荐)

macOS系统默认的Clang对C++20支持完善,且vcpkg在macOS下默认用Clang构建依赖,兼容性更高。修改CMake配置命令,去掉指定GCC的参数,或明确指定Clang:

# 方式1:使用系统默认编译器(自动选择Clang)
cmake --preset=${{ matrix.preset }} -B build -DCalculator_Test=1 -DCMAKE_VERBOSE_MAKEFILE=1

# 方式2:明确指定Clang
cmake --preset=${{ matrix.preset }} -B build -DCalculator_Test=1 -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_VERBOSE_MAKEFILE=1

方案二:强制vcpkg用GCC-11构建Catch2

如果必须使用GCC,需让vcpkg用相同的GCC版本构建Catch2:

  1. 在GitHub Action的macos-12任务中,设置环境变量指定vcpkg的编译器:
    export VCPKG_C_COMPILER=gcc-11
    export VCPKG_CXX_COMPILER=g++-11
    
  2. 重新安装Catch2依赖(确保vcpkg重新编译库)。

注意:该方案在macOS下可能遇到系统库适配问题,因为GCC不是macOS原生编译器,不推荐优先使用。

与各技术点的关联

  • C++20:间接相关,C20的新特性在不同编译器实现上有差异,但核心问题是ABI不兼容,而非C20特性本身;
  • CMake:CMake的目标链接配置无错误,问题出在编译器与依赖库的匹配上;
  • vcpkg:vcpkg默认根据系统环境选择编译器,当项目指定不同编译器时,会出现依赖库与项目代码的ABI不兼容;
  • macOS特定操作:macOS默认编译器为Clang,GCC是第三方安装的,两者ABI不兼容是macOS环境特有的问题。

内容的提问来源于stack exchange,提问作者mwthinker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 18:24:25