diff --git a/integration/test_cuda.py b/integration/test_cuda.py
index 56a478c7b08e684fb03398b5b7cb951982336fe8..6b1f1f439c6dc3adbbca73f8a56f676ac9951ef2 100644
--- a/integration/test_cuda.py
+++ b/integration/test_cuda.py
@@ -1,13 +1,11 @@
-from pystencils import Target, CreateKernelConfig, create_kernel, no_jit
+from pystencils import Target, CreateKernelConfig, no_jit
 from lbmpy import create_lb_update_rule, LBMOptimisation
-from pystencilssfg import SourceFileGenerator, SfgConfiguration
-from pystencilssfg.lang.cpp import mdspan_ref
+from pystencilssfg import SourceFileGenerator, SfgConfig
 
-sfg_config = SfgConfiguration(
-    output_directory="out/test_cuda",
-    outer_namespace="gen_code",
-    impl_extension="cu"
-)
+sfg_config = SfgConfig()
+sfg_config.extensions.impl = "cu"
+sfg_config.output_directory = "out/test_cuda"
+sfg_config.outer_namespace = "gen_code"
 
 with SourceFileGenerator(sfg_config) as sfg:
     gen_config = CreateKernelConfig(target=Target.CUDA, jit=no_jit)
@@ -15,6 +13,4 @@ with SourceFileGenerator(sfg_config) as sfg:
     update = create_lb_update_rule()
     kernel = sfg.kernels.create(update, "lbm_update", gen_config)
 
-    sfg.function("lb_update")(
-        sfg.call(kernel)
-    )
+    sfg.function("lb_update")(sfg.call(kernel))
diff --git a/mypy.ini b/mypy.ini
index ca7990ba101438a4b0bebc14824640a2f0c29479..efef4eab417220d306836a87754293a3f9510aeb 100644
--- a/mypy.ini
+++ b/mypy.ini
@@ -3,3 +3,6 @@ python_version=3.10
 
 [mypy-pystencils.*]
 ignore_missing_imports=true
+
+[mypy-sympy.*]
+ignore_missing_imports=true
diff --git a/pyproject.toml b/pyproject.toml
index f942a18536ef30209cf48ecc320b4e625fd30a6c..b787da5c7180e32c6751bc8c78c2532f693382e2 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -9,7 +9,7 @@ dependencies = [
 ]
 requires-python = ">=3.10"
 readme = "README.md"
-license = { file = "COPYING.txt" }
+license = { file = "LICENSE" }
 dynamic = ["version"]
 
 [project.scripts]
diff --git a/pytest.ini b/pytest.ini
index 91afe80606639eb5ad33c77d899d7eb57b91d107..dd91f5271f8dd399e22854b40ec42abb7e0f6728 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -9,5 +9,6 @@ addopts =
     --ignore=tests/generator_scripts/deps
     --ignore=tests/generator_scripts/expected
     --ignore=tests/data
+    --ignore=tests/integration/cmake_project
 
 doctest_optionflags = NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL
diff --git a/src/pystencilssfg/lang/headers.py b/src/pystencilssfg/lang/headers.py
index fdb8f17be3ddbe177994c67099cebeaeb719b67e..550dd4d4c17e4d8bc6d3bfb83e498ce41f32eb14 100644
--- a/src/pystencilssfg/lang/headers.py
+++ b/src/pystencilssfg/lang/headers.py
@@ -24,6 +24,9 @@ class HeaderFile:
             return header
 
         system_header = False
+        if header.startswith('"') and header.endswith('"'):
+            header = header[1:-1]
+
         if header.startswith("<") and header.endswith(">"):
             header = header[1:-1]
             system_header = True
