簡體   English   中英

從 cmake 創建 python package (deb/rpm)

[英]Creating a python package (deb/rpm) from cmake

我正在嘗試從cmake創建一個 python package (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會調用以下過程

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

我的問題是:

  • 我是否正確理解了 python package 的 cmake/cpack 文檔? 如果是這樣,這意味着我需要生成一個中間setup.py腳本。
  • 我一直在搜索 cmake/cpack 代碼庫( git grep setuptools )但沒有找到幫助函數來處理setup.py的生成並將結果文件傳回cpack 是否有可以重復使用的現有cmake模塊?

我確實閱讀了一些替代解決方案,例如:

這似乎過於復雜,並且面向僅基於 Debian 的系統。 在我的情況下,我需要處理 RPM。

我將發布我目前正在使用的臨時解決方案,直到有人提供更強大的東西。

所以我最終設法偶然發現:

重新使用上述內容來執行install步驟而不是build步驟可以如下完成:

find_package(PythonInterp REQUIRED)

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()的文檔對絕對路徑非常清楚:

 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'])

正如我在其他解決方案中提到的,丑陋的部分是在 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確實可以使用上述解決方案正常運行:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM