clair - Automatic Python/C++ bindings
0.3.0
  • Installation
    • Compiling from source
      • clair
      • c2py
        • CMake options
      • Set environment variables
  • Getting Started
    • C++ Code
    • Generate Python Bindings and Compile the Module
      • Use clair-c2py manually
        • Generate Python Bindings
        • Compile the Module
      • Use CMake integration [Recommended]
        • Generate Python Bindings and Compile the Module
        • CMake Configuration
        • General Workflow
    • Use the Python Module
    • What is a Clang tool?
  • Gallery
    • Functions
    • Classes
  • Reference documentation
    • Basic notions
      • Type conversion
        • Principle
        • Convertible types
      • Dynamical dispatch
    • Customization
      • Using annotations in the C++ sources
      • Using a TOML configuration file
        • Generating a template TOML file
        • TOML Configuration Options
        • Example
          • Filtering by namespace
          • Filtering by name
          • Filter by file name
          • Wrap no argument methods as properties
    • Functions
      • Default Behavior & Customization
      • Template Functions
      • Coroutines, generators
    • Classes
      • Default Behavior & Customization
        • Constructors
          • User-defined constructors
          • Synthesized aggregate constructor
        • Methods
          • Instance Methods
          • Const Methods
          • Static Methods
        • Operators
          • Operator()
          • Operator[]
          • Arithmetic Operators
          • Comparison Operators
        • Iterable Objects
        • String Representation
    • Enumerations
    • Across multiple modules
      • Example: Two communicating modules
        • Module A: Defining a class
        • Module B
        • CMake configuration
        • Usage in Python
    • Converters
      • Default converters
      • Custom converters for user-defined types
      • Set up for third party libraries
    • c2py
    • HDF5 (TRIQS/h5 Integration)
    • TRIQS/nda
  • Notebook integration
  • Reporting issues
  • Change Logs
  • About clair/c2py
clair - Automatic Python/C++ bindings
  • Getting Started
  • Use CMake integration [Recommended]
  • View page source

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

$ mkdir build
$ cd build
$ cmake ..
$ make -j 8

CMake Configuration

The CMakeLists.txt used for our Getting Started example looks as follows:

 1cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
 2project(getting-started-example VERSION 3.2.0 LANGUAGES C CXX)
 3set(CMAKE_CXX_STANDARD 20)
 4set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
 5include(FetchContent)
 6
 7# Locate Python and NumPy components
 8find_package(Python COMPONENTS Interpreter Development NumPy)
 9
10# Fetch the c2py library
11FetchContent_Declare(c2py
12  GIT_REPOSITORY https://github.com/flatironinstitute/c2py
13  GIT_TAG unstable
14  EXCLUDE_FROM_ALL
15)
16FetchContent_MakeAvailable(c2py)
17include(${c2py_SOURCE_DIR}/share/cmake/clair_c2py_generate_bindings.cmake)  
18
19# Build the Python C++ extension module
20Python_add_library(getting_started MODULE getting_started.cpp)
21target_link_libraries(getting_started PRIVATE c2py::c2py)
22
23# -----------------------------------------------
24# Optionally regenerate bindings with clair-c2py
25# -----------------------------------------------
26
27option(Update_Python_Bindings "Use clair python bindings generators" ON)
28
29if (Update_Python_Bindings)
30  clair_c2py_generate_bindings(getting_started)
31endif()

Let’s take a closer look at the CMakeLists.txt file:

  • [Lines 1-5] Standard CMake project configuration where we require c++20 support and tell CMake to generate a compile_commands.json database file.

  • [Lines 8] Since we want to build a Python C++ extension, we need to find Python/Numpy on the system.

  • [Lines 11-17] We fetch c2py from GitHub and make it available for the current project rather than relying on a system installation. This ensures that both, c2py and the extension module, iare built with consistent compiler options and linked against the same Python interpreter. As c2py compiles quickly, it does not add significant overhead to the build process.

  • [Lines 20–21] We use the Python_add_library command to declare our getting_started extension module. The command is part of CMake.

  • [Line 27-end] Here we introduce the user option Update_Python_Bindings and, if it is set to ON, we call the clair_c2py_generate_bindings macro provided by c2py. The macro finds the clair-c2py executable and makes sure to (re)generate the bindings before the module is compiled.

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

Previous Next

© Copyright 2024, The Simons Foundation, author: O. Parcollet.