From ab978807fc18caabf81ba5ff1f02fcd07132dcbc Mon Sep 17 00:00:00 2001 From: Frederik Hennig <frederik.hennig@fau.de> Date: Mon, 20 Nov 2023 14:23:24 +0900 Subject: [PATCH] extended cmake support via command-line interface --- src/pystencilssfg/cli.py | 50 ++++++++++++++----- .../cmake}/FindPystencilsSfg.cmake | 6 +-- src/pystencilssfg/cmake/__init__.py | 11 +++- .../PystencilsSfg.cmake} | 2 +- tests/cmake_integration/.gitignore | 1 + tests/cmake_integration/CMakeLists.txt | 6 ++- 6 files changed, 57 insertions(+), 19 deletions(-) rename {cmake => src/pystencilssfg/cmake}/FindPystencilsSfg.cmake (74%) rename src/pystencilssfg/cmake/{PystencilsSfgFunctions.cmake => modules/PystencilsSfg.cmake} (97%) create mode 100644 tests/cmake_integration/.gitignore diff --git a/src/pystencilssfg/cli.py b/src/pystencilssfg/cli.py index 458c1fe..a832642 100644 --- a/src/pystencilssfg/cli.py +++ b/src/pystencilssfg/cli.py @@ -1,7 +1,8 @@ import sys +import os from os import path -from argparse import ArgumentParser +from argparse import ArgumentParser, BooleanOptionalAction from .configuration import ( SfgConfigException, SfgConfigSource, @@ -9,25 +10,40 @@ from .configuration import ( ) +def add_newline_arg(parser): + parser.add_argument("--newline", action=BooleanOptionalAction, default=True, + help="Whether to add a terminating newline to the output.") + + def cli_main(program='sfg-cli'): parser = ArgumentParser(program, - description="pystencilssfg command-line utility") + description="pystencilssfg command-line utility for build system integration") subparsers = parser.add_subparsers(required=True, title="Subcommands") - version_parser = subparsers.add_parser( - "version", help="Print version and exit.") + version_parser = subparsers.add_parser("version", help="Print version and exit.") + add_newline_arg(version_parser) 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") + add_config_args_to_parser(outfiles_parser) + add_newline_arg(outfiles_parser) + outfiles_parser.add_argument("--sep", type=str, default=" ", dest="sep", help="Separator for list items") outfiles_parser.add_argument("codegen_script", type=str) - add_config_args_to_parser(outfiles_parser) + cmake_parser = subparsers.add_parser("cmake", help="Operations for CMake integation") + cmake_subparsers = cmake_parser.add_subparsers(required=True) + + modpath = cmake_subparsers.add_parser("modulepath", help="Print the include path for the pystencils-sfg cmake module") + add_newline_arg(modpath) + modpath.set_defaults(func=print_cmake_modulepath) + + findmod = cmake_subparsers.add_parser("make-find-module", + help="Creates the pystencils-sfg CMake find module as 'FindPystencilsSfg.cmake' in the current directory.") + findmod.set_defaults(func=make_cmake_find_module) args = parser.parse_args() args.func(args) @@ -37,7 +53,9 @@ def cli_main(program='sfg-cli'): def version(args): from . import __version__ - print(__version__) + + print(__version__, end=os.linesep if args.newline else '') + exit(0) @@ -49,20 +67,28 @@ def list_files(args): config = merge_configurations(project_config, cmdline_config, None) - scriptdir, scriptname = path.split(args.codegen_script) + _, 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="") + print(args.sep.join(emitter.output_files), end=os.linesep if args.newline else '') exit(0) +def print_cmake_modulepath(args): + from .cmake import get_sfg_cmake_modulepath + print(get_sfg_cmake_modulepath(), end=os.linesep if args.newline else '') + + +def make_cmake_find_module(args): + from .cmake import make_find_module + make_find_module() + + def abort_with_config_exception(exception: SfgConfigException): def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) diff --git a/cmake/FindPystencilsSfg.cmake b/src/pystencilssfg/cmake/FindPystencilsSfg.cmake similarity index 74% rename from cmake/FindPystencilsSfg.cmake rename to src/pystencilssfg/cmake/FindPystencilsSfg.cmake index bdc5132..c1affee 100644 --- a/cmake/FindPystencilsSfg.cmake +++ b/src/pystencilssfg/cmake/FindPystencilsSfg.cmake @@ -6,7 +6,7 @@ find_package( Python COMPONENTS Interpreter REQUIRED ) # Try to find pystencils-sfg in the python environment -execute_process(COMMAND ${Python_EXECUTABLE} -c "import pystencilssfg; print(pystencilssfg.__version__, end='')" +execute_process(COMMAND ${Python_EXECUTABLE} -m pystencilssfg version --no-newline RESULT_VARIABLE _PystencilsSfgFindResult OUTPUT_VARIABLE PystencilsSfg_VERSION ) if(${_PystencilsSfgFindResult} EQUAL 0) @@ -20,10 +20,10 @@ endif() if(${PystencilsSfg_FOUND}) message( STATUS "Found pystencils Source File Generator (Version ${PystencilsSfg_VERSION})") - execute_process(COMMAND ${Python_EXECUTABLE} -c "from pystencilssfg.cmake import get_sfg_cmake_modulepath; print(get_sfg_cmake_modulepath(), end='')" + execute_process(COMMAND ${Python_EXECUTABLE} -m pystencilssfg cmake modulepath --no-newline OUTPUT_VARIABLE _PystencilsSfg_CMAKE_MODULE_PATH) set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${_PystencilsSfg_CMAKE_MODULE_PATH}) - include( PystencilsSfgFunctions ) + include( PystencilsSfg ) endif() diff --git a/src/pystencilssfg/cmake/__init__.py b/src/pystencilssfg/cmake/__init__.py index 7e08187..39b3cb6 100644 --- a/src/pystencilssfg/cmake/__init__.py +++ b/src/pystencilssfg/cmake/__init__.py @@ -1,5 +1,12 @@ -from os.path import dirname, realpath +from os.path import dirname, realpath, join +import shutil def get_sfg_cmake_modulepath(): - return dirname(realpath(__file__)) + return join(dirname(realpath(__file__)), "modules") + + +def make_find_module(): + cmake_dir = dirname(realpath(__file__)) + find_module_file = join(cmake_dir, "FindPystencilsSfg.cmake") + shutil.copy(find_module_file, "FindPystencilsSfg.cmake") diff --git a/src/pystencilssfg/cmake/PystencilsSfgFunctions.cmake b/src/pystencilssfg/cmake/modules/PystencilsSfg.cmake similarity index 97% rename from src/pystencilssfg/cmake/PystencilsSfgFunctions.cmake rename to src/pystencilssfg/cmake/modules/PystencilsSfg.cmake index 3af2a29..b2d98f2 100644 --- a/src/pystencilssfg/cmake/PystencilsSfgFunctions.cmake +++ b/src/pystencilssfg/cmake/modules/PystencilsSfg.cmake @@ -19,7 +19,7 @@ function(_pssfg_add_gen_source target script) get_filename_component(basename ${script} NAME_WLE) cmake_path(ABSOLUTE_PATH script OUTPUT_VARIABLE scriptAbsolute) - execute_process(COMMAND ${Python_EXECUTABLE} -m pystencilssfg list-files --format=cmake ${_pssfg_GENERATOR_ARGS} ${script} + execute_process(COMMAND ${Python_EXECUTABLE} -m pystencilssfg list-files "--sep=\;" --no-newline ${_pssfg_GENERATOR_ARGS} ${script} OUTPUT_VARIABLE generatedSources RESULT_VARIABLE _pssfg_result ERROR_VARIABLE _pssfg_stderr) diff --git a/tests/cmake_integration/.gitignore b/tests/cmake_integration/.gitignore new file mode 100644 index 0000000..facd9a1 --- /dev/null +++ b/tests/cmake_integration/.gitignore @@ -0,0 +1 @@ +.cmake \ No newline at end of file diff --git a/tests/cmake_integration/CMakeLists.txt b/tests/cmake_integration/CMakeLists.txt index d107541..54769ad 100644 --- a/tests/cmake_integration/CMakeLists.txt +++ b/tests/cmake_integration/CMakeLists.txt @@ -2,7 +2,11 @@ cmake_minimum_required( VERSION 3.24 ) project( pssfg_cmake_integration_test ) -set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${pssfg_cmake_integration_test_SOURCE_DIR}/../../cmake ) +set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${pssfg_cmake_integration_test_SOURCE_DIR}/.cmake ) + +# Don't try this at home! +execute_process( COMMAND sfg-cli cmake make-find-module + WORKING_DIRECTORY ${pssfg_cmake_integration_test_SOURCE_DIR}/.cmake ) find_package( PystencilsSfg REQUIRED ) -- GitLab