Skip to main content

Test CPPLib integration

Project description

C++ and Python Library

This is a template repository used to create C++/Python libraries. This is for individuals who want to write a standalone C++ library that can also be bound to Python using Pybind11 for better performance. This repository additionally takes care of the intricate world of building binary wheels automatically and publishing to PyPI, including linux and windows. I have tried my best to use good tools and practices in this repo to provide a clean codebase for others to start their project on. What you see in this repo is not all my work, but lessons/code I have learned after observing others work.

Key Features

  • C++ Library is independent of Python Extension, i.e. can be dropped into pure C++ projects.
  • Cross platform using Modern CMake.
  • Benchmark (Nanobench) and Testing (doctest) built in.
  • Good handling of thirdparty dependencies using CMake FetchContent.
  • Documentation for both C++ and Python created using Sphinx, Doxygen, Breathe, and Exhale. The documentation is unified into one website.
  • Integration of CMake into setup.py so that pip install works for python users wanting to build manually (CMake must be installed still).
    • Note that the C++ Library and even the python extension can still be built with standard CMake procedures, see Build with CMake
  • Automatic building of python binary wheels using github actions, see Workflow

This repo relies upon using Modern CMake to build both the C++ and Python Extension libraries. I find that integrating it all in CMake leads to a much nicer developer experience. External users building the library will need CMake installed which may be a consideration before using this template repo as a starting point. However, this repo has a github workflow setup to automatically build python binary wheels for you and upload to PyPI for a variety of python versions/OS/architectures! Please see workflows

Instructions For Using Template

  1. git clone https://github.com/JeremyBYU/cpp-pybind-skel.git

Rename Files

You will want to rename files and library names with a simple find and replace using your IDE/editor. Lets say you named your project SimpleImageFilters with an associates short acronym of SIF . Then simply find and replace in this repository the following (case sensitivity matters):

  • CPPLib -> SimpleImageFilters - C++ Top Namespace and CMake Project Name
  • CPPLIB -> SIMPLEIMAGEFILTERS - Same but uppercase, used in CMake
  • CPPL -> SIF - Acronym used in CMake alias for project
  • cpplib -> simpleimagefilters - Python Library Extension Name

A helper python script, rename_project.py is provided if desired. I would recommend using it because it saves a lot of time.

Note: you don't have to use the naming convention proposed above and may use any you would like. I think the most important thing is simply that the Python extension target is different then C++ library target.

Build Project Manually

You can build the project manually in two ways: one in pure CMake, the other using python setup.py.

Build Manually With CMake

Building happens entirely with CMake. This is meant really only for the library developers who are working on C++ and Python in an edit-compile cycle.

C++ Library

  1. mkdir cmake-build && cd cmake-build
  2. cmake .. - Note - For windows also add -DCMAKE_GENERATOR_PLATFORM=x64
  3. cmake --build . -j$(nproc) --config Release

Build options:

CPPL_BUILD_BENCHMARKS:BOOL=ON // CPPL - Build Benchmarks
CPPL_BUILD_EXAMPLES:BOOL=ON // CPPL - Build Examples
CPPL_BUILD_PYMODULE:BOOL=ON // CPPL -Build Python Module
CPPL_BUILD_TESTS:BOOL=ON // CPPL - Build Tests
CPPL_BUILD_WERROR:BOOL=OFF // CPPL - Add Werror flag to build (turns warnings into errors)
CPPL_WITH_OPENMP:BOOL=ON // CPPL - Build with OpenMP Support

Python Extension

This is meant for advanced python users who are actively developing the extension.

  1. Install conda or create a python virtual environment (Why?). I recommend conda for Windows users.
  2. Perform CMake build as described above
  3. cd cmake-build && cmake --build . --target python-package --config Release
  4. cd lib/python_package && pip install -e . . This installs the library in develop/edit mode. To update the python extension in your python virtual environment all you need to do is run step 3 again.

Note you can alternatively build using Python setup.py

Build Manually with Python

The root directory setup.py file has been modified to build with CMake. This is meant for python users that need to build manually (for some reason) but are not actively developing or changing the code.

  1. Install conda or create a python virtual environment (Why?). I recommend conda for Windows users.
  2. pip install . - Call from root directory

That should be it!

Install with Python

If you only care about installing the python extension you can install from the binary wheels generated by the github action workflows. The binary wheels are uploaded to PyPi. Therefore, after configuring the workflow and tagging a version, you can install as:

  1. pip install cpplib - Change cpplib to whatever your python extension will end up being.

