diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5b1c017af7bdd54a605c171f161b5fbd242023f2..24fafb8f6b951c56c500664c39f64011b597e054 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,8 +2,19 @@ cmake_minimum_required( VERSION 3.24 )
 project ( sfg-walberla )
 
 list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake )
+
 find_package( PystencilsSfg REQUIRED )
 
+set( SfgConfigModule ${CMAKE_BINARY_DIR}/CodegenConfig.py )
+configure_file(
+    ${CMAKE_CURRENT_SOURCE_DIR}/cmake/CodegenConfig.template.py
+    ${SfgConfigModule}
+)
+
+message( STATUS "Wrote project-wide code generator configuration to ${SfgConfigModule}" )
+
+set( PystencilsSfg_CONFIG_MODULE ${SfgConfigModule} PARENT_SCOPE )
+
 add_library( sfg_walberla INTERFACE )
 
 target_sources( sfg_walberla
diff --git a/cmake/CodegenConfig.template.py b/cmake/CodegenConfig.template.py
new file mode 100644
index 0000000000000000000000000000000000000000..07f29998fd188b7f4f95a2bd5409cb02f77f6c8d
--- /dev/null
+++ b/cmake/CodegenConfig.template.py
@@ -0,0 +1,31 @@
+from pystencilssfg import SfgConfig
+from sfg_walberla import WalberlaBuildConfig
+
+
+def configure_sfg(cfg: SfgConfig):
+    cfg.extensions.header = "hpp"
+    cfg.extensions.impl = "cpp"
+
+
+def project_info() -> WalberlaBuildConfig:
+    from sfg_walberla.build_config import cmake_parse_bool
+
+    return WalberlaBuildConfig(
+        c_compiler_id="${CMAKE_C_COMPILER_ID}",
+        cxx_compiler_id="${CMAKE_CXX_COMPILER_ID}",
+        use_double_precision=cmake_parse_bool("${WALBERLA_DOUBLE_ACCURACY}"),
+        optimize_for_localhost=cmake_parse_bool("${WALBERLA_OPTIMIZE_FOR_LOCALHOST}"),
+        mpi_enabled=cmake_parse_bool("${WALBERLA_BUILD_WITH_MPI}"),
+        openmp_enabled=cmake_parse_bool("${WALBERLA_BUILD_WITH_OPENMP}"),
+        cuda_enabled=cmake_parse_bool("${WALBERLA_BUILD_WITH_CUDA}"),
+        hip_enabled=cmake_parse_bool("${WALBERLA_BUILD_WITH_HIP}"),
+        likwid_enabled=cmake_parse_bool("${WALBERLA_BUILD_WITH_LIKWID_MARKERS}"),
+    )
+
+
+def validate():
+    _ = project_info()
+
+
+if __name__ == "__main__":
+    validate()
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 56d5261c522b3e8065ff6a812213a046a43e3b68..59c36c295de0103a5eb5657faee2ff1dfadc1fb4 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -8,10 +8,10 @@ FetchContent_Declare(
     GIT_REPOSITORY https://i10git.cs.fau.de/walberla/walberla.git
 )
 
+message( STATUS "Fetching waLBerla sources (this might take a while)..." )
 FetchContent_MakeAvailable(walberla)
 
 add_subdirectory(${CMAKE_SOURCE_DIR}/.. ${CMAKE_BINARY_DIR}/sfg-walberla)
 
 add_subdirectory( GeneratorScriptBasics )
-add_subdirectory( PoiseuilleChannel )
-
+add_subdirectory( ForceDrivenChannel )
diff --git a/examples/ForceDrivenChannel/CMakeLists.txt b/examples/ForceDrivenChannel/CMakeLists.txt
index bebe118f655fc55007b721fe4f701b62bb4279ab..4fbb89077b6d17f564cad91113e1f74cc0cd81b6 100644
--- a/examples/ForceDrivenChannel/CMakeLists.txt
+++ b/examples/ForceDrivenChannel/CMakeLists.txt
@@ -1,14 +1,14 @@
 waLBerla_link_files_to_builddir( Channel.prm )
 
-add_executable( Ex_PoiseuilleChannel )
-target_sources( Ex_PoiseuilleChannel PRIVATE PoiseuilleChannel.cpp )
+add_executable( Ex_ForceDrivenChannel )
+target_sources( Ex_ForceDrivenChannel PRIVATE ForceDrivenChannel.cpp )
 
-pystencilssfg_generate_target_sources( Ex_PoiseuilleChannel 
+pystencilssfg_generate_target_sources( Ex_ForceDrivenChannel
     SCRIPTS LbmAlgorithms.py
 )
 
 target_link_libraries(
-    Ex_PoiseuilleChannel
+    Ex_ForceDrivenChannel
     PRIVATE 
     core stencil blockforest geometry vtk sfg_walberla 
 )
diff --git a/examples/GeneratorScriptBasics/BasicCodegen.py b/examples/GeneratorScriptBasics/BasicCodegen.py
index a23e622ffd334f082f067602c037450790e5f636..61b2e312aeed674fa3961f1ac59b7a67b0ea6d76 100644
--- a/examples/GeneratorScriptBasics/BasicCodegen.py
+++ b/examples/GeneratorScriptBasics/BasicCodegen.py
@@ -1,4 +1,7 @@
 from pystencilssfg import SourceFileGenerator
+from sfg_walberla import WalberlaBuildConfig
 
 with SourceFileGenerator() as sfg:
-    pass
+    build_config = WalberlaBuildConfig.from_sfg(sfg)
+
+    print(build_config)
diff --git a/examples/GeneratorScriptBasics/CMakeLists.txt b/examples/GeneratorScriptBasics/CMakeLists.txt
index ab855a422790fa0910f1c0ee96212ffed91a1fd7..118434c7bc3af7560b4de6d91ada4971d7c803d9 100644
--- a/examples/GeneratorScriptBasics/CMakeLists.txt
+++ b/examples/GeneratorScriptBasics/CMakeLists.txt
@@ -1,7 +1,7 @@
 add_executable( Ex_GeneratorScriptBasics )
-target_sources( Ex_GeneratorScriptBasics PRIVATE Ex_GeneratorScriptBasics.cpp )
+# target_sources( Ex_GeneratorScriptBasics PRIVATE Ex_GeneratorScriptBasics.cpp )
 
-pystencilssfg_generate_target_sources( Ex_PoiseuilleChannel 
+pystencilssfg_generate_target_sources( Ex_GeneratorScriptBasics 
     SCRIPTS BasicCodegen.py
 )
 
diff --git a/src/sfg_walberla/__init__.py b/src/sfg_walberla/__init__.py
index 063b350bec25105d9167aa6b0a7476e448c6a574..50097ef8b19500c16e44a5e25622d4fbaf6889d9 100644
--- a/src/sfg_walberla/__init__.py
+++ b/src/sfg_walberla/__init__.py
@@ -1,6 +1,7 @@
 from .api import real_t, Vector3, GhostLayerFieldPtr, glfield, IBlockPtr
 from .postprocessing import CaptureToClass
 from .sweep import Sweep
+from .build_config import WalberlaBuildConfig
 
 __all__ = [
     "real_t",
@@ -10,6 +11,7 @@ __all__ = [
     "IBlockPtr",
     "CaptureToClass",
     "Sweep",
+    "WalberlaBuildConfig",
 ]
 
 from . import _version
diff --git a/src/sfg_walberla/build_config.py b/src/sfg_walberla/build_config.py
new file mode 100644
index 0000000000000000000000000000000000000000..55fe4117da493680f323945039029ac07ecb4be7
--- /dev/null
+++ b/src/sfg_walberla/build_config.py
@@ -0,0 +1,74 @@
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+from pystencils import CreateKernelConfig
+from pystencils.types.quick import Fp
+from pystencils.backend.jit import no_jit
+
+from pystencilssfg import SfgContext
+from pystencilssfg.composer import SfgIComposer
+
+
+def cmake_parse_bool(var: str):
+    var = var.upper()
+    if var in ("ON", "1", "TRUE"):
+        return True
+    elif var in ("OFF", "0", "FALSE"):
+        return False
+    else:
+        raise ValueError(f"Could not parse cmake value `{var}` as boolean.")
+
+
+@dataclass
+class WalberlaBuildConfig:
+    """Represents a waLBerla build system configuration"""
+
+    c_compiler_id: str
+    """Value of `CMAKE_C_COMPILER_ID`."""
+
+    cxx_compiler_id: str
+    """Value of `CMAKE_CXX_COMPILER_ID`."""
+
+    use_double_precision: bool
+    """Value of `WALBERLA_DOUBLE_ACCURACY`"""
+
+    optimize_for_localhost: bool
+    """Value of `WALBERLA_OPTIMIZE_FOR_LOCALHOST`."""
+
+    mpi_enabled: bool
+    """Value of `WALBERLA_BUILD_WITH_MPI`."""
+
+    openmp_enabled: bool
+    """Value of `WALBERLA_BUILD_WITH_OPENMP`."""
+
+    cuda_enabled: bool
+    """Value of `WALBERLA_BUILD_WITH_CUDA`."""
+
+    hip_enabled: bool
+    """Value of `WALBERLA_BUILD_WITH_HIP`."""
+
+    likwid_enabled: bool
+    """Value of `WALBERLA_BUILD_WITH_LIKWID_MARKERS`"""
+
+    @staticmethod
+    def from_sfg(sfg: SfgContext | SfgIComposer) -> WalberlaBuildConfig:
+        if isinstance(sfg, SfgIComposer):
+            ctx = sfg.context
+        else:
+            ctx = sfg
+
+        if isinstance(ctx.project_info, WalberlaBuildConfig):
+            return ctx.project_info
+        else:
+            raise ValueError(
+                "The given SfgContext does not encapsulate a waLBerla build config object."
+            )
+
+    def get_pystencils_config(self) -> CreateKernelConfig:
+        dtype = Fp(64) if self.use_double_precision else Fp(32)
+
+        return CreateKernelConfig(
+            default_dtype=dtype,
+            jit=no_jit,
+        )