An open API service indexing awesome lists of open source software.

https://github.com/mizux/cmake-pybind11

Test to build a Native Python 3 package using pybind11
https://github.com/mizux/cmake-pybind11

cmake cpp mizux native-library pybind11 python

Last synced: 3 months ago
JSON representation

Test to build a Native Python 3 package using pybind11

Awesome Lists containing this project

README

          

Github-CI:

[![Build Status][amd64_linux_status]][amd64_linux_link]
[![Build Status][amd64_macos_status]][amd64_macos_link]
[![Build Status][arm64_macos_status]][arm64_macos_link]
[![Build Status][amd64_windows_status]][amd64_windows_link]

[![Build Status][amd64_docker_status]][amd64_docker_link]
[![Build Status][arm64_docker_status]][arm64_docker_link]
[![Build Status][riscv64_docker_status]][riscv64_docker_link]

[amd64_linux_status]: ./../../actions/workflows/amd64_linux_cmake.yml/badge.svg
[amd64_linux_link]: ./../../actions/workflows/amd64_linux_cmake.yml
[amd64_macos_status]: ./../../actions/workflows/amd64_macos_cmake.yml/badge.svg
[amd64_macos_link]: ./../../actions/workflows/amd64_macos_cmake.yml
[arm64_macos_status]: ./../../actions/workflows/arm64_macos_cmake.yml/badge.svg
[arm64_macos_link]: ./../../actions/workflows/arm64_macos_cmake.yml
[amd64_windows_status]: ./../../actions/workflows/amd64_windows_cmake.yml/badge.svg
[amd64_windows_link]: ./../../actions/workflows/amd64_windows_cmake.yml

[amd64_docker_status]: ./../../actions/workflows/amd64_docker_cmake.yml/badge.svg
[amd64_docker_link]: ./../../actions/workflows/amd64_docker_cmake.yml
[arm64_docker_status]: ./../../actions/workflows/arm64_docker_cmake.yml/badge.svg
[arm64_docker_link]: ./../../actions/workflows/arm64_docker_cmake.yml
[riscv64_docker_status]: ./../../actions/workflows/riscv64_docker_cmake.yml/badge.svg
[riscv64_docker_link]: ./../../actions/workflows/riscv64_docker_cmake.yml

# Introduction

|
Requirement |
Codemap |
Dependencies |
Build |
CI |
Appendices |
Contributing |
License |

This is an example of how to create a Modern [CMake](https://cmake.org/) C++/Python Project.

This project aim to explain how you build a Python 3.6+ native wheel package using
[`Python3`](https://www.python.org/doc/) and a [setup.py](https://setuptools.readthedocs.io/en/latest/userguide/quickstart.html).

e.g. You have a cross platform C++ library (using a CMake based build) and a
Python wrapper on it thanks to [`Pybind11`](https://github.com/pybind/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.

## Requirement

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".

## Codemap

The project layout is as follow:

* [CMakeLists.txt](CMakeLists.txt) Top-level for [CMake](https://cmake.org/cmake/help/latest/) based build.
* [cmake](cmake) Subsidiary CMake files.
* [python.cmake](cmake/python.cmake) All internall Python CMake stuff.

* [ci](ci) Root directory for continuous integration.

* [Foo](Foo) Root directory for `Foo` library.
* [CMakeLists.txt](Foo/CMakeLists.txt) for `Foo`.
* [include](Foo/include) public folder.
* [foo](Foo/include/foo)
* [Foo.hpp](Foo/include/foo/Foo.hpp)
* [src](Foo/src) private folder.
* [src/Foo.cpp](Foo/src/Foo.cpp)
* [python](Foo/python)
* [CMakeLists.txt](Foo/python/CMakeLists.txt) for `Foo` Python.
* [pyFoo.cpp](Foo/python/pyFoo.cpp) Pybind Python wrapper.
* [Bar](Bar) Root directory for `Bar` library.
* [CMakeLists.txt](Bar/CMakeLists.txt) for `Bar`.
* [include](Bar/include) public folder.
* [bar](Bar/include/bar)
* [Bar.hpp](Bar/include/bar/Bar.hpp)
* [src](Bar/src) private folder.
* [src/Bar.cpp](Bar/src/Bar.cpp)
* [python](Bar/python)
* [CMakeLists.txt](Bar/python/CMakeLists.txt) for `Bar` Python.
* [pyBar.cpp](Bar/python/pyBar.cpp) Pybind Python wrapper.
* [FooBar](FooBar) Root directory for `FooBar` library.
* [CMakeLists.txt](FooBar/CMakeLists.txt) for `FooBar`.
* [include](FooBar/include) public folder.
* [foobar](FooBar/include/foobar)
* [FooBar.hpp](FooBar/include/foobar/FooBar.hpp)
* [src](FooBar/src) private folder.
* [src/FooBar.cpp](FooBar/src/FooBar.cpp)
* [python](FooBar/python)
* [CMakeLists.txt](FooBar/python/CMakeLists.txt) for `FooBar` Python.
* [pyFooBar.cpp](FooBar/python/pyFooBar.cpp) Pybind Python wrapper.

* [python](python) Root directory for Python template files
* [`setup.py.in`](python/setup.py.in) setup.py template for the Python native package.

## Dependencies
To complexify a little, the CMake project is composed of three libraries (Foo, Bar and FooBar)
with the following dependencies:
```sh
Foo:
Bar:
FooBar: PUBLIC Foo PRIVATE Bar
```

## Build Process

To 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](pypi.org) support multiple packages, we will simply upload one package per supported platform.

### Local Package
The pipeline for `linux-x86-64` should be as follow:

![Local Pipeline](docs/pipeline.svg)
![Legend](docs/legend.svg)

#### Building local native Package
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:
```bash
python3 setup.py bdist_wheel
python3 -m pip install --user --find-links=dist cmakepybind11
```

If everything good the package (located in `/python/dist`) should have
this layout:
```
{...}/dist/cmakepybind11-X.Y.9999-cp3Z-cp3Z-.whl:
\- pythonnative
\- __init__.py
\- .libs
\- libFoo.so
\- ...
\- foo
\- __init__.py
\- pyFoo.so
...
```
note: `` 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 .whl`
to study their layout.

## Appendices

Few links on the subject...

### Resources

Project layout:
* [The Pitchfork Layout Revision 1 (cxx-pflR1)](https://github.com/vector-of-bool/pitchfork)

CMake:
* https://llvm.org/docs/CMakePrimer.html
* https://cliutils.gitlab.io/modern-cmake/
* https://cgold.readthedocs.io/en/latest/

Python:
* [Packaging Python Project](https://packaging.python.org/tutorials/packaging-projects/)
* [PEP 600 Future 'manylinux' Platform Tags](https://www.python.org/dev/peps/pep-0600/)

### Misc
Image has been generated using [plantuml](http://plantuml.com/):
```bash
plantuml -Tsvg docs/{file}.dot
```
So you can find the dot source files in [docs](docs).

# Contributing

The [CONTRIBUTING.md](./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.

## License

Apache 2. See the LICENSE file for details.

## Disclaimer

This is not an official Google product, it is just code that happens to be
owned by Google.