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

使用vcpkg+Emscripten编译WASM时find_package(spdlog)失败

WASM交叉编译spdlog时CMake兼容性检查失败问题

问题场景

项目基于以下配置开发:

CMakeLists.txt:

cmake_minimum_required(VERSION 3.14)

include(FetchContent)
FetchContent_Declare(vcpkg GIT_REPOSITORY https://github.com/microsoft/vcpkg/ GIT_TAG 2022.09.27)
FetchContent_MakeAvailable(vcpkg)
set(CMAKE_TOOLCHAIN_FILE "${vcpkg_SOURCE_DIR}/scripts/buildsystems/vcpkg.cmake" CACHE FILEPATH "")

project(MyProject)

set(CMAKE_CXX_STANDARD 20)

find_package(spdlog CONFIG REQUIRED)

add_executable(${CMAKE_PROJECT_NAME} src/main.cpp)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE spdlog::spdlog)

vcpkg.json:

{
    "name": "main",
    "version-string": "latest",
    "dependencies": [
        "spdlog"
    ]
}

原生环境下项目可正常构建运行,但添加-DVCPKG_TARGET_TRIPLET=wasm32-emscripten参数(已正确配置EMSDK环境变量)进行WASM交叉编译时,构建配置失败,报错如下:

CMake Error at cmake-build-release-wasm/_deps/vcpkg-src/scripts/buildsystems/vcpkg.cmake:829 (_find_package):
  Could not find a configuration file for package "spdlog" that is compatible
  with requested version "".

  The following configuration files were considered but not accepted:

    C:/Users/kiv/Projects/MyProject/cmake-build-release-wasm/vcpkg_installed/wasm32-emscripten/share/spdlog/spdlogConfig.cmake, version: 1.10.0 (32bit)

排查过程

网上资料显示这类错误通常是库版本不兼容(比如交叉编译误用系统库),但本次案例并非如此。

检查cmake-build-release-wasm\vcpkg_installed\wasm32-emscripten\lib\libspdlog.a,解压出spdlog.cpp.o后用Linuxfile工具查看:

$ file spdlog.cpp.o
spdlog.cpp.o: WebAssembly (wasm) binary module version 0x1 (MVP)

确认该库确实是针对WASM目标编译的,理论上可以正常使用。尝试在find_package中指定版本参数(如1.10.0 (32bit)或1.10.0),均无法解决问题。

问题根源

定位到兼容性检查的代码位于vcpkg_installed/wasm32-emscripten/share/spdlog/spdlogConfigVersion.cmake:

...
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "4" STREQUAL "")
  return()
endif()

# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "4")
  math(EXPR installedBits "4 * 8")
  set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
  set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()

在find_package前添加message("${CMAKE_SIZEOF_VOID_P}"),CMake输出为8,说明CMAKE_SIZEOF_VOID_P取的是主机系统(64位)的值,而非目标WASM平台(32位)的值,导致兼容性检查不通过。

解决方案

方案1:提前设置目标平台指针大小

在project指令前,针对wasm32-emscripten triplet强制设置CMAKE_SIZEOF_VOID_P为4,确保CMake使用目标平台的指针大小进行兼容性检查:

cmake_minimum_required(VERSION 3.14)

include(FetchContent)
FetchContent_Declare(vcpkg GIT_REPOSITORY https://github.com/microsoft/vcpkg/ GIT_TAG 2022.09.27)
FetchContent_MakeAvailable(vcpkg)
set(CMAKE_TOOLCHAIN_FILE "${vcpkg_SOURCE_DIR}/scripts/buildsystems/vcpkg.cmake" CACHE FILEPATH "")

# 针对wasm32平台强制设置指针大小
if(VCPKG_TARGET_TRIPLET STREQUAL "wasm32-emscripten")
  set(CMAKE_SIZEOF_VOID_P 4 CACHE INTERNAL "Size of void* for wasm32 architecture")
endif()

project(MyProject)

set(CMAKE_CXX_STANDARD 20)

find_package(spdlog CONFIG REQUIRED)

add_executable(${CMAKE_PROJECT_NAME} src/main.cpp)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE spdlog::spdlog)

方案2:调整工具链加载顺序

确保Emscripten工具链优先于vcpkg工具链加载,让Emscripten的工具链文件自动设置正确的CMAKE_SIZEOF_VOID_P:

cmake_minimum_required(VERSION 3.14)

# 先加载Emscripten原生工具链
set(CMAKE_TOOLCHAIN_FILE "${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" CACHE FILEPATH "")

include(FetchContent)
FetchContent_Declare(vcpkg GIT_REPOSITORY https://github.com/microsoft/vcpkg/ GIT_TAG 2022.09.27)
FetchContent_MakeAvailable(vcpkg)
# 再加载vcpkg工具链
set(CMAKE_TOOLCHAIN_FILE "${vcpkg_SOURCE_DIR}/scripts/buildsystems/vcpkg.cmake" CACHE FILEPATH "")

project(MyProject)

set(CMAKE_CXX_STANDARD 20)

find_package(spdlog CONFIG REQUIRED)

add_executable(${CMAKE_PROJECT_NAME} src/main.cpp)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE spdlog::spdlog)

方案3:临时跳过兼容性检查(不推荐)

临时注释掉spdlogConfigVersion.cmake中关于指针大小的检查逻辑,但此方案会跳过平台兼容性验证,仅适合临时测试:

...
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
# if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "4" STREQUAL "")
#   return()
# endif()

# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
# if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "4")
#   math(EXPR installedBits "4 * 8")
#   set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
#   set(PACKAGE_VERSION_UNSUITABLE TRUE)
# endif()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 01:50:50