CMake脚本中选择VCPKG Triplet的配置问题求助
解决CMake中自动设置VCPKG Triplet的架构识别问题
我来帮你搞定这个问题,先拆解下你遇到的两个问题的根源,再给出适配你场景的可行方案:
问题根源分析
1. project()后设置Triplet导致找不到库
VCPKG_TARGET_TRIPLET必须在VCPKG的toolchain脚本加载前设置,而CMake会在执行project()命令时自动加载CMAKE_TOOLCHAIN_FILE指定的脚本。你在project()之后才设置Triplet,此时VCPKG已经完成初始化流程,新设置的Triplet不会生效,自然找不到对应架构/链接类型的Protobuf库。
2. project()前设置Triplet无法识别架构
CMAKE_SIZEOF_VOID_P是CMake在project()或enable_language()执行后,根据目标编译架构才会初始化的变量。在project()之前访问它,变量还未被赋值,所以只能得到xUNKNOWN的结果。
解决方案
我们需要在project()之前完成架构判断,但要换一种不依赖CMAKE_SIZEOF_VOID_P的方式。下面的脚本结合了Visual Studio生成器的平台参数和主机架构回退,能在Windows环境下准确识别目标架构,同时保证Triplet在VCPKG toolchain加载前设置完毕:
cmake_minimum_required(VERSION 3.5) # 第一步:判断目标架构 # 优先使用Visual Studio生成器的平台参数(最准确) if(CMAKE_GENERATOR_PLATFORM STREQUAL "x64") set(__ARCH "x64") message(STATUS "----------------- x64") elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "Win32") set(__ARCH "x86") message(STATUS "----------------- x86") else() # 如果生成器不提供平台参数,回退到主机架构判断(适用于Ninja等生成器) if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "AMD64|x86_64") set(__ARCH "x64") message(STATUS "----------------- x64 (host fallback)") elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86") set(__ARCH "x86") message(STATUS "----------------- x86 (host fallback)") else() set(__ARCH "xUNKNOWN") message(STATUS "----------------- xUNKNOWN") endif() endif() # 第二步:根据构建类型设置VCPKG Triplet if(CMAKE_BUILD_TYPE MATCHES Debug) set(VCPKG_TARGET_TRIPLET "${__ARCH}-windows-static-md" CACHE STRING "target triplet" FORCE) message(STATUS "Target triplet for debug is " ${VCPKG_TARGET_TRIPLET}) else() set(VCPKG_TARGET_TRIPLET "${__ARCH}-windows-static" CACHE STRING "target triplet" FORCE) message(STATUS "Target triplet for release is " ${VCPKG_TARGET_TRIPLET}) endif() # 第三步:加载VCPKG Toolchain if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE) set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "") endif() # 最后初始化项目 project(xxx CXX) find_package(Protobuf REQUIRED)
方案说明
- 架构判断逻辑:优先使用
CMAKE_GENERATOR_PLATFORM(Visual Studio生成器会自动设置这个变量,比如选x64平台时它的值就是"x64"),这是最准确的目标架构判断方式;如果是Ninja等不提供该参数的生成器,再回退到主机架构判断,覆盖大多数Windows编译场景。 - Triplet设置时机:所有Triplet相关的设置都在
project()和toolchain加载前完成,确保VCPKG初始化时能读取到正确的Triplet值。 - 适配你的限制:全程不需要命令行参数,完全在CMake脚本内自动完成架构检测和Triplet设置。
内容的提问来源于stack exchange,提问作者yudjin




