diff --git a/source/fab/api.py b/source/fab/api.py index 5d31c79f..e16cf681 100644 --- a/source/fab/api.py +++ b/source/fab/api.py @@ -35,6 +35,7 @@ from fab.tools.flags import AlwaysFlags, ContainFlags, FlagList, MatchFlags from fab.tools.linker import Linker from fab.tools.pkg_config import PkgConfig +from fab.tools.preprocessor import Cpp, Fpp from fab.tools.tool import Tool from fab.tools.tool_box import ToolBox from fab.tools.tool_repository import ToolRepository @@ -61,11 +62,13 @@ "compile_fortran", "ContainFlags", "c_pragma_injector", + "Cpp", "Exclude", "FabBase", "fcm_export", "file_checksum", "FlagList", + "Fpp", "get_fab_workspace", "git_checkout", "grab_files", diff --git a/source/fab/steps/preprocess.py b/source/fab/steps/preprocess.py index a7f39928..4dca0010 100644 --- a/source/fab/steps/preprocess.py +++ b/source/fab/steps/preprocess.py @@ -119,7 +119,7 @@ def process_artefact(arg: tuple[Path, MpCommonArgs]): f"'{' '.join(flags)}'.'") try: args.preprocessor.preprocess(input_fpath, output_fpath, - flags) + args.config, flags) except Exception as err: raise Exception(f"error preprocessing {input_fpath}:\n" f"{err}") from err diff --git a/source/fab/tools/preprocessor.py b/source/fab/tools/preprocessor.py index 3de75f6d..f4a22a86 100644 --- a/source/fab/tools/preprocessor.py +++ b/source/fab/tools/preprocessor.py @@ -12,6 +12,7 @@ from pathlib import Path from typing import Optional, Sequence, Union +from fab.build_config import BuildConfig from fab.tools.category import Category from fab.tools.tool_with_flags import ToolWithFlags @@ -31,19 +32,23 @@ def __init__(self, name: str, exec_name: Union[str, Path], availability_option=availability_option) self._version = None - def preprocess(self, input_file: Path, output_file: Path, + def preprocess(self, + input_file: Path, + output_file: Path, + config: "BuildConfig", add_flags: Optional[Sequence[Union[Path, str]]] = None): '''Calls the preprocessor to process the specified input file, creating the requested output file. :param input_file: input file. :param output_file: the output filename. + :param config: the build config, used to access mode-specific flags. :param add_flags: list with additional flags to be used. ''' params: list[Union[str, Path]] = [] + params.extend(self.flags.get_flags(config, input_file)) if add_flags: - # Make a copy to avoid modifying the caller's list - params = list(add_flags) + params.extend(add_flags) # Input and output files come as the last two parameters params.extend([input_file, output_file]) @@ -64,9 +69,9 @@ class CppFortran(Preprocessor): ''' def __init__(self): super().__init__("cpp", "cpp", Category.FORTRAN_PREPROCESSOR) - self.add_flags(["-traditional-cpp", "-P"]) def preprocess(self, input_file: Path, output_file: Path, + config: BuildConfig, add_flags: Optional[Sequence[Union[Path, str]]] = None): '''Calls the preprocessor to process the specified input file, creating the requested output file. @@ -80,7 +85,7 @@ def preprocess(self, input_file: Path, output_file: Path, if add_flags: params.extend(add_flags) - super().preprocess(input_file, output_file, params) + super().preprocess(input_file, output_file, config, params) # ============================================================================ diff --git a/tests/unit_tests/tools/test_preprocessor.py b/tests/unit_tests/tools/test_preprocessor.py index 6470600c..c1fd1667 100644 --- a/tests/unit_tests/tools/test_preprocessor.py +++ b/tests/unit_tests/tools/test_preprocessor.py @@ -12,6 +12,7 @@ from pytest import mark from pytest_subprocess.fake_process import FakeProcess +from fab.build_config import BuildConfig from fab.tools.category import Category from fab.tools.preprocessor import Cpp, CppFortran, Fpp, Preprocessor @@ -44,6 +45,9 @@ def test_fpp_is_available(rc, fake_process: FakeProcess) -> None: class TestCpp: + """ + Tests the C preprocessor. + """ def test_cpp(self, subproc_record: ExtendedRecorder) -> None: """ Tests the CPP tool. @@ -53,6 +57,9 @@ def test_cpp(self, subproc_record: ExtendedRecorder) -> None: assert subproc_record.invocations() == [['cpp', '--version']] def test_is_not_available(self, fake_process: FakeProcess) -> None: + """ + Tests if a preprocessor is not abailable + """ fake_process.register(['cpp', '--version'], returncode=1) cpp = Cpp() assert cpp.is_available is False @@ -60,9 +67,13 @@ def test_is_not_available(self, fake_process: FakeProcess) -> None: class TestCppTraditional: + """ + Tests to verify that the traditional flags is used for the standard + preprocessor in Fortran mode. + """ def test_is_not_available(self, fake_process: FakeProcess) -> None: """ - Tests CPP in "traditional" mode. + Tests CPP in "traditional" mode when the tool is not available. """ command = ['cpp', '--version'] fake_process.register(command, returncode=1) @@ -71,12 +82,20 @@ def test_is_not_available(self, fake_process: FakeProcess) -> None: assert cppf.is_available is False assert call_list(fake_process) == [command] - def test_preprocess(self, subproc_record: ExtendedRecorder) -> None: + def test_preprocess(self, + stub_configuration: BuildConfig, + subproc_record: ExtendedRecorder) -> None: + """Tests the combination of various sources of flags: + tool and additional flags. + """ cppf = CppFortran() - cppf.preprocess(Path("a.in"), Path("a.out")) - cppf.preprocess(Path("a.in"), Path("a.out"), ["-DDO_SOMETHING"]) + cppf.add_flags(["-Dtool-specific-flag"]) + cppf.preprocess(Path("a.in"), Path("a.out"), stub_configuration) + cppf.preprocess(Path("a.in"), Path("a.out"), stub_configuration, + ["-DDO_SOMETHING"]) assert subproc_record.invocations() == [ - ["cpp", "-traditional-cpp", "-P", "a.in", "a.out"], - ["cpp", "-traditional-cpp", "-P", "-DDO_SOMETHING", - "a.in", "a.out"] + ["cpp", "-Dtool-specific-flag", "-traditional-cpp", "-P", "a.in", + "a.out"], + ["cpp", "-Dtool-specific-flag", "-traditional-cpp", "-P", + "-DDO_SOMETHING", "a.in", "a.out"] ]