hiker / fab_new

BOM version of the flexible build system for scientific software
https://metoffice.github.io/fab/
BSD 3-Clause "New" or "Revised" License
1 stars 0 forks source link

Linker inherits CompilerWrapper (#20) #23

Open lukehoffmann opened 2 weeks ago

lukehoffmann commented 2 weeks ago

Changes Linker to inherit CompilerWrapper as in Issue #20

lukehoffmann commented 2 weeks ago

This was my work on issue #20 before I saw the new comment about reusing flags with mpi wrappers.

Have a look and see if it would be useful in its current form.

hiker commented 1 week ago

Seems to go in the right direction. But we need to support nested linker - e.g. an intel mpif90 wrapper would need to take a linker (which is now a CompilerWrapper) - linker-ifort as parameter. Then any flags from linker-ifort need to he used in the intel-mpif90 wrapper. I am not sure about the best way to implement this, here some tests with using isinstance:

joerg@Joerg-Surface:~/work/fab/source/fab/tools$ git diff ./linker.py
diff --git a/source/fab/tools/linker.py b/source/fab/tools/linker.py
index 1256ff3..7c60066 100644
--- a/source/fab/tools/linker.py
+++ b/source/fab/tools/linker.py
@@ -55,6 +55,8 @@ class Linker(CompilerWrapper):
         try:
             return self._lib_flags[lib]
         except KeyError:
+            if isinstance(self.compiler, Linker):
+                return self._compiler.get_lib_flags(lib)
             raise RuntimeError(f"Unknown library name: '{lib}'")

     def add_lib_flags(self, lib: str, flags: List[str],
@@ -112,6 +114,8 @@ class Linker(CompilerWrapper):
         :returns: the stdout of the link command
         '''
         # Don't need to add compiler's flags, they are added by CompilerWrapper.
+        if isinstance(self.compiler, Linker):
+            print("RECURSIVE")
         params: List[Union[str, Path]] = []
         if openmp:
             params.append(self._compiler.openmp_flag)

So the first modification (to get_lib_flags) should work just fine - if we don't have a defintion (which could overwrite the base linker), and the 'compiler' is a linker, we call it to get the definition.

The second modification needs a bit more work. For now I'd guess that any pre- and post-flags from the linker wrapper should wrap the linker ... that sounds convoluted. Assume linker1 adds pre1 and post1, and linker 2 adds pre2 and post2. If linker2 - Linker(linker1), then we should get:

pre2  pre1  <libraryflags> post1 post2

Is that enough to get you started?