Workflows

Several github action workflows are included in this repository. The first is the binary wheel creation and uploading to pypi.

Binary Wheel

This workflow file generates the binary wheels and uploads to PyPI. You will need to configure your github repository with a token access to publish to PyPI and PyPITest. Please read here about what is expected. Note that this workflow only run on the master branch, and publishing only occurs on tagged releases.

Tests

Automatic testing is also done using this test workflow file

Documentation

C++ classes and functions are documented in their header files. Associated Python functions/classes which are bound with Pybind11 are re-documented. This is for two reasons:

  1. The function/class API might actually be slightly different in arguments and return types (e.g., list vs. std::vector) and more detail/nuance may be desired in one form of the other.
  2. I have no idea how to share them.

For Python, I am using this method to inject further documentation into functions/classes which was developed by Intel at Open3D. They provide a function that can transform an input map of arg/description pairs and convert to Googles Python Docstring format.

Documentation Website Generation

Documentation building has been taken from Open3D with some small modification. Python and C++ documentation is generated using Sphinx into the same website. The C++ API is actually integrated into sphinx using breathe/exhale. Please see docs/builddocs.rst.

Release Steps

These are the release steps that I perform to create a release.

  1. Make all necessary changes
  2. python scripts/manage_versions.py --bump patch
  3. pip install .
  4. cd src_docs && python make_docs.py && cd ..
  5. commit changes
  6. python scripts/manage_versions.py --tag
  7. git push origin dev --tags

FAQ

Q: ERROR: Could not install packages due to an EnvironmentError

A: Remove the build directory

Acknowledgements

I have learned a lot by listening/watching/reading about C++. I can't list them all but the following links had the most influence in developing this repo.

  • Open3D - Much of this repo comes from following their practices. After having made many C++/Python projects I find this code structure to be the best for hybrid projects.
  • Modern CMake - An invaluable resource which has taught me about CMake.
  • Mapbox hpp-skel - A great starting point for header-only libraries. Almost everything MapBox makes is gold to me.
  • Parselmouth - A great resource on using github workflows!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cpplib-1.0.5.tar.gz (32.1 kB view details)

Uploaded Source

Built Distributions

cpplib-1.0.5-cp39-cp39-win_amd64.whl (132.9 kB view details)

Uploaded CPython 3.9 Windows x86-64

