pybind / scikit_build_example Goto Github PK
View Code? Open in Web Editor NEWAn example combining scikit-build and pybind11
License: Other
An example combining scikit-build and pybind11
License: Other
I was just playing around with this to learn more about skikit-build (which is pretty nifty!). I had a two small observations/suggestions:
cmake_minimum_required(VERSION 3.13...3.18)
It's sometimes useful to run CMake directly using the system-provided distribution, and Ubuntu 20.04.1 LTS is still at CMake 3.16.3.
execute_process
command in to extract the site packages directory doesn't parse correctly on that version of CMake. Here, it fails with:CMake Error at CMakeLists.txt:17 (execute_process):
execute_process given unknown argument "ECHO_OUTPUT_VARIABLE".
Is the echo step potentially a leftover from debugging on your end? It seems potentially confusing to users. I would suggest removing it, and also using the `pybind`` package for resolving the path rather than skikit-build:
execute_process(
COMMAND
"${Python_EXECUTABLE}" -c
"import pybind11, os; print(os.path.dirname(os.path.dirname(pybind11.__file__)))"
OUTPUT_VARIABLE _tmp_sitepackages OUTPUT_STRIP_TRAILING_WHITESPACE)
Hello, everyone
First of all, thank you for providing this build example.
To give some context for my question. I aim to create a pybind11 binding for one C++ function to enable its invocation from Python code. But this function dependes on a third-party library called OpenCASCADE.
I'm building on a windows OS. I have cloned this repository and tried to add a simple function into the main.cpp to test the build. I have added the following lines:
main.cpp:
#include <TopoDS_Shape.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
TopoDS_Shape makeBox(float length, float width, float height){
return BRepPrimAPI_MakeBox(length, width, height).Shape();
}
m.def("make_box", &makeBox, "A function that returns a TopoDS_Shape");
And I have also added these lines into the CmakeLists.txt to take into account the OpenCASCADE dependecy:
CmakeLists.txt:
set(OpenCASCADE_DIR "C:/Program Files/OCCT/opencascade-install/cmake")
# OpenCascade
find_package(OpenCASCADE)
# Configure C++ compiler's includes dir
include_directories(SYSTEM ${OpenCASCADE_INCLUDE_DIR})
# Add linker options
foreach(LIB ${OpenCASCADE_LIBRARIES})
# TODO: add only optimized build in production
#target_link_libraries(_core PUBLIC debug ${OpenCASCADE_LIBRARY_DIR}d/${LIB}.lib)
target_link_libraries(_core PUBLIC optimized ${OpenCASCADE_LIBRARY_DIR}/${LIB}.lib)
endforeach(LIB)
set_property(TARGET _core PROPERTY VS_DEBUGGER_ENVIRONMENT "PATH=$<$<CONFIG:DEBUG>:${OpenCASCADE_BINARY_DIR}d>$<$<NOT:$<CONFIG:DEBUG>>:${OpenCASCADE_BINARY_DIR}>;%PATH%")
When I run pip install ./scikit_build_example
I have a successful installation, but then when I try to import scikit_build_example I get the following error:
module = self._system_import(name, *args, **kwargs)
ImportError: DLL load failed while importing _core: The specified module could not be found.
Searching about this error I've found some people saying that to solve I could use the following code:
import os
os.add_dll_directory()
So I've tried referencing my opencascade installation folder, that on my machine is on the path: "C:/Program Files/OCCT/opencascade-install/win64/vc14/bin"
It worked. I would like to know if is there some way to specify this path in the moment of the build. If it should be specified in the CmakeLists.txt or in other file like pyproject.toml.
Any insights or examples on this matter would be highly appreciated!
Thank you very much for the attention
Hi:
I can't find wheels.yml anywhere, could you help me?
Windows 11, Python 3.6, pip 21.3.1.
Repeat-by:
Follow instructions in README.md.
Git clone works.
Then type pip install ./scikit_build_example
Expected: builds
Actual:
ERROR: Invalid requirement: './scikit_build_example'
Well, it's Windows, does changing the / to a \ help?
Expected: builds
Actual:
ERROR: Invalid requirement: '.\\scikit_build_example'
Hint: It looks like a path. File '.\scikit_build_example' does not exist.
What about changing it from . to .. so that there's something with the right name it can look at?
It also helps scikit-build-core. :) I'd say it's a hacky interm solution for all backends to pick up on setuptools configuraiton, but it's a reasonable solution until we have a better cross compiling standard.
Expected: builds:
Actual:
Processing c:\users\beryl\source\repos\scikit_build_example
Installing build dependencies ... error
ERROR: Command errored out with exit status 1:
command: 'c:\program files\python36\python.exe' 'c:\Program Files\python36\lib\site-packages\pip' install --ignore-installed --no-user --prefix 'C:\Users\beryl\AppData\Local\Temp\pip-build-env-n4hg686l\overlay' --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- 'scikit-build-core>=0.3.3' pybind11
cwd: None
Complete output (2 lines):
ERROR: Could not find a version that satisfies the requirement scikit-build-core>=0.3.3 (from versions: none)
ERROR: No matching distribution found for scikit-build-core>=0.3.3
----------------------------------------
WARNING: Discarding file:///C:/Users/beryl/source/repos/scikit_build_example. Command errored out with exit status 1: 'c:\program files\python36\python.exe' 'c:\Program Files\python36\lib\site-packages\pip' install --ignore-installed --no-user --prefix 'C:\Users\beryl\AppData\Local\Temp\pip-build-env-n4hg686l\overlay' --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- 'scikit-build-core>=0.3.3' pybind11 Check the logs for full command output.
ERROR: Command errored out with exit status 1: 'c:\program files\python36\python.exe' 'c:\Program Files\python36\lib\site-packages\pip' install --ignore-installed --no-user --prefix 'C:\Users\beryl\AppData\Local\Temp\pip-build-env-n4hg686l\overlay' --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- 'scikit-build-core>=0.3.3' pybind11 Check the logs for full command output.
Hi, how would I go about creating a single module package? Say I have one module with a few classes. The automatically generated signatures of the class functions contain then something like
packagename.modulename.classname
However, as this package only contains one module, the packagename and modulename are redundant information. Is there away to create just the module, and not a package? Or to omit these names in the signatures?
The documentation generated using Sphinx does not contain the signature and the docstrings of the functions add and subtract defined in the extension module code in src/main.cpp.
scikit_build_example/
pip install .
cd docs/
make html
The target module from which docstrings and function signature are to be extracted as documentation is incorrectly referenced in docs/python_example.rst
as highlighted in the make html
outout below.
$ make html
sphinx-build -b html -d _build/doctrees . _build/html
Running Sphinx v7.3.6
WARNING: Failed to import python_example.
Possible hints:
* ModuleNotFoundError: No module named 'python_example'
* KeyError: 'python_example'
building [mo]: targets for 0 po files that are out of date
writing output...
building [html]: targets for 2 source files that are out of date
updating environment: [new config] 2 added, 0 changed, 0 removed
reading sources... [100%] python_example
WARNING: autodoc: failed to import module 'python_example'; the following exception was raised:
No module named 'python_example'
writing output... [100%] python_example
/~/scikit_build_example/docs/index.rst:6: WARNING: toctree contains reference to document 'python_example' that doesn't have a title: no link will be generated
/~/scikit_build_example/docs/index.rst:6: WARNING: toctree contains reference to document 'python_example' that doesn't have a title: no link will be generated
/~/scikit_build_example/docs/index.rst:6: WARNING: toctree contains reference to document 'python_example' that doesn't have a title: no link will be generated
generating indices... genindex /~/scikit_build_example/docs/index.rst:6: WARNING: toctree contains reference to document 'python_example' that doesn't have a title: no link will be generated
done
writing additional pages... search /~/scikit_build_example/docs/index.rst:6: WARNING: toctree contains reference to document 'python_example' that doesn't have a title: no link will be generated
done
dumping search index in English (code: en)... done
dumping object inventory... done
scikit_build_example
is the correct target module to mention in docs/python_example.rst
from which the function signatures and docstrings are to be extracted.
Hi there, I found this repo when I was deciding on how to port some C++ code to python.
I used to go the way via described in the cmake_example
, but after watching @henryiii 's talk from SciPy22 I thought about scikit_build_example
would be worth a try.
However, I find it quite hard to understand what the (minimum) necessary components are and how this example works, especially since new/unknown/fancy tools like nox and ruff are used.
For example in this file a beginner wonders if the imports from future
are necessary. Comments would be helpful there as well as in the CMakeLists.txt where one can not assume that beginners know where SKBUILD_PROJECT_NAME
etc. come from.
Please don't get me wrong, I appreciate this project. I just think it needs a bit more documentation to be really usable for a broader audience
Hello,
I'm trying to make my package "pip installable" by using this project as reference but the lines cited here seem to force an installation directory.
I believe the most standard usage of cmake would require something along the lines of:
include(GNUInstallDirs)
install(TARGETS ${mypybindlib}
EXPORT ${CMAKE_PROJECT_NAME}Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
For instance, CMAKE_INSTALL_LIBDIR
translates to a relative directory lib
on my system.
I've noticed that this is important because it determines the cmake_install_dir
(here) and the import path in src/scikit_build_example/__init__.py
.
Is there a way to make this work?
Maybe I'm just missing a way to tell scikit-build to pass a variable to cmake, so that I could handle it directly inside the CMakeLists.txt
.
edit:
I found a workaround. It's not ideal (because it doesn't load the install directory from the GNUInstallDirs
or my CMakeLists.txt
) but it works:
from .lib._core import *
Thanks for the great examples and sorry for the naive question, but I am not a python packaging expert, but when I do:
$ pip install -e .
Obtaining file:///home/gailuron/workspace/formations/scikit_build_example
Installing build dependencies ... done
Checking if build backend supports build_editable ... done
ERROR: Project file:///home/gailuron/workspace/formations/scikit_build_example has a 'pyproject.toml' and its build backend is missing the 'build_editable' hook. Since it does not have a 'setup.py' nor a 'setup.cfg', it cannot be installed in editable mode. Consider using a build backend that supports PEP 660.
And I don't know where to start to fix this error.
Maybe proposing a setup.py like this one. But the information are quite redundant with the pyproject.toml.
I'm working on a few python packages using this setup, and there is extra code/functionality on the C++ side that I don't expose to python. I'd like to be able to write unit tests, perhaps using GTEST, that I can integrate into this setup. I attempted incorporating the setup in this tutorial, but I'm unclear about a few things. The way that I understand it, a possible solution could be:
pip
, and then manually run the tests. Perhaps something like this.pybind11
explicitly within CMakeLists.txt
. I'm not sure if this is fine.CMakeLists.txt
files that would work both with pip
and cmake
. (I'm a beginner in cmake
, so I'm assuming there's a way to do this.)Can someone chime in? Am I overcomplicating things?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.