This is an example of how to create a Modern CMake C++/Python Project.
This project aim to explain how you build a Python 3.6+ native wheel package using
Python3 and a setup.py.
e.g. You have a cross platform C++ library (using a CMake based build) and a
Python wrapper on it thanks to Pybind11.
Then you want to provide a cross-platform Python packages to consume it in a
Python project...
This project should run on GNU/Linux, MacOS and Windows.
You'll need:
- "CMake >= 3.34".
- "Python >= 3.9" and python module 'pip' (ed "setuptools" and "wheel" will be auto installed on demand).
- "Pybind11 >= 2.13".
The project layout is as follow:
-
CMakeLists.txt Top-level for CMake based build.
-
cmake Subsidiary CMake files.
- python.cmake All internall Python CMake stuff.
-
ci Root directory for continuous integration.
-
Foo Root directory for
Foolibrary.- CMakeLists.txt for
Foo. - include public folder.
- src private folder.
- python
- CMakeLists.txt for
FooPython. - pyFoo.cpp Pybind Python wrapper.
- CMakeLists.txt for
- CMakeLists.txt for
-
Bar Root directory for
Barlibrary.- CMakeLists.txt for
Bar. - include public folder.
- src private folder.
- python
- CMakeLists.txt for
BarPython. - pyBar.cpp Pybind Python wrapper.
- CMakeLists.txt for
- CMakeLists.txt for
-
FooBar Root directory for
FooBarlibrary.- CMakeLists.txt for
FooBar. - include public folder.
- src private folder.
- python
- CMakeLists.txt for
FooBarPython. - pyFooBar.cpp Pybind Python wrapper.
- CMakeLists.txt for
- CMakeLists.txt for
-
python Root directory for Python template files
setup.py.insetup.py template for the Python native package.
To complexify a little, the CMake project is composed of three libraries (Foo, Bar and FooBar) with the following dependencies:
Foo:
Bar:
FooBar: PUBLIC Foo PRIVATE BarTo Create a native dependent package which will contains two parts:
- A bunch of native libraries for the supported platform targeted.
- The Python code depending on it.
note: Since Pypi.org support multiple packages, we will simply upload one package per supported platform.
The pipeline for linux-x86-64 should be as follow:
Thus we have the C++ shared library libFoo.so and the pybind11
Python shared library e.g. pyFoo.so in the same package.
Here some dev-note concerning this setup.py.
- This package is a native package containing native libraries.
Then you can generate the package and install it locally using:
python3 setup.py bdist_wheel
python3 -m pip install --user --find-links=dist cmakepybind11If everything good the package (located in <buildir>/python/dist) should have
this layout:
{...}/dist/cmakepybind11-X.Y.9999-cp3Z-cp3Z-<platform>.whl:
\- pythonnative
\- __init__.py
\- .libs
\- libFoo.so
\- ...
\- foo
\- __init__.py
\- pyFoo.so
...
note: <platform> could be manylinux2014_x86_64, macosx_10_9_x86_64 or win-amd64.
tips: since wheel package are just zip archive you can use unzip -l <package>.whl
to study their layout.
Few links on the subject...
Project layout:
CMake:
- https://llvm.org/docs/CMakePrimer.html
- https://cliutils.gitlab.io/modern-cmake/
- https://cgold.readthedocs.io/en/latest/
Python:
Image has been generated using plantuml:
plantuml -Tsvg docs/{file}.dotSo you can find the dot source files in docs.
The CONTRIBUTING.md file contains instructions on how to file the Contributor License Agreement before sending any pull requests (PRs). Of course, if you're new to the project, it's usually best to discuss any proposals and reach consensus before sending your first PR.
Apache 2. See the LICENSE file for details.
This is not an official Google product, it is just code that happens to be owned by Google.