diff --git a/source/fab/tools/tool_repository.py b/source/fab/tools/tool_repository.py index 0c65030d..b633964d 100644 --- a/source/fab/tools/tool_repository.py +++ b/source/fab/tools/tool_repository.py @@ -294,6 +294,9 @@ def get_default(self, category: Category, if category == Category.LINKER: tool = cast(Linker, tool) compiler = tool.compiler + # Find the real compiler if we have a compiler wrapper: + while isinstance(compiler, CompilerWrapper): + compiler = compiler.compiler # Ignore C linker if Fortran is requested and vice versa: if (enforce_fortran_linker and not isinstance(compiler, FortranCompiler)): diff --git a/tests/unit_tests/tools/test_tool_repository.py b/tests/unit_tests/tools/test_tool_repository.py index 3e4a803c..5fb42b5a 100644 --- a/tests/unit_tests/tools/test_tool_repository.py +++ b/tests/unit_tests/tools/test_tool_repository.py @@ -15,7 +15,8 @@ from fab.tools.ar import Ar from fab.tools.category import Category from fab.tools.compiler import Compiler, FortranCompiler, Gfortran, Ifort -from fab.tools.compiler_wrapper import Mpif90 +from fab.tools.compiler_wrapper import Mpicc, Mpif90 +from fab.tools.linker import Linker from fab.tools.tool_repository import ToolRepository from tests.conftest import call_list @@ -125,6 +126,33 @@ def test_get_default(stub_tool_repository, stub_fortran_compiler, assert isinstance(ar, Ar) +def test_get_default_linker_with_wrapper(stub_tool_repository, + stub_fortran_compiler, + stub_c_compiler) -> None: + """ + Tests that we get the right linker if compiler wrapper are used. + """ + + # Add a linker around a compiler wrapper, to test that the compiler + # wrapper is recognised as a Fortran compiler: + linker = Linker(Mpif90(stub_fortran_compiler)) + linker._is_available = True + stub_tool_repository.add_tool(linker) + for_link = stub_tool_repository.get_default(Category.LINKER, mpi=True, + openmp=True, + enforce_fortran_linker=True) + assert for_link is linker + + # Now the same for a linker around a C compiler wrapper: + linker = Linker(Mpicc(stub_c_compiler)) + linker._is_available = True + stub_tool_repository.add_tool(linker) + cc_link = stub_tool_repository.get_default(Category.LINKER, mpi=True, + openmp=True, + enforce_fortran_linker=False) + assert cc_link is linker + + def test_get_default_error_invalid_category() -> None: """ Tests error handling in get_default, the category must be a Category, @@ -152,6 +180,11 @@ def test_get_default_error_missing_mpi() -> None: assert str(err.value) == ("Invalid or missing openmp specification " "for 'FORTRAN_COMPILER'.") + with raises(RuntimeError) as err: + tr.get_default(Category.LINKER, mpi=True, openmp=True) + assert str(err.value) == ("Invalid or missing enforce_fortran_linker " + "specification for 'LINKER'.") + def test_get_default_error_missing_openmp() -> None: """