Skip to content

Commit

Permalink
Add 'libs' argument to link_exe function
Browse files Browse the repository at this point in the history
  • Loading branch information
Luke Hoffmann committed Aug 29, 2024
1 parent 8d72ccd commit b3021d6
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
15 changes: 11 additions & 4 deletions source/fab/steps/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"""
import logging
from string import Template
from typing import Optional
from typing import Optional, Union

from fab.artefacts import ArtefactSet
from fab.steps import step
Expand All @@ -33,7 +33,10 @@ def __call__(self, artefact_store):


@step
def link_exe(config, flags=None, source: Optional[ArtefactsGetter] = None):
def link_exe(config,
libs: Union[list[str], None] = None,
flags: Union[list[str], None] = None,
source: Optional[ArtefactsGetter] = None):
"""
Link object files into an executable for every build target.
Expand All @@ -49,8 +52,10 @@ def link_exe(config, flags=None, source: Optional[ArtefactsGetter] = None):
The :class:`fab.build_config.BuildConfig` object where we can read
settings such as the project workspace folder or the multiprocessing
flag.
:param libs:
A list of required library names to pass to the linker.
:param flags:
A list of flags to pass to the linker.
A list of additional flags to pass to the linker.
:param source:
An optional :class:`~fab.artefacts.ArtefactsGetter`. It defaults to the
output from compiler steps, which typically is the expected behaviour.
Expand All @@ -59,13 +64,15 @@ def link_exe(config, flags=None, source: Optional[ArtefactsGetter] = None):
linker = config.tool_box.get_tool(Category.LINKER, config.mpi)
logger.info(f'Linker is {linker.name}')

libs = libs or []
flags = flags or []
source_getter = source or DefaultLinkerSource()

target_objects = source_getter(config.artefact_store)
for root, objects in target_objects.items():
exe_path = config.project_workspace / f'{root}'
linker.link(objects, exe_path, openmp=config.openmp, add_flags=flags)
linker.link(objects, exe_path, openmp=config.openmp, libs=libs,
add_flags=flags)
config.artefact_store.add(ArtefactSet.EXECUTABLES, exe_path)


Expand Down
8 changes: 6 additions & 2 deletions tests/unit_tests/steps/test_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,20 @@ def test_run(self, tool_box):
linker = Linker("mock_link", "mock_link.exe", "mock-vendor")
# Mark the linker as available to it can be added to the tool box
linker._is_available = True

# Add a custom library to the linker
linker.add_lib_flags('mylib', ['-L/my/lib', '-mylib'])
tool_box.add_tool(linker, silent_replace=True)
mock_result = mock.Mock(returncode=0, stdout="abc\ndef".encode())
with mock.patch('fab.tools.tool.subprocess.run',
return_value=mock_result) as tool_run, \
pytest.warns(UserWarning,
match="_metric_send_conn not "
"set, cannot send metrics"):
link_exe(config, flags=['-fooflag', '-barflag'])
link_exe(config, libs=['mylib'], flags=['-fooflag', '-barflag'])

tool_run.assert_called_with(
['mock_link.exe', '-L/foo1/lib', '-L/foo2/lib', 'bar.o', 'foo.o',
'-fooflag', '-barflag', '-o', 'workspace/foo'],
'-L/my/lib', '-mylib', '-fooflag', '-barflag',
'-o', 'workspace/foo'],
capture_output=True, env=None, cwd=None, check=False)

0 comments on commit b3021d6

Please sign in to comment.