[英]Build a python package with setup.py in CMake
EDIT: The question is a bit too long.编辑:这个问题有点太长了。 Here is my real question: How can I build and install a python package with setuptools (setup.py) inside CMake?
这是我真正的问题:如何在 CMake 中使用 setuptools (setup.py) 构建和安装 python 包? The detail of my code is shown below (but with an out-of-source build method, the method with the source is working).
我的代码的详细信息如下所示(但使用源外构建方法,使用源代码的方法有效)。
I have a project where I need to distribute my own python package.我有一个项目需要分发我自己的 python 包。 I made a setup.py script but I would like to build & install it with CMake.
我制作了一个 setup.py 脚本,但我想用 CMake 构建和安装它。
I followed Using CMake with setup.py but it only works with one CMakeLists.txt
alongside the setup.py
and the python folder and without executing cmake from a build directory.我遵循Using CMake with setup.py但它仅适用于
setup.py
和 python 文件夹旁边的一个CMakeLists.txt
,并且不从构建目录执行 cmake 。
With this layout :使用这种布局:
Project/
--build/
--lib/
----python/
------folder1/
------folder2/
------data/
------...
------__init__.py
----setup.py
----CMakeLists.txt
--CMakeLists.txt
and with CMakeLists.txt
:并使用
CMakeLists.txt
:
cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
add_subdirectory(lib)
(..)
and with lib/CMakeLists.txt
:并使用
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()
and with setup.py
:并使用
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")
When I run CMake
from build directory and then make
, the target is built but with nothing.当我从 build 目录运行
CMake
然后make
,目标被构建但什么都没有。 It is as if no packages were found.就好像没有找到包裹一样。 The installation installs the python package without
.py
files.安装会安装没有
.py
文件的 python 包。
setuptools doesn't know about the out of source build and therefore doesn't find any python source files (because you do not copy them to the binary dir, only the setup.py
file seems to exist there). setuptools 不知道源代码外构建,因此找不到任何 python 源文件(因为您没有将它们复制到二进制目录,所以那里似乎只存在
setup.py
文件)。 In order to fix this, you would have to copy the python source tree into the CMAKE_CURRENT_BINARY_DIR
.为了解决这个问题,您必须将 python 源代码树复制到
CMAKE_CURRENT_BINARY_DIR
中。
https://bloerg.net/2012/11/10/cmake-and-distutils.html建议在setup.py
中将package_dir
设置为${CMAKE_CURRENT_SOURCE_DIR}
。
As pointed out previously you can copy your python files to the build folder, eg something like this如前所述,您可以将 python 文件复制到构建文件夹,例如这样的
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)
and then have a build target like this然后有一个像这样的构建目标
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})
In case you do not want to use pip you have to adjust the PyPackageBuld target.如果您不想使用 pip,则必须调整 PyPackageBuld 目标。
If you want to include some shared library, eg written in C++, which is build by other parts of your cmake project you have to copy the shared object file as well to the binary folder如果您想包含一些共享库,例如用 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}")
and add it to the package_data
in setup.py
并将其添加到
setup.py
中的package_data
....
package_data={
'': ['libs/YourLib.cpython-39-x86_64-linux-gnu.so']
}
You can find a working example using pybind11
for `C++´ bindings at https://github.com/maximiliank/cmake_python_r_example您可以在https://github.com/maximiliank/cmake_python_r_example找到使用
pybind11
进行“C++”绑定的工作示例
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.