Skip to content
Snippets Groups Projects
Commit fe7f85a7 authored by Frederik Hennig's avatar Frederik Hennig Committed by Christoph Alt
Browse files

Add CONFIG_MODULE parameter to CMake function. Add Tests for CMake Integration.

parent 7de3cd0b
Branches
No related merge requests found
......@@ -74,6 +74,7 @@ find_package( PystencilsSfg )
Make sure to set the `Python_ROOT_DIR` cache variable to point to the correct Python interpreter
(i.e. the virtual environment you have installed *pystencils-sfg* into).
(cmake_add_generator_scripts)=
### Add generator scripts
The primary interaction point in CMake is the function `pystencilssfg_generate_target_sources`,
......@@ -85,6 +86,7 @@ pystencilssfg_generate_target_sources( <target>
[DEPENDS dependency1.py [dependency2.py...]]
[FILE_EXTENSIONS <header-extension> <impl-extension>]
[OUTPUT_MODE <standalone|inline|header-only>]
[CONFIG_MODULE <path-to-config-module.py>]
)
```
......@@ -97,6 +99,9 @@ The function takes the following options:
- `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 [](#cmake_set_config_module))
### Include generated files
......@@ -110,9 +115,13 @@ path, such that generated header files for a target `<target>` may be included v
(cmake_set_config_module)=
### Set a Configuration Module
To specify a [configuration module](#config_module) for your project,
set the scoped variable `PystencilsSfg_CONFIG_MODULE` to point at the respective Python file.
The pystencils-sfg CMake system will then pass that module to each generator script invocation.
There are two ways of specifying a [configuration module](#config_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 [](#cmake_add_generator_scripts)).
- 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.
......
......@@ -3,3 +3,6 @@ python_version=3.10
[mypy-pystencils.*]
ignore_missing_imports=true
[mypy-sympy.*]
ignore_missing_imports=true
......@@ -9,7 +9,7 @@ dependencies = [
]
requires-python = ">=3.10"
readme = "README.md"
license = { file = "COPYING.txt" }
license = { file = "LICENSE" }
dynamic = ["version"]
[project.scripts]
......
......@@ -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
......@@ -43,7 +43,7 @@ endfunction()
function(pystencilssfg_generate_target_sources TARGET)
set(options)
set(oneValueArgs OUTPUT_MODE)
set(oneValueArgs OUTPUT_MODE CONFIG_MODULE)
set(multiValueArgs SCRIPTS DEPENDS FILE_EXTENSIONS)
cmake_parse_arguments(_pssfg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
......@@ -53,21 +53,27 @@ function(pystencilssfg_generate_target_sources TARGET)
list(APPEND generatorArgs "--sfg-output-mode=${_pssfg_OUTPUT_MODE}")
endif()
if(DEFINED PystencilsSfg_CONFIGURATOR_SCRIPT)
message(AUTHOR_WARNING "The variable PystencilsSfg_CONFIGURATOR_SCRIPT is deprecated. Set PystencilsSfg_CONFIG_MODULE instead.")
cmake_path(ABSOLUTE_PATH PystencilsSfg_CONFIGURATOR_SCRIPT OUTPUT_VARIABLE configscript)
list(APPEND generatorArgs "--sfg-config-module=${configscript}")
list(APPEND _pssfg_DEPENDS ${configscript})
endif()
if(DEFINED PystencilsSfg_CONFIG_MODULE)
if(DEFINED _pssfg_CONFIG_MODULE)
cmake_path(ABSOLUTE_PATH _pssfg_CONFIG_MODULE OUTPUT_VARIABLE config_module)
list(APPEND generatorArgs "--sfg-config-module=${config_module}")
list(APPEND _pssfg_DEPENDS ${config_module})
else()
if(DEFINED PystencilsSfg_CONFIGURATOR_SCRIPT)
message(FATAL_ERROR "At most one of PystencilsSfg_CONFIGURATOR_SCRIPT and PystencilsSfg_CONFIG_MODULE may be set.")
message(AUTHOR_WARNING "The variable PystencilsSfg_CONFIGURATOR_SCRIPT is deprecated. Set PystencilsSfg_CONFIG_MODULE instead.")
cmake_path(ABSOLUTE_PATH PystencilsSfg_CONFIGURATOR_SCRIPT OUTPUT_VARIABLE configscript)
list(APPEND generatorArgs "--sfg-config-module=${configscript}")
list(APPEND _pssfg_DEPENDS ${configscript})
endif()
cmake_path(ABSOLUTE_PATH PystencilsSfg_CONFIG_MODULE OUTPUT_VARIABLE config_module)
list(APPEND generatorArgs "--sfg-config-module=${config_module}")
list(APPEND _pssfg_DEPENDS ${config_module})
if(DEFINED PystencilsSfg_CONFIG_MODULE)
if(DEFINED PystencilsSfg_CONFIGURATOR_SCRIPT)
message(FATAL_ERROR "At most one of PystencilsSfg_CONFIGURATOR_SCRIPT and PystencilsSfg_CONFIG_MODULE may be set.")
endif()
cmake_path(ABSOLUTE_PATH PystencilsSfg_CONFIG_MODULE OUTPUT_VARIABLE config_module)
list(APPEND generatorArgs "--sfg-config-module=${config_module}")
list(APPEND _pssfg_DEPENDS ${config_module})
endif()
endif()
if(DEFINED _pssfg_FILE_EXTENSIONS)
......
FindPystencilsSfg.cmake
\ No newline at end of file
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()
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};"
)
#include "gen/TestApp/GenTest.hpp"
int main(void) {
return int( gen::getValue() );
}
from pystencilssfg import SfgConfig
def configure_sfg(cfg: SfgConfig):
cfg.extensions.impl = "c++"
def project_info():
return 31
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
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment