Skip to content
Snippets Groups Projects

(guide_project_integration)=

Project and Build System Integration

(config_module)=

Project-Wide Settings using Configuration Modules

When embedding pystencils-sfg into a C++ project or build system, you might want to set a project-wide base configuration for all generator scripts. In addition, it might be necessary to pass various details about the project and build setup to the generator scripts. Both can be achieved by the use of a configuration module.

A configuration module is a Python file that defines up to two functions:

  • def configure_sfg(cfg: SfgConfig) is called to set up the project-wide base configuration. It takes an {any}SfgConfig object which it may modify to establish the project-wide option set.
  • def project_info() -> Any is called by pystencils-sfg to retrieve an object that encapsulates any custom project-specific information. This information is passed on to the generator scripts through the {any}sfg.context.project_info <SfgContext.project_info> attribute.

An example configuration module might look like this:

from pystencilssfg import SfgConfig

def configure_sfg(cfg: SfgConfig):
    cfg.extensions.header = "h++"
    cfg.extensions.impl = "c++"
    cfg.clang_format.code_style = "llvm"
    ...

def project_info():
    return {
        "project_name": "my-project",
        "float_precision": "float32",
        "use_cuda": False,
        ...
    }

Here, project_info returns a dictionary, but this is just for illustration; the function may return any type of arbitrarily complex objects. For improved API safety, {any}dataclasses might be a good tool for setting up project info objects.

When invoking a generator script, the path to the current configuration module must be passed to it using the --sfg-config-module command-line parameter. This can be automated by an adequately set up build system, such as GNU Make or CMake.

If you are using pystencils-sfg with CMake through the provided CMake module, see below on how to specify a configuration module for your project.

(cmake_integration)=

CMake Integration

pystencils-sfg is shipped with a CMake module for on-the-fly code generation during the CMake build process.

Add the module

To include the module in your CMake source tree, you must first add the pystencils-sfg Find-module to your CMake module path. To create the Find-module, navigate to the directory it should be placed in and run the following command:

sfg-cli cmake make-find-module

This will create the FindPystencilsSfg.cmake file. Make sure that its containing directory is added to the CMake module path.

To load pystencils-sfg into CMake, we first need to set the Python interpreter of the environment SFG is installed in. There are several ways of doing this:

Set Python via a Find-Module Hint

Set the PystencilsSfg_PYTHON_PATH hint variable inside your CMakeLists.txt to point at the Python executable which should be used to invoke pystencils-sfg, e.g.:

set(PystencilsSfg_PYTHON_PATH ${CMAKE_SOURCE_DIR}/.venv/bin/python)

This is the recommended way, especially when other parts of your project also use Python.

Set Python via a Cache Variable

On the command line or in a CMake configure preset, set the PystencilsSfg_PYTHON_INTERPRETER cache variable to point at the Python executable to be used to invoke pystencils-sfg; e.g.:

cmake -S . -B build -DPystencilsSfg_PYTHON_INTERPRETER=`pwd`/.venv/bin/python

If both the cache variable and the PystencilsSfg_PYTHON_PATH hint are set, the cache variable takes precedence, so you can use the cache variable to override the hint.

Automatically Find a Python Installation

If none of the above is provided, pystencils-sfg will invoke FindPython to determine the Python interpreter it should use. You can affect this process through any of the hints listed in the FindPython documentation.

Find pystencils-sfg

Finally, call find_package( PystencilsSfg ) from your CMakeLists.txt to load the SFG module. If SFG as a dependency is not optional, add the REQUIRED flag such that the call will fail if the package cannot be found.

(cmake_add_generator_scripts)=

Adding Generator Scripts

The primary interaction point in CMake is the function pystencilssfg_generate_target_sources, with the following signature:

pystencilssfg_generate_target_sources( <target> 
    SCRIPTS script1.py [script2.py ...]
    [SCRIPT_ARGS arg1 [arg2 ...]]
    [DEPENDS dependency1.py [dependency2.py...]]
    [FILE_EXTENSIONS <header-extension> <impl-extension>]
    [OUTPUT_MODE <standalone|inline|header-only>]
    [CONFIG_MODULE <path-to-config-module.py>]
    [OUTPUT_DIRECTORY <output-directory>]
)

It registers the generator scripts script1.py [script2.py ...] to be executed at compile time using add_custom_command and adds their output files to the specified <target>. Any changes in the generator scripts, or any listed dependency, will trigger regeneration. The function takes the following options:

  • SCRIPTS: A list of generator scripts
  • SCRIPT_ARGS: A list of custom command line arguments passed to the generator scripts; see
  • DEPENDS: A list of dependencies for the generator scripts
  • FILE_EXTENSION: The desired extensions for the generated files
  • OUTPUT_MODE: Sets the output mode of the code generator; see {any}SfgConfig.output_mode.
  • CONFIG_MODULE: Set the configuration module for all scripts registered with this call. If set, this overrides the value of PystencilsSfg_CONFIG_MODULE in the current scope (see )
  • OUTPUT_DIRECTORY: Custom output directory for generated files. If OUTPUT_DIRECTORY is a relative path, it will be interpreted relative to the current build directory.

If OUTPUT_DIRECTORY is not specified, any C++ header files generated by the above call can be included in any files belonging to target via:

#include "gen/<file1.hpp>"
#include "gen/<file2.hpp>"
/* ... */

:::{attention} If you change the code generator output directory using the OUTPUT_DIRECTORY argument, you are yourself responsible for placing that directory--or any of its parents--on the include path of your target. :::

(cmake_set_config_module)=

Set a Configuration Module

There are two ways of specifying a configuration module for generator scripts registered with CMake:

  • To set a configuration module for scripts registered with a single call to pystencilssfg_generate_target_sources, use the CONFIG_MODULE function parameter (see ).
  • To set a config module for all generator scripts within the current CMake directory and its subdirectories, set the scoped variable PystencilsSfg_CONFIG_MODULE to point at the respective Python file, e.g. set( PystencilsSfg_CONFIG_MODULE ProjectConfig.py ).

You might want to populate your configuration module with information about the current build setup and environment. For this purpose, take a look at the configure_file CMake function.