Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions source/fab/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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())
Expand Down
27 changes: 20 additions & 7 deletions source/fab/steps/c_pragma_injector.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,27 @@
"""
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')


# 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
Expand All @@ -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

Expand Down
2 changes: 2 additions & 0 deletions tests/system_tests/CFortranInterop/test_CFortranInterop.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.")
Expand All @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions tests/system_tests/CUserHeader/test_CUserHeader.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.")
Expand All @@ -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')
Expand Down
Loading