diff --git a/source/fab/cli.py b/source/fab/cli.py index dc78c235..e4323a11 100644 --- a/source/fab/cli.py +++ b/source/fab/cli.py @@ -31,7 +31,8 @@ def _generic_build_config(folder: Path, kwargs=None) -> BuildConfig: project_label = 'zero_config_build' if kwargs: - project_label = kwargs.pop('project_label', 'zero_config_build') or project_label + project_label = kwargs.pop('project_label', + 'zero_config_build') or project_label # Set the default Fortran compiler as linker (otherwise e.g. the # C compiler might be used in linking, requiring additional flags) @@ -45,15 +46,18 @@ def _generic_build_config(folder: Path, kwargs=None) -> BuildConfig: tool_box.add_tool(fc) tool_box.add_tool(linker) # Within the fab workspace, we'll create a project workspace. - # Ideally we'd just use folder.name, but to avoid clashes, we'll use the full absolute path. + # Ideally we'd just use folder.name, but to avoid clashes, we'll use the + # full absolute path. with BuildConfig(project_label=project_label, mpi=False, openmp=False, tool_box=tool_box, **kwargs) as config: grab_folder(config, folder) find_source_files(config) - root_inc_files(config) # JULES helper, get rid of this eventually + # JULES helper, get rid of this eventually + root_inc_files(config, suffix_list=[".inc", ".h"]) preprocess_fortran(config) c_pragma_injector(config) - preprocess_c(config, source=CollectionGetter(ArtefactSet.C_COMPILER_FILES)) + preprocess_c(config, + source=CollectionGetter(ArtefactSet.C_COMPILER_FILES)) analyse(config, find_programs=True) compile_fortran(config) compile_c(config) @@ -67,9 +71,9 @@ def _generic_build_config(folder: Path, kwargs=None) -> BuildConfig: def cli_fab(folder: Optional[Path] = None, kwargs: Optional[Dict] = None): """ - Running Fab from the command line will attempt to build the project in the current or - given folder. The following params are used for testing. When run normally any parameters - will be caught by a common_arg_parser. + Running Fab from the command line will attempt to build the project in + the current or given folder. The following params are used for testing. + When run normally any parameters will be caught by a common_arg_parser. :param folder: source folder (Testing Only) @@ -79,9 +83,9 @@ def cli_fab(folder: Optional[Path] = None, kwargs: Optional[Dict] = None): """ kwargs = kwargs or {} - # We check if 'fab' was called directly. As it can be called by other things like 'pytest', - # the cli arguments may not apply to 'fab' which will cause arg_parser to fail with an - # invalid argument message. + # We check if 'fab' was called directly. As it can be called by other + # things like 'pytest', the cli arguments may not apply to 'fab' which + # will cause arg_parser to fail with an invalid argument message. if Path(sys.argv[0]).parts[-1] == 'fab': arg_parser = common_arg_parser() kwargs = vars(arg_parser.parse_args()) diff --git a/source/fab/steps/c_pragma_injector.py b/source/fab/steps/c_pragma_injector.py index 0b796512..71192236 100644 --- a/source/fab/steps/c_pragma_injector.py +++ b/source/fab/steps/c_pragma_injector.py @@ -9,11 +9,13 @@ """ import re from pathlib import Path -from typing import Generator, Pattern, Optional, Match +from typing import Generator, Match, Optional, Pattern, Tuple from fab import FabException +from fab.build_config import BuildConfig from fab.artefacts import ArtefactSet, ArtefactsGetter, SuffixFilter from fab.steps import run_mp, step +from fab.util import input_to_output_fpath DEFAULT_SOURCE_GETTER = SuffixFilter(ArtefactSet.C_COMPILER_FILES, '.c') @@ -21,13 +23,13 @@ # todo: test @step def c_pragma_injector(config, source: Optional[ArtefactsGetter] = None, - output_name=None): + output_name: Optional[ArtefactSet] = None) -> None: """ A build step to inject custom pragmas to mark blocks of user and system include statements. - By default, reads .c files from the *INITIAL_SOURCE_FILES* artefact and creates - the *pragmad_c* artefact. + By default, reads .c files from the *INITIAL_SOURCE_FILES* artefact and + creates the *pragmad_c* artefact. This step does not write to the build output folder, it creates the pragmad c in the same folder as the c file. This is because a subsequent @@ -50,15 +52,26 @@ def c_pragma_injector(config, source: Optional[ArtefactsGetter] = None, output_name = output_name or ArtefactSet.PRAGMAD_C files = source_getter(config.artefact_store) - results = run_mp(config, items=files, func=_process_artefact) + args = [(config, file) for file in files] + results = run_mp(config, items=args, func=_process_artefact) config.artefact_store[output_name] = set(results) config.artefact_store.replace(ArtefactSet.C_COMPILER_FILES, remove_files=files, add_files=results) -def _process_artefact(fpath: Path): - prag_output_fpath = fpath.with_suffix('.prag') +def _process_artefact(config_fpath: Tuple[BuildConfig, Path]) -> None: + ''' + Adds the pragmas to a given C file, and stores the modified file + with a ".prag" suffix in the output directory. + + :param config_fpath: a tuple of the config directory and the file + to process. + ''' + config, fpath = config_fpath + prag_output_fpath = input_to_output_fpath(config, + fpath.with_suffix('.prag')) + prag_output_fpath.parent.mkdir(parents=True, exist_ok=True) prag_output_fpath.open('w').writelines(inject_pragmas(fpath)) return prag_output_fpath diff --git a/tests/system_tests/CFortranInterop/test_CFortranInterop.py b/tests/system_tests/CFortranInterop/test_CFortranInterop.py index 1231c374..5313462c 100644 --- a/tests/system_tests/CFortranInterop/test_CFortranInterop.py +++ b/tests/system_tests/CFortranInterop/test_CFortranInterop.py @@ -18,6 +18,7 @@ from fab.steps.grab.folder import grab_folder from fab.steps.link import link_exe from fab.steps.preprocess import preprocess_fortran, preprocess_c +from fab.steps.root_inc_files import root_inc_files from fab.tools.tool_box import ToolBox clang = importorskip('clang', reason="Clang bindings not found.") @@ -32,6 +33,7 @@ def test_CFortranInterop(tmp_path): tool_box=ToolBox(), multiprocessing=False) as config: grab_folder(config, src=PROJECT_SOURCE) find_source_files(config) + root_inc_files(config, suffix_list=[".h"]) c_pragma_injector(config) preprocess_c(config) preprocess_fortran(config) diff --git a/tests/system_tests/CUserHeader/test_CUserHeader.py b/tests/system_tests/CUserHeader/test_CUserHeader.py index 44a3d7de..03ad2baf 100644 --- a/tests/system_tests/CUserHeader/test_CUserHeader.py +++ b/tests/system_tests/CUserHeader/test_CUserHeader.py @@ -17,6 +17,7 @@ from fab.steps.grab.folder import grab_folder from fab.steps.link import link_exe from fab.steps.preprocess import preprocess_c +from fab.steps.root_inc_files import root_inc_files from fab.tools.tool_box import ToolBox clang = importorskip('clang', reason="Clang bindings not found.") @@ -32,6 +33,7 @@ def test_CUseHeader(tmp_path): grab_folder(config, PROJECT_SOURCE) find_source_files(config) + root_inc_files(config, suffix_list=[".h"]) c_pragma_injector(config) preprocess_c(config) analyse(config, root_symbol='main')