Build a python package with setup.py in CMake
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). In order to fix this, you would have to copy the python source tree into the CMAKE_CURRENT_BINARY_DIR
.
As pointed out previously you can copy your python files to the build folder, e.g. something like this
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.
If you want to include some shared library, e.g. 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
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
....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