diff --git a/.gitignore b/.gitignore index bbbd4e1fed3e6666ccd721036b1b7a6edfe9cb3a..6bccaaee4d029027cf3491ecbff30df8b3054aad 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ .pdm-python # build artifacts +dist *.tar.gz *.whl *.egg-info diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000000000000000000000000000000000000..62a5456a9347c8768b5305270b1e850ff5b26c8a --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include src/pystencilssfg/cmake/*.cmake \ No newline at end of file diff --git a/cmake/FindPystencilsSfg.cmake b/cmake/FindPystencilsSfg.cmake index 27eb1c01bdb06a7cf730d229f423c64f0dc68a6d..bdc5132d42335afe8cbce49872ddf5d6c0b51b48 100644 --- a/cmake/FindPystencilsSfg.cmake +++ b/cmake/FindPystencilsSfg.cmake @@ -1,5 +1,4 @@ set( PystencilsSfg_FOUND OFF CACHE BOOL "pystencils source file generator found" ) -set( PystencilsSfg_CONFIGURATOR_SCRIPT "" CACHE STRING "Configurator script for the pystencils source file generator" ) mark_as_advanced( PystencilsSfg_FOUND ) diff --git a/pyproject.toml b/pyproject.toml index e8ce266e1c0ec9c2b2e02a0deab988926ecc88b4..4e241ff535ccbeb055f7d6621854852d1aa4b62f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,9 @@ readme = "README.md" license = {text = "noneyet"} dynamic = ["version"] +[project.scripts] +sfg-cli = "pystencilssfg.cli:cli_main" + [build-system] requires = ["setuptools>=61", "versioneer>=0.29"] build-backend = "setuptools.build_meta" diff --git a/src/pystencilssfg/__main__.py b/src/pystencilssfg/__main__.py index 3c793c464fd8762c21bbcf932e81496d09019a84..ce41802d0392490b67433f3429ac38a90d3373f2 100644 --- a/src/pystencilssfg/__main__.py +++ b/src/pystencilssfg/__main__.py @@ -1,80 +1,4 @@ -import sys -from os import path -from argparse import ArgumentParser - -from .configuration import ( - SfgConfigException, SfgConfigSource, - add_config_args_to_parser, config_from_parser_args, merge_configurations -) - - -def main(): - parser = ArgumentParser("pystencilssfg", - description="pystencilssfg command-line utility") - - subparsers = parser.add_subparsers(required=True, title="Subcommands") - - version_parser = subparsers.add_parser( - "version", help="Print version and exit.") - version_parser.set_defaults(func=version) - - outfiles_parser = subparsers.add_parser( - "list-files", help="List files produced by given codegen script.") - - outfiles_parser.set_defaults(func=list_files) - outfiles_parser.add_argument( - "--format", type=str, choices=("human", "cmake"), default="human") - outfiles_parser.add_argument("codegen_script", type=str) - - add_config_args_to_parser(outfiles_parser) - - args = parser.parse_args() - args.func(args) - - -def version(args, argv): - from . import __version__ - print(__version__) - exit(0) - - -def list_files(args): - try: - project_config, cmdline_config = config_from_parser_args(args) - except SfgConfigException as exc: - abort_with_config_exception(exc) - - config = merge_configurations(project_config, cmdline_config, None) - - scriptdir, scriptname = path.split(args.codegen_script) - basename = path.splitext(scriptname)[0] - - from .emitters.cpu.basic_cpu import BasicCpuEmitter - - emitter = BasicCpuEmitter(basename, config) - - match args.format: - case "human": print(" ".join(emitter.output_files)) - case "cmake": print(";".join(emitter.output_files), end="") - - exit(0) - - -def abort_with_config_exception(exception: SfgConfigException): - def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) - - match exception.config_source: - case SfgConfigSource.PROJECT: - eprint( - f"Invalid project configuration: {exception.message}\nCheck your configurator script.") - case SfgConfigSource.COMMANDLINE: - eprint( - f"Invalid configuration on command line: {exception.message}") - case _: assert False, "(Theoretically) unreachable code. Contact the developers." - - exit(1) - - -main() +if __name__ == "__main__": + from .cli import cli_main + cli_main("python -m pystencilssfg") diff --git a/src/pystencilssfg/cli.py b/src/pystencilssfg/cli.py new file mode 100644 index 0000000000000000000000000000000000000000..458c1fe6ae75649bbde9df46ebf88a3d7cf26455 --- /dev/null +++ b/src/pystencilssfg/cli.py @@ -0,0 +1,79 @@ +import sys +from os import path + +from argparse import ArgumentParser + +from .configuration import ( + SfgConfigException, SfgConfigSource, + add_config_args_to_parser, config_from_parser_args, merge_configurations +) + + +def cli_main(program='sfg-cli'): + parser = ArgumentParser(program, + description="pystencilssfg command-line utility") + + subparsers = parser.add_subparsers(required=True, title="Subcommands") + + version_parser = subparsers.add_parser( + "version", help="Print version and exit.") + version_parser.set_defaults(func=version) + + outfiles_parser = subparsers.add_parser( + "list-files", help="List files produced by given codegen script.") + + outfiles_parser.set_defaults(func=list_files) + outfiles_parser.add_argument( + "--format", type=str, choices=("human", "cmake"), default="human") + outfiles_parser.add_argument("codegen_script", type=str) + + add_config_args_to_parser(outfiles_parser) + + args = parser.parse_args() + args.func(args) + + exit(-1) # should never happen + + +def version(args): + from . import __version__ + print(__version__) + exit(0) + + +def list_files(args): + try: + project_config, cmdline_config = config_from_parser_args(args) + except SfgConfigException as exc: + abort_with_config_exception(exc) + + config = merge_configurations(project_config, cmdline_config, None) + + scriptdir, scriptname = path.split(args.codegen_script) + basename = path.splitext(scriptname)[0] + + from .emitters.cpu.basic_cpu import BasicCpuEmitter + + emitter = BasicCpuEmitter(basename, config) + + match args.format: + case "human": print(" ".join(emitter.output_files)) + case "cmake": print(";".join(emitter.output_files), end="") + + exit(0) + + +def abort_with_config_exception(exception: SfgConfigException): + def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + + match exception.config_source: + case SfgConfigSource.PROJECT: + eprint( + f"Invalid project configuration: {exception.message}\nCheck your configurator script.") + case SfgConfigSource.COMMANDLINE: + eprint( + f"Invalid configuration on command line: {exception.message}") + case _: assert False, "(Theoretically) unreachable code. Contact the developers." + + exit(1) diff --git a/src/pystencilssfg/cmake/PystencilsSfgFunctions.cmake b/src/pystencilssfg/cmake/PystencilsSfgFunctions.cmake index 0817bf2b0c8096bcacc7328c670df84233e43153..3af2a29c75ebc7f4e1bf7a367bfb7e03573b6a7f 100644 --- a/src/pystencilssfg/cmake/PystencilsSfgFunctions.cmake +++ b/src/pystencilssfg/cmake/PystencilsSfgFunctions.cmake @@ -1,9 +1,11 @@ -set(PSSFG_CONFIGURATOR_SCRIPT "" CACHE FILEPATH "Configurator script for the pystencils Source File Generator" ) +set(PystencilsSfg_CONFIGURATOR_SCRIPT "" CACHE FILEPATH "Configurator script for the pystencils Source File Generator" ) +set(PystencilsSfg_GENERATED_SOURCES_DIR "${CMAKE_BINARY_DIR}/sfg_sources" CACHE PATH "Output directory for genenerated sources" ) -set(PSSFG_GENERATED_SOURCES_DIR "${CMAKE_BINARY_DIR}/pystencils_generated_sources") -file(MAKE_DIRECTORY "${PSSFG_GENERATED_SOURCES_DIR}") -include_directories(${PSSFG_GENERATED_SOURCES_DIR}) +mark_as_advanced(PystencilsSfg_GENERATED_SOURCES_DIR) + +file(MAKE_DIRECTORY "${PystencilsSfg_GENERATED_SOURCES_DIR}") +include_directories(${PystencilsSfg_GENERATED_SOURCES_DIR}) function(_pssfg_add_gen_source target script) @@ -13,7 +15,7 @@ function(_pssfg_add_gen_source target script) cmake_parse_arguments(_pssfg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - set(generatedSourcesDir ${PSSFG_GENERATED_SOURCES_DIR}/gen/${target}) + set(generatedSourcesDir ${PystencilsSfg_GENERATED_SOURCES_DIR}/${target}) get_filename_component(basename ${script} NAME_WLE) cmake_path(ABSOLUTE_PATH script OUTPUT_VARIABLE scriptAbsolute) @@ -46,16 +48,14 @@ function(pystencilssfg_generate_target_sources TARGET) set(multiValueArgs SCRIPTS DEPENDS FILE_EXTENSIONS) cmake_parse_arguments(_pssfg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - set(generatedSourcesDir ${PSSFG_GENERATED_SOURCES_DIR}/gen/${_pssfg_TARGET}) - set(generatorArgs) if(_pssfg_HEADER_ONLY) list(APPEND generatorArgs "--sfg-header-only") endif() - if(NOT (PSSFG_CONFIGURATOR_SCRIPT STREQUAL "")) - list(APPEND generatorArgs "--sfg-configurator='${_pssfg_CONFIGURATOR_SCRIPT}'") + if(NOT (PystencilsSfg_CONFIGURATOR_SCRIPT STREQUAL "")) + list(APPEND generatorArgs "--sfg-configurator='${_PystencilsSfg_CONFIGURATOR_SCRIPT}'") endif() if(DEFINED _pssfg_FILE_EXTENSIONS)