python - 如何从 CMake 获取 "install"Python 代码?

标签 python jenkins cmake

我有一个主要是 c++ 的项目,我使用 CMake 来管理它。设置后cmake_install_prefix和配置,它会生成生成文件,然后可以使用这些文件以非常标准的方式构建和安装:

make
make install

此时,我的二进制文件结束于 cmake_install_prefix ,并且它们可以在没有额外工作的情况下执行。最近我在源代码树的一些地方添加了一些 Python 脚本,其中一些依赖于其他。我可以使用 CMake 将 Python 文件+目录结构复制到 cmake_install_prefix ,但是如果我进入该路径并尝试使用其中一个脚本,Python 将找不到用作 imports 的其他脚本因为PYTHONPATH不包含 cmake_install_prefix .我知道您可以使用 CMake 设置环境变量,但它不会在 shell 中持续存在,因此对于用户而言,除了当前终端 session 之外,它并不是真正的“设置”。

解决方案似乎是在您的软件构建说明中添加一个步骤,上面写着“设置您的 PYTHONPATH”。有没有办法避免这种情况?这是作为更大项目的一部分“安装”Python 脚本的标准做法吗?为项目设置持续集成之类的事情似乎真的很复杂,因为必须手动配置像 Jenkins 这样的东西来注入(inject)环境变量,而它不需要什么特别的东西来构建和执行从 c++ 代码构建的可执行文件。

最佳答案

Python 提供 sys.path列表,用于搜索具有 import 的模块指令。您可以在包含您的模块之前调整此列表:

脚本1.py :

# Do some things useful for other scripts

script2.py.in :
# Uses script1.py.
...
sys.path.insert(1, "@SCRIPT1_INSTALL_PATH@")
import script1
...

CMakeLists.txt :
...
# Installation path for script1. Depends from CMAKE_INSTALL_PREFIX.
set(SCRIPT1_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/<...>)

install(FILES script1.py DESTINATION ${SCRIPT1_INSTALL_PATH}

# Configure 'sys.path' in script2.py, so it may find script1.py.
configure_file("script2.py.in" "script2.py" @ONLY)

set(SCRIPT2_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/<...>)
install(FILES script2.py DESTINATION ${SCRIPT2_INSTALL_PATH}
...

如果您希望 script2.py 在构建树和安装树中都工作,您需要拥有它的两个实例,一个在构建树中工作,一个在安装后工作。两个实例都可以从单个 .in 进行配置文件。

对于已编译的可执行文件和库,类似的机制用于帮助二进制文件在非标准位置查找库。它被称为 RPATH。

因为 CMake
  • 知道创建的每个二进制文件(它跟踪 add_executableadd_library 调用),
  • 知道二进制文件之间的链接(target_link_libraries 调用也被跟踪),
  • 完全控制链接过程,

  • CMake 能够 自动安装二进制文件时调整 RPATH。

    如果 Python 脚本 CMake 没有此类信息,则应手动调整链接路径。

    关于python - 如何从 CMake 获取 "install"Python 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41733030/

    相关文章:

    python - Pandas:获取每行中最小值的列名称,并获取与其余列相比的%差异

    python - 如何仅编辑一个数据帧pandas的显示精度

    jenkins - 在所有 Jenkins 页面上显示公告

    c++ - 支持 C++17 的 AppleLLVM 9.1.0?还是 cmake/env 的问题?

    CMake:如何在 Linux 中将目标/文件打包成多个包?

    CMake - Code::Blocks - Hello World - 基本示例

    python - Django 注释问题

    Python:索引列表列表的问题

    bash - 如何在Jenkins的pylint失败(在Docker容器中)上使步骤失败

    jenkins - 我是否必须在声明式 Jenkins 管道中使用节点 block ?