|
| 1 | +# Compilation with Scikit-Build |
| 2 | +Scikit-Build is building system generator based on Python's setpuptools system and C++'s Cmake system. With Scikit-Build toolkit, we can compile C++/Python hybrid libraries automatically. The minimum requirements of Scikit-Build include three files: `setup.py`, `pyproject.toml` and `CMakeLists.txt`. |
| 3 | + |
| 4 | +## `setup.py` |
| 5 | +`setup.py` is config file used by Python's setuptools. It consists of basic information about the project. To activate Sckikit-Build tools, the `setup` function must be overloaded by function provided by Scikit-Build in `setup.py`: |
| 6 | +```python |
| 7 | +from skbuild import setup |
| 8 | +``` |
| 9 | +An example of `setup.py` can be found [here](https://github.com/yaozhenghangma/hybrid_programming/blob/main/setup.py). The additional options in `setup.py` are listed on [Scikit-Build's website](https://scikit-build.readthedocs.io/en/latest/usage.html#setup-options) and [Python's document](https://docs.python.org/3/distutils/setupscript.html). |
| 10 | + |
| 11 | +## `pyproject.toml` |
| 12 | +`pyproject.toml` is the specified file format of [PEP 518](https://peps.python.org/pep-0518/), which contains the building system requirements of the project. A detailed description of `pyproject.toml` can be found in [pip's document](https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/). Here, we only utilize a simplified yet practical version that is suitable for most scenarios: |
| 13 | +```toml |
| 14 | +[build-system] |
| 15 | +requires = [ |
| 16 | + "setuptools>=42", |
| 17 | + "cmake>=3.13", |
| 18 | + "scikit-build>=0.14.1", |
| 19 | +] |
| 20 | + |
| 21 | +build-backend = "setuptools.build_meta" |
| 22 | +``` |
| 23 | + |
| 24 | +## `CMakeLists.txt` |
| 25 | +`CMakeLists.txt` file contains building options of CMake. To correctly build a pybind11 project, the location of pybind11 must be provided to CMake: |
| 26 | +```txt |
| 27 | +if(SKBUILD) |
| 28 | + execute_process( |
| 29 | + COMMAND "${PYTHON_EXECUTABLE}" -c |
| 30 | + "import pybind11; print(pybind11.get_cmake_dir())" |
| 31 | + OUTPUT_VARIABLE _tmp_dir |
| 32 | + OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ECHO STDOUT) |
| 33 | + list(APPEND CMAKE_PREFIX_PATH "${_tmp_dir}") |
| 34 | +endif() |
| 35 | +
|
| 36 | +find_package(pybind11 CONFIG REQUIRED) |
| 37 | +``` |
| 38 | +To compile a C++ source code into a shared library, we can use the following commands: |
| 39 | +```txt |
| 40 | +pybind11_add_module(example_cpp_lib src/example_lib/example.cpp) |
| 41 | +
|
| 42 | +install(TARGETS example_cpp_lib DESTINATION .) |
| 43 | +``` |
| 44 | +The `pybind11_add_module` command will compile `example.cpp` file into shared library named `example_cpp_lib`. And when the project is packaged by Python, `install` command will place the library in the root directory of the project. |
| 45 | +This example `CMakeLists.txt` can be found [here](https://github.com/yaozhenghangma/hybrid_programming/blob/main/CMakeLists.txt). |
| 46 | + |
| 47 | +## Building |
| 48 | +Once these three things are prepared correctly. In root directory of the project, we can utilize commands provided by setuptools to build the package. |
| 49 | +```bash |
| 50 | +python3 setup.py build |
| 51 | +python3 setup.py install |
| 52 | +``` |
| 53 | +The command `build` will build and package the project into a directory named `_skbuild`, and `install` command will copy the packaged project to site-packages director of Python. |
0 commit comments