diff --git a/tests/integration/cmake_project/.gitignore b/tests/integration/cmake_project/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..2f4eb1ab954a587388367711592b5aa8d8f483b8
--- /dev/null
+++ b/tests/integration/cmake_project/.gitignore
@@ -0,0 +1 @@
+FindPystencilsSfg.cmake
\ No newline at end of file
diff --git a/tests/integration/cmake_project/CMakeLists.txt b/tests/integration/cmake_project/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..efee91238eec893bc523f5df4710b0d40125a2b2
--- /dev/null
+++ b/tests/integration/cmake_project/CMakeLists.txt
@@ -0,0 +1,28 @@
+cmake_minimum_required( VERSION 3.22 )
+project( sfg_cmake_project_test )
+
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+find_package( PystencilsSfg REQUIRED )
+
+set( UseGlobalCfgModule OFF CACHE BOOL "Specify config module globally" )
+set( UseLocalCfgModule OFF CACHE BOOL "Specify config module locally" )
+
+if( $CACHE{UseGlobalCfgModule} )
+    set( PystencilsSfg_CONFIG_MODULE ${CMAKE_CURRENT_SOURCE_DIR}/gen_config.py )
+endif()
+
+add_executable( TestApp TestApp.cpp )
+
+if( $CACHE{UseLocalCfgModule} )
+    pystencilssfg_generate_target_sources(
+        TestApp
+        SCRIPTS GenTest.py
+        CONFIG_MODULE ${CMAKE_CURRENT_SOURCE_DIR}/gen_config.py
+    )
+else()
+    pystencilssfg_generate_target_sources(
+        TestApp
+        SCRIPTS GenTest.py
+    )
+endif()
diff --git a/tests/integration/cmake_project/GenTest.py b/tests/integration/cmake_project/GenTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..8399e7061ae79b5b3a8c0fe6c3d544f0b5d6f586
--- /dev/null
+++ b/tests/integration/cmake_project/GenTest.py
@@ -0,0 +1,10 @@
+from pystencilssfg import SourceFileGenerator
+
+with SourceFileGenerator() as sfg:
+    sfg.namespace("gen")
+
+    retval = 42 if sfg.context.project_info is None else sfg.context.project_info
+
+    sfg.function("getValue", return_type="int")(
+        f"return {retval};"
+    )
diff --git a/tests/integration/cmake_project/TestApp.cpp b/tests/integration/cmake_project/TestApp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7ceb98b42f40e6c91dddad76170b4654e14d4851
--- /dev/null
+++ b/tests/integration/cmake_project/TestApp.cpp
@@ -0,0 +1,5 @@
+#include "gen/TestApp/GenTest.hpp"
+
+int main(void) {
+    return int( gen::getValue() );
+}
diff --git a/tests/integration/cmake_project/gen_config.py b/tests/integration/cmake_project/gen_config.py
new file mode 100644
index 0000000000000000000000000000000000000000..3a62d2808b3356d0a9031a585a464e4f6f8151b5
--- /dev/null
+++ b/tests/integration/cmake_project/gen_config.py
@@ -0,0 +1,9 @@
+from pystencilssfg import SfgConfig
+
+
+def configure_sfg(cfg: SfgConfig):
+    cfg.extensions.impl = "c++"
+
+
+def project_info():
+    return 31
diff --git a/tests/integration/test_cmake.py b/tests/integration/test_cmake.py
new file mode 100644
index 0000000000000000000000000000000000000000..21091583114094e2639818ea6da01eb8db44b009
--- /dev/null
+++ b/tests/integration/test_cmake.py
@@ -0,0 +1,37 @@
+import pytest
+
+import pathlib
+import subprocess
+
+THIS_DIR = pathlib.Path(__file__).parent
+
+CMAKE_PROJECT_DIRNAME = "cmake_project"
+CMAKE_PROJECT_DIR = THIS_DIR / CMAKE_PROJECT_DIRNAME
+
+
+@pytest.mark.parametrize("config_source", [None, "UseGlobalCfgModule", "UseLocalCfgModule"])
+def test_cmake_project(tmp_path, config_source):
+    obtain_find_module_cmd = ["sfg-cli", "cmake", "make-find-module"]
+
+    result = subprocess.run(obtain_find_module_cmd, cwd=CMAKE_PROJECT_DIR)
+    assert result.returncode == 0
+
+    cmake_configure_cmd = ["cmake", "-S", CMAKE_PROJECT_DIR, "-B", str(tmp_path)]
+    if config_source is not None:
+        cmake_configure_cmd.append(f"-D{config_source}=ON")
+    configure_result = subprocess.run(cmake_configure_cmd)
+    assert configure_result.returncode == 0
+
+    cmake_build_cmd = ["cmake", "--build", str(tmp_path), "--target", "TestApp"]
+    build_result = subprocess.run(cmake_build_cmd)
+    assert build_result.returncode == 0
+
+    run_cmd = [str(tmp_path / "TestApp")]
+    run_result = subprocess.run(run_cmd)
+
+    if config_source is not None:
+        assert (tmp_path / "sfg_sources" / "gen" / "TestApp" / "GenTest.c++").exists()
+        assert run_result.returncode == 31
+    else:
+        assert (tmp_path / "sfg_sources" / "gen" / "TestApp" / "GenTest.cpp").exists()
+        assert run_result.returncode == 42
diff --git a/tests/lang/test_headers.py b/tests/lang/test_headers.py
new file mode 100644
index 0000000000000000000000000000000000000000..3eaf040bc159f91556abb039d921ba81ee0228fe
--- /dev/null
+++ b/tests/lang/test_headers.py
@@ -0,0 +1,13 @@
+from pystencilssfg.lang import HeaderFile
+import pytest
+
+
+def test_parse_system():
+    headerfile = HeaderFile.parse("<test>")
+    assert str(headerfile) == "<test>" and headerfile.system_header
+
+
+@pytest.mark.parametrize("header_string", ["test.hpp", '"test.hpp"'])
+def test_parse_private(header_string):
+    headerfile = HeaderFile.parse(header_string)
+    assert str(headerfile) == "test.hpp" and not headerfile.system_header