使用 vcpkg 安装在 c++ 中运行嵌入式 Python

Dre*_*ith 2 c++ python vcpkg

我不明白如何通过 vcpkg 安装 python。我的 CMakesLists 文件是:

cmake_minimum_required(VERSION 3.8)

if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
set(CMAKE_TOOLCHAIN_FILE "./vcpkg/scripts/buildsystems/vcpkg.cmake"
    CACHE STRING "")
endif()

project(test)

find_package(Python3 COMPONENTS Development REQUIRED)

add_executable(test test.cpp)
target_link_libraries(test PRIVATE Python3::Python)
Run Code Online (Sandbox Code Playgroud)

c++文件直接取自https://docs.python.org/3/extending/embedding.html#very-high-level-embedding

一切编译和链接都没有错误,但在执行时会出现以下错误:

Python path configuration:
  PYTHONHOME = (not set)
  PYTHONPATH = (not set)
  program name = 'C:\Users\smith\OneDrive\Desktop\OSU\vcpkg-python-test\build\Debug\test.exe'
  isolated = 0
  environment = 1
  user site = 1
  import site = 1
  sys._base_executable = 'C:\\Users\\smith\\OneDrive\\Desktop\\OSU\\vcpkg-python-test\\build\\Debug\\test.exe'
  sys.base_prefix = ''
  sys.base_exec_prefix = ''
  sys.platlibdir = 'lib'
  sys.executable = 'C:\\Users\\smith\\OneDrive\\Desktop\\OSU\\vcpkg-python-test\\build\\Debug\\test.exe'      
  sys.prefix = ''
  sys.exec_prefix = ''
  sys.path = [
    'C:\\Users\\smith\\OneDrive\\Desktop\\OSU\\vcpkg-python-test\\build\\Debug\\python310_d.zip',
    '.\\DLLs',
    '.\\lib',
    'C:\\Users\\smith\\OneDrive\\Desktop\\OSU\\vcpkg-python-test\\build\\Debug',
  ]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'
    
Current thread 0x000062bc (most recent call first):
  <no Python frame>
Run Code Online (Sandbox Code Playgroud)

我不明白我做错了什么,或者我是否错过了某些步骤。

完整的示例代码可以在https://github.com/Drew-j-Smith/vcpkg-python-test找到

这是在 Windows 10 上运行的

编辑:

将其添加到 CMakeLists.txt (找到 python 后):

get_filename_component(Python3_EXECUTABLE_DIR ${Python3_EXECUTABLE} DIRECTORY)
add_definitions(-DPYTHON_LIB=L"${Python3_EXECUTABLE_DIR}/Lib")
Run Code Online (Sandbox Code Playgroud)

并打电话

Py_SetPath(PYTHON_LIB);
Run Code Online (Sandbox Code Playgroud)

在 python 初始化之前确实解决了这个问题。然而,这对我来说似乎是一个黑客。我仍在寻找一个强大的解决方案。

Dre*_*ith 6

经过大量的尝试和错误,解决方案是在可执行文件的父目录中创建一个虚拟环境。

这种行为对我来说似乎很奇怪,但记录在这里: https: //docs.python.org/3/c-api/intro.html#embedding-python

示例解决方案是将其添加到 CMakeLists.txt 的末尾

if(WIN32)
    add_custom_command(TARGET test POST_BUILD 
    COMMAND ${Python3_EXECUTABLE} -m venv $<TARGET_FILE_DIR:test>/..
    COMMAND $<TARGET_FILE_DIR:test>/../Scripts/activate.bat
    COMMAND python -m pip install -r ${CMAKE_SOURCE_DIR}/requirements.txt > pip_install.log)
else()
    add_custom_command(TARGET test POST_BUILD 
    COMMAND ${Python3_EXECUTABLE} -m venv $<TARGET_FILE_DIR:test>/..
    COMMAND $<TARGET_FILE_DIR:test>/../Scripts/activate
    COMMAND python -m pip install -r ${CMAKE_SOURCE_DIR}/requirements.txt > pip_install.log)
endif()
Run Code Online (Sandbox Code Playgroud)

这将安装所需的任何包并为可执行文件创建一个虚拟环境,以便它知道 python 的路径。

编辑:

我在调试模式下运行时遇到一些问题。当尝试导入 numpy 时,由于缺少调试二进制文件,我不得不使用发布模式。