Windows下CMake构建x86项目时使用64位Python3解释器的配置方法
我维护一个跨平台C项目,项目中Python仅用于从外部源下载依赖、生成部分C代码,Python不会与任何编译目标进行链接,因此我不关心Python自身的运行平台架构。
配置Windows 64位平台的项目构建时,通过find_package指令可正常找到Python,我的设备上仅安装了Win64版本的Python 3.10.0。
但当我尝试构建同项目的x86(Win32)版本时,配置流程会失败,原因是CMake无法找到32位版本的Python。
CMakeLists.txt
cmake_minimum_required(VERSION 3.16) project(findPythonToGenerate CXX) find_package(Python3 REQUIRED) configure_file(test.h.in test.h) add_executable(foo main.cpp ${CMAKE_CURRENT_BINARY_DIR}/test.h) target_include_directories(foo PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
main.cpp
#include <iostream> #include "test.h" int main() { std::cout << PYTHON_EXE << '\n'; return 0; }
test.h.in
#pragma once #define PYTHON_EXE "@Python3_EXECUTABLE@"
构建Windows 64位版本时流程完全正常,对应执行日志如下:
f:\mcve>cmake --version cmake version 3.20.21032501-MSVC_2 CMake suite maintained and supported by Kitware (kitware.com/cmake). f:\mcve>rmdir /Q /S build32 build64 The system cannot find the file specified. f:\mcve>cmake -S . -B build64 -A x64 -Thost=x64 -G "Visual Studio 16 2019" -- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19044. -- The CXX compiler identification is MSVC 19.29.30145.0 -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Found Python3: C:/Python310/python.exe (found version "3.10.0") found components: Interpreter -- Configuring done -- Generating done -- Build files have been written to: F:/mcve/build64 f:\mcve>cmake -S . -B build32 -A Win32 -Thost=x86 -G "Visual Studio 16 2019" -- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19044. -- The CXX compiler identification is MSVC 19.29.30145.0 -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.29.30133/bin/Hostx86/x86/cl.exe - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done CMake Error at C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.20/Modules/FindPackageHandleStandardArgs.cmake:230 (message): Could NOT find Python3 (missing: Python3_EXECUTABLE Interpreter) Call Stack (most recent call first): C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.20/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE) C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.20/Modules/FindPython/Support.cmake:3165 (find_package_handle_standard_args) C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.20/Modules/FindPython3.cmake:485 (include) CMakeLists.txt:4 (find_package) -- Configuring incomplete, errors occurred! See also "F:/mcve/build32/CMakeFiles/CMakeOutput.log".
是否可以通过某种CMake配置,忽略当前构建的目标平台,直接定位到可用的Python解释器?我不希望额外安装Python,因为我根本不需要32位版本的Python。我构建32位平台版本仅用于排查该平台专属的构建问题。
现有类似问题场景不同,我的项目中不会将Python与任何目标进行链接。
我印象中旧版本CMake不存在该问题,近期我更新了Visual Studio 2019,配套的CMake版本也同步更新,但无法完全确认该点。
我核查了每日全平台构建的构建机日志,构建机使用CMake 3.19版本,搭配同版本的64位Python,可正常完成两个平台的构建,因此该问题疑似是CMake 3.20版本的功能回退。
不需要额外安装32位Python,通过以下任意一种方式即可解决问题:
永久方案(修改项目配置)
在调用find_package查找Python3前关闭架构匹配校验,同时明确声明仅需要解释器组件,不查找和架构绑定的开发库、头文件:
cmake_minimum_required(VERSION 3.16) project(findPythonToGenerate CXX) # 关闭Python解释器的架构匹配检查 set(Python3_FIND_ARCHITECTURE FALSE) # 明确指定仅查找解释器组件 find_package(Python3 REQUIRED COMPONENTS Interpreter) configure_file(test.h.in test.h) add_executable(foo main.cpp ${CMAKE_CURRENT_BINARY_DIR}/test.h) target_include_directories(foo PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
修改后无论构建x86还是x64目标,CMake都会直接找到系统中已安装的64位Python解释器,不会再做架构一致性校验。
临时方案(无需修改CMakeLists)
如果不想改动项目配置,可以在执行CMake配置命令时,直接通过参数指定Python解释器的绝对路径,跳过自动搜索流程:
cmake -S . -B build32 -A Win32 -Thost=x86 -G "Visual Studio 16 2019" -DPython3_EXECUTABLE=C:/Python310/python.exe
原因说明
该问题是CMake 3.20版本的逻辑变动导致的:3.20版本更新了FindPython3模块的默认行为,会强制校验搜索到的Python解释器架构和当前编译目标架构一致,该设计原本是为了避免需要嵌入Python、链接Python开发库的项目误引用架构不匹配的文件导致链接失败,但对于仅用Python执行辅助脚本、完全不做链接的场景,这个校验属于多余限制。3.19及更早版本没有这个默认校验,因此可以正常跨架构找到64位Python。
内容的提问来源于stack exchange,提问作者Marek R

