.. _use_cmake_integration: Use CMake integration [Recommended] ==================================== Generate Python Bindings and Compile the Module ............................................... To generate the Python bindings and compile the module with CMake, we simply run .. code-block:: bash $ mkdir build $ cd build $ cmake .. $ make -j 8 CMake Configuration ................... The recommended way to build a module is the ``c2py_add_module`` macro provided by **c2py**: it declares the Python extension module, links it against **c2py**, and -- when ``Update_Python_Bindings`` is ``ON`` -- (re)generates the bindings with ``clair-c2py``. The ``CMakeLists.txt`` for our :ref:`getting_started` example looks as follows: .. literalinclude:: ../examples/getting_started/CMakeLists.txt :language: cmake :linenos: Let's take a closer look at the ``CMakeLists.txt`` file: * **[Lines 1-4]** Standard CMake project configuration: we require ``c++20`` support and tell CMake to generate a ``compile_commands.json`` database (``clair-c2py`` relies on it to parse the code). * **[Line 7]** This example ships without generated bindings, so we default ``Update_Python_Bindings`` to ``ON`` to (re)generate them; see the *General Workflow* below. * **[Lines 9-17]** We fetch **c2py** from GitHub and make it available for the current project rather than relying on a system installation. This ensures that **c2py** and the extension module are built with consistent compiler options and linked against the same Python interpreter, and it makes the ``c2py_add_module`` macro available. As **c2py** compiles quickly, it does not add significant overhead. (If **c2py** is already installed, ``find_package(c2py)`` makes the macro available just as well.) * **[Line 20]** ``c2py_add_module`` declares the ``getting_started`` extension module, links it against **c2py**, and -- when ``Update_Python_Bindings`` is ``ON`` -- finds ``clair-c2py`` and (re)generates the bindings before the module is compiled. It also accepts optional arguments such as ``LINK_LIBRARIES`` for extra dependencies and ``DEPENDS_ON_BINDINGS`` to order generation across modules (see :ref:`multiple_modules`). .. note:: * The bindings are only (re)generated if the option ``Update_Python_Bindings`` is set to ``ON``. * ``clair-c2py`` automatically uses the compilation database generated by CMake. * Even if CMake uses an out-of-source build, the tool acts **in the source directory**, where it generates the binding files. General Workflow ................ The above ``CMakeLists.txt`` file is designed to be used in two different modes, depending on the value of the ``Update_Python_Bindings`` option: * **Developer Mode** (``Update_Python_Bindings == ON``)[default]: * The bindings are automatically regenerated using ``clair-c2py`` when the C++ code or the options TOML file are modified. * At the end, the regenerated bindings should be committed along with the rest of the source (they are produced in the **source** directory). * Any C++20-compliant compiler can be used to compile the module, even though ``clair-c2py`` itself relies on Clang and its libraries. * **User Mode** (``Update_Python_Bindings == OFF``): * The compilation uses the bindings already present in the source, as they are included in ``my_module.cpp``. * ``clair-c2py`` and **clair** in general are not needed. * Any C++20-compliant compiler can be used.