cpplib-1.0.5-cp39-cp39-manylinux2010_x86_64.whl (217.7 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.12+ x86-64

cpplib-1.0.5-cp38-cp38-win_amd64.whl (132.8 kB view details)

Uploaded CPython 3.8 Windows x86-64

cpplib-1.0.5-cp38-cp38-manylinux2010_x86_64.whl (217.8 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.12+ x86-64

cpplib-1.0.5-cp37-cp37m-win_amd64.whl (133.4 kB view details)

Uploaded CPython 3.7m Windows x86-64

cpplib-1.0.5-cp37-cp37m-manylinux2010_x86_64.whl (214.7 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.12+ x86-64

cpplib-1.0.5-cp36-cp36m-win_amd64.whl (133.1 kB view details)

Uploaded CPython 3.6m Windows x86-64

cpplib-1.0.5-cp36-cp36m-manylinux2010_x86_64.whl (215.0 kB view details)

Uploaded CPython 3.6m manylinux: glibc 2.12+ x86-64

File details

Details for the file cpplib-1.0.5.tar.gz.

File metadata

  • Download URL: cpplib-1.0.5.tar.gz
  • Upload date:
  • Size: 32.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.0 CPython/3.8.6

File hashes

Hashes for cpplib-1.0.5.tar.gz
Algorithm Hash digest
SHA256 c0f23d9d717359da813694ba7c1e3b42be235335995fd551ba5417ef73f67afd
MD5 96656721495a05ffb51f65b81109c1f0
BLAKE2b-256 dfffde2cfa3f77b52e417846e93ce473094ec0451fed46eca4df5cbad2c17a6a

See more details on using hashes here.

File details

Details for the file cpplib-1.0.5-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: cpplib-1.0.5-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 132.9 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.0 CPython/3.8.6

File hashes

Hashes for cpplib-1.0.5-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 2197f9e72276be3136daded0188efa659fd74d267154744c2cd2e003a38902c7
MD5 966de45b8ae44d8fd37b6e9064dfb2f4
BLAKE2b-256 e7e9cc9d89b0bd3dfb067cd38ece3b32be502518aa6424ff9a40bf749d29a0af

See more details on using hashes here.

File details

Details for the file cpplib-1.0.5-cp39-cp39-manylinux2010_x86_64.whl.

File metadata

  • Download URL: cpplib-1.0.5-cp39-cp39-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 217.7 kB
  • Tags: CPython 3.9, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.0 CPython/3.8.6

File hashes

Hashes for cpplib-1.0.5-cp39-cp39-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 6d3eb532cd4d525717541febb9b8aa47a23b3bfb805e975e93e23a96a4e3ff50
MD5 375be5450410cf09f6a1aaa49cbe2242
BLAKE2b-256 df3488693765683c3562c66d575728574f02256320b6787800e08a57da1ba479

See more details on using hashes here.

File details

Details for the file cpplib-1.0.5-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: cpplib-1.0.5-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 132.8 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.0 CPython/3.8.6

File hashes

Hashes for cpplib-1.0.5-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 889cc945acfd509950d6efd88af777d78565b3009cd010432ca39f58b8d695c5
MD5 7310f693d38bc360b4772eb1ac414492
BLAKE2b-256 0a75688bd3eb43f7824cfe682f9ca5216688b2839a5927cedfd5184a27e9d33d

See more details on using hashes here.

File details

Details for the file cpplib-1.0.5-cp38-cp38-manylinux2010_x86_64.whl.

File metadata

  • Download URL: cpplib-1.0.5-cp38-cp38-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 217.8 kB
  • Tags: CPython 3.8, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.0 CPython/3.8.6

File hashes

Hashes for cpplib-1.0.5-cp38-cp38-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 565c83a198bbf6955a14df78271a4709e487723c0405d4aa39c5789e67393cb8
MD5 5353a3114ceae101d414f3678737f737
BLAKE2b-256 2a53088646a4055e9fb2d2de46c421d2a06287768842ef92cec45470c53d5381

See more details on using hashes here.

File details

Details for the file cpplib-1.0.5-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: cpplib-1.0.5-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 133.4 kB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.0 CPython/3.8.6

File hashes

Hashes for cpplib-1.0.5-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 905aab37ed97674cc89cd4316d29c08d179dcd711d72eb96904be8ba724f87a1
MD5 6158095d78a4401b38fec02e5a4f2a80
BLAKE2b-256 6b087247bed775fc3e0dd81ed82a57a0b18b38f28880aefd5ae8d6041801c014

See more details on using hashes here.

File details

Details for the file cpplib-1.0.5-cp37-cp37m-manylinux2010_x86_64.whl.

File metadata

  • Download URL: cpplib-1.0.5-cp37-cp37m-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 214.7 kB
  • Tags: CPython 3.7m, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.0 CPython/3.8.6

File hashes

Hashes for cpplib-1.0.5-cp37-cp37m-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 47b0930b1afa8b4be947a215a4b5d6c3e663091afdba717cbf6b0f9d2c80b036
MD5 c5a30af56512df242703791993153977
BLAKE2b-256 1bb0287c0ed4aad4df230a83f6f5bd2066521a3471fded93ff08ce1f2ba206c4

See more details on using hashes here.

File details

Details for the file cpplib-1.0.5-cp36-cp36m-win_amd64.whl.

File metadata

  • Download URL: cpplib-1.0.5-cp36-cp36m-win_amd64.whl
  • Upload date:
  • Size: 133.1 kB
  • Tags: CPython 3.6m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.0 CPython/3.8.6

File hashes

Hashes for cpplib-1.0.5-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 ecabd7728289acb84fdd45d2c27e2589ad13650277d0a20ad4c25223d730bff4
MD5 f1b393b899e6c2644b0f7ddb59997c80
BLAKE2b-256 7b396032b9ac1442ad0e6a4837b807de56908c8b0080cc0292755eb68fb578bb

See more details on using hashes here.

File details

Details for the file cpplib-1.0.5-cp36-cp36m-manylinux2010_x86_64.whl.

File metadata

  • Download URL: cpplib-1.0.5-cp36-cp36m-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 215.0 kB
  • Tags: CPython 3.6m, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.54.0 CPython/3.8.6

File hashes

Hashes for cpplib-1.0.5-cp36-cp36m-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 d140cd15da1a1226b438951f3828152a388e00c4b816b29f7c768688029e9217
MD5 59fb8ac62b74a47dab38d3f77ecc3780
BLAKE2b-256 9096c54a4474418a7550dbbf8521d1a1867a190d4f5ae9b66f73978844fc169a

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page