<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def link(obj_files, out_file=None, shared=False, CompilerRunner_=None, cwd=None, cplus=False, fort=False, **kwargs):
 """ Link object files. Parameters obj_files: iterable of path strings out_file: path string (optional) path to executable/shared library, if missing it will be deduced from the last item in obj_files. shared: bool Generate a shared library? default: False CompilerRunner_: pycompilation.CompilerRunner subclass (optional) If not given the `cplus` and `fort` flags will be inspected (fallback is the C compiler) cwd: path string root of relative paths and working directory for compiler cplus: bool C++ objects? default: False fort: bool Fortran objects? default: False **kwargs: dict keyword arguments passed onto CompilerRunner_ Returns ------- The absolute to the generated shared object / executable """

    if out_file is None:
        out_file, ext = os.path.splitext(os.path.basename(obj_files[-1]))
        if shared:
            out_file += sharedext

    if not CompilerRunner_:
        if fort:
            CompilerRunner_, extra_kwargs, vendor = \
                get_mixed_fort_c_linker(
                    vendor=kwargs.get('vendor', None),
                    metadir=kwargs.get('metadir', None),
                    cplus=cplus,
                    cwd=cwd,
                )
            for k, v in extra_kwargs.items():
                expand_collection_in_dict(kwargs, k, v)
        else:
            if cplus:
                CompilerRunner_ = CppCompilerRunner
            else:
                CompilerRunner_ = CCompilerRunner

    flags = kwargs.pop('flags', [])
    if shared:
        if '-shared' not in flags:
            flags.append('-shared')

        # mimic GNU linker behavior on OS X when using -shared
        # (otherwise likely Undefined symbol errors)
        dl_flag = '-undefined dynamic_lookup'
        if sys.platform == 'darwin' and dl_flag not in flags:
            flags.append(dl_flag)
    run_linker = kwargs.pop('run_linker', True)
    if not run_linker:
        raise ValueError("link(..., run_linker=False)!?")

    out_file = get_abspath(out_file, cwd=cwd)
    runner = CompilerRunner_(
        obj_files, out_file, flags,
        cwd=cwd,
        **kwargs)
    runner.run()
    return out_file