在 CMake 中使用 setup.py 构建一个 python 包

新手上路,请多包涵

编辑:问题有点太长了。这是我真正的问题:如何在 CMake 中使用 setuptools (setup.py) 构建和安装 python 包?我的代码的详细信息如下所示(但使用源代码之外的构建方法,使用源代码的方法有效)。


我有一个项目,我需要在其中分发我自己的 python 包。我制作了一个 setup.py 脚本,但我想使用 CMake 构建和安装它。

我遵循 了 Using CMake with setup.py 但它只适用于一个 CMakeLists.txt 以及 setup.py 和 python 文件夹,并且没有从构建目录执行 cmake。

使用此布局:

 Project/
--build/
--lib/
----python/
------folder1/
------folder2/
------data/
------...
------__init__.py
----setup.py
----CMakeLists.txt
--CMakeLists.txt

CMakeLists.txt

 cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
add_subdirectory(lib)
(..)

lib/CMakeLists.txt

 find_program(PYTHON "python")

if (PYTHON)
    set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py")
    set(SETUP_PY    "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
    set(DEPS        "${CMAKE_CURRENT_SOURCE_DIR}/python/__init__.py")
    set(OUTPUT      "${CMAKE_CURRENT_BINARY_DIR}/build")

    configure_file(${SETUP_PY_IN} ${SETUP_PY})

    add_custom_command(OUTPUT ${OUTPUT}
                       COMMAND ${PYTHON}
                       ARGS setup.py build
                       DEPENDS ${DEPS})

    add_custom_target(target ALL DEPENDS ${OUTPUT})

    install(CODE "execute_process(COMMAND ${PYTHON} ${SETUP_PY} install)")
endif()

setup.py

 from setuptools import setup, find_packages

setup(name="python",
    version="xx",
    author="xx",
    packages = find_packages(),
    package_data = {'': ['*.txt']},
    description="Python lib for xx")

当我从构建目录运行 CMake 然后运行 --- make 时,目标已构建但没有任何内容。好像没有找到包裹。安装会安装没有 .py 文件的 python 包。

原文由 Samuel Girardin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.5k
1 个回答

如前所述,您可以将 python 文件复制到 build 文件夹,例如像这样的东西

set(TARGET_NAME YourLib)
file(GLOB_RECURSE pyfiles python/*.py)
foreach (filename ${pyfiles})
    get_filename_component(target "${filename}" NAME)
    message(STATUS "Copying ${filename} to ${TARGET_NAME}/${target}")
    configure_file("${filename}"
    "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}/${target}" COPYONLY)
endforeach (filename)

然后有一个这样的构建目标

add_custom_target(PyPackageBuild
        COMMAND "${PYTHON_EXECUTABLE}" -m pip wheel .
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
        COMMENT "Building python wheel package"
        )
add_dependencies(PyPackageBuild ${TARGET_NAME})

如果您不想使用 pip,则必须调整 PyPackageBuld 目标。

如果你想包含一些共享库,例如用 C++ 编写的,它是由你的 cmake 项目的其他部分构建的,你必须将共享对象文件也复制到二进制文件夹

set_target_properties(${TARGET_NAME} PROPERTIES
        PREFIX "${PYTHON_MODULE_PREFIX}"
        SUFFIX "${PYTHON_MODULE_EXTENSION}"
        BUILD_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
        LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}/libs"
        BUILD_WITH_INSTALL_RPATH TRUE)
set(TARGET_PYMODULE_NAME "${PYTHON_MODULE_PREFIX}${TARGET_NAME}${PYTHON_MODULE_EXTENSION}")

并将其添加到 package_data 中的 setup.py

 ....
package_data={
        '': ['libs/YourLib.cpython-39-x86_64-linux-gnu.so']
    }

您可以在 https://github.com/maximiliank/cmake_python_r_example 找到一个使用 pybind11 的“C++”绑定的工作示例

原文由 Max 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题