【问题标题】:Creating a python package (deb/rpm) from cmake从 cmake 创建一个 python 包(deb/rpm)
【发布时间】:2021-12-29 05:14:42
【问题描述】:

我正在尝试从cmake 创建一个python 包(deb 和rpm),最好使用cpack。我确实读过

对于我的共享库,安装工作正常(使用组件安装)。但是,我无法理解安装 python 绑定(胶水)代码的文档。使用标准的 cmake 安装机制,我尝试了:

install(
  FILES __init__.py library.py
  DESTINATION ${ACME_PYTHON_PACKAGE_DIR}/project_name
  COMPONENT python)

然后使用蛮力方法最终得到:

# debian based package (relative path)
set(ACME_PYTHON_PACKAGE_DIR lib/python3/dist-packages)

# rpm based package (full path required)
set(ACME_PYTHON_PACKAGE_DIR /var/lang/lib/python3.8/site-packages)

以上来源于:

debian % python -c 'import site; print(site.getsitepackages())'
['/usr/local/lib/python3.9/dist-packages', '/usr/lib/python3/dist-packages', '/usr/lib/python3.9/dist-packages']

同时:

rpm % python -c 'import site; print(site.getsitepackages())'
['/var/lang/lib/python3.8/site-packages']

很明显,蛮力方法将无法移植,并且在 python 的下一个版本中注定会失败。我能想到的唯一可能的解决方案是生成一个临时的setup.py python 脚本(使用setuptools),它将进行安装。通常cmake 会调用following process

% python setup.py install --root ${ACME_PYTHON_INSTALL_ROOT}

我的问题是:

  • 我是否正确理解了 python 包的 cmake/cpack 文档?如果是这样,这意味着我需要生成一个中间 setup.py 脚本。
  • 我一直在搜索 cmake/cpack 代码库 (git grep setuptools),但没有找到帮助函数来处理 setup.py 的生成并将结果文件传递回 cpack。是否有可以重复使用的现有 cmake 模块?

我确实阅读了一些替代解决方案,例如:

这似乎过于复杂,并且面向仅基于 Debian 的系统。我需要处理 RPM。

【问题讨论】:

  • 为什么不创建一个wheel包呢?
  • @Mizux 任何关于 cpack+wheel 的文档,谢谢?
  • 只是想直接创建一个像 github.com/Mizux/python-native 这样的 whl 包,您可以上传到 pypi.org 等,不涉及 rpm。否则你可能对github.com/google/or-tools/blob/stable/cmake/…感兴趣
  • @Mizux 对于您的建议 #1,我无法将公司代码上传到 pypi.org。至于建议#2,这与我自己的答案非常相似。但是它没有处理与绝对路径 cmake install() 命令相关的复杂性。

标签: python python-3.x cmake setuptools


【解决方案1】:

正如my other solution 中提到的,丑陋的部分是处理cmake install() 命令中的绝对路径。我能够重构代码以避免在install() 中使用绝对路径。我只是将安装更改为:

install(
  # trailing slash is important:
  DIRECTORY ${SETUP_OUTPUT}/
  # "." syntax is a reliable mechanism, see:
  # https://gitlab.kitware.com/cmake/cmake/-/issues/22616
  DESTINATION "."
  COMPONENT python)

然后你只需要:

set(CMAKE_INSTALL_PREFIX "/")
set(CPACK_PACKAGING_INSTALL_PREFIX "/")
include(CPack)

此时,所有安装路径现在都需要明确包含 /usr,因为我们已经清除了 CMAKE_INSTALL_PREFIX 的值。

以上内容已针对 deb 和 rpm 包进行了测试。 CPACK_BINARY_TGZ 确实可以使用上述解决方案正常运行:

【讨论】:

    【解决方案2】:

    我将发布我目前使用的临时解决方案,直到有人提供更强大的解决方案。

    所以我最终偶然发现了:

    重新使用上面的方法来执行install 步骤而不是build 步骤可以如下完成:

    find_package(Python COMPONENTS Interpreter)
    
    set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in")
    set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
    set(SETUP_DEPS "${CMAKE_CURRENT_SOURCE_DIR}/project_name/__init__.py")
    set(SETUP_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build-python")
    
    configure_file(${SETUP_PY_IN} ${SETUP_PY})
    
    add_custom_command(
      OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/setup_timestamp
      COMMAND ${Python_EXECUTABLE} ARGS ${SETUP_PY} install --root ${SETUP_OUTPUT}
      COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/setup_timestamp
      DEPENDS ${SETUP_DEPS})
    
    add_custom_target(target ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/setup_timestamp)
    

    然后丑陋的部分是:

    install(
      # trailing slash is important:
      DIRECTORY ${SETUP_OUTPUT}/
      DESTINATION "/" # FIXME may cause issues with other cpack generators
      COMPONENT python)
    

    原来install() 的文档对absolute paths 非常清楚:

    DESTINATION
    [...]
    As absolute paths are not supported by cpack installer generators,
    it is preferable to use relative paths throughout.
    

    供参考,这是我的setup.py.in

    from setuptools import setup
    
    if __name__ == '__main__':
        setup(name='project_name_python',
              version='${PROJECT_VERSION}',
              package_dir={'': '${CMAKE_CURRENT_SOURCE_DIR}'},
              packages=['project_name'])
    

    您可以使用-B 标志删除__pycache__ 文件夹:

    COMMAND ${Python_EXECUTABLE} ARGS -B ${SETUP_PY} install --root ${SETUP_OUTPUT}
    

    您可以更加花哨并添加 debian 选项,例如:

    if(CPACK_BINARY_DEB)
      set(EXTRA_ARG "--install-layout" "deb")
    endif()
    

    用作:

    COMMAND ${Python_EXECUTABLE} ARGS -B ${SETUP_PY} install --root ${SETUP_OUTPUT} ${EXTRA_ARG}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-17
      • 2015-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-22
      相关资源
      最近更新 更多