# Copyright 2012-2017 The Meson development team

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import abc
import os
import typing as T

from . import mesonlib
from .arglist import CompilerArgs
from .envconfig import get_env_var

if T.TYPE_CHECKING:
    from .coredata import OptionDictType
    from .environment import Environment


class StaticLinker:

    def __init__(self, exelist: T.List[str]):
        self.exelist = exelist

    def compiler_args(self, args: T.Optional[T.Iterable[str]] = None) -> CompilerArgs:
        return CompilerArgs(self, args)

    def can_linker_accept_rsp(self) -> bool:
        """
        Determines whether the linker can accept arguments using the @rsp syntax.
        """
        return mesonlib.is_windows()

    def get_base_link_args(self, options: 'OptionDictType') -> T.List[str]:
        """Like compilers.get_base_link_args, but for the static linker."""
        return []

    def get_exelist(self) -> T.List[str]:
        return self.exelist.copy()

    def get_std_link_args(self) -> T.List[str]:
        return []

    def get_buildtype_linker_args(self, buildtype: str) -> T.List[str]:
        return []

    def get_output_args(self, target: str) -> T.List[str]:
        return[]

    def get_coverage_link_args(self) -> T.List[str]:
        return []

    def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
                         rpath_paths: str, build_rpath: str,
                         install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
        return ([], set())

    def thread_link_flags(self, env: 'Environment') -> T.List[str]:
        return []

    def openmp_flags(self) -> T.List[str]:
        return []

    def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
        return []

    @classmethod
    def unix_args_to_native(cls, args: T.List[str]) -> T.List[str]:
        return args[:]

    @classmethod
    def native_args_to_unix(cls, args: T.List[str]) -> T.List[str]:
        return args[:]

    def get_link_debugfile_name(self, targetfile: str) -> str:
        return None

    def get_link_debugfile_args(self, targetfile: str) -> T.List[str]:
        # Static libraries do not have PDB files
        return []

    def get_always_args(self) -> T.List[str]:
        return []

    def get_linker_always_args(self) -> T.List[str]:
        return []


class VisualStudioLikeLinker:
    always_args = ['/NOLOGO']

    def __init__(self, machine: str):
        self.machine = machine

    def get_always_args(self) -> T.List[str]:
        return self.always_args.copy()

    def get_linker_always_args(self) -> T.List[str]:
        return self.always_args.copy()

    def get_output_args(self, target: str) -> T.List[str]:
        args = []  # type: T.List[str]
        if self.machine:
            args += ['/MACHINE:' + self.machine]
        args += ['/OUT:' + target]
        return args

    @classmethod
    def unix_args_to_native(cls, args: T.List[str]) -> T.List[str]:
        from .compilers import VisualStudioCCompiler
        return VisualStudioCCompiler.unix_args_to_native(args)

    @classmethod
    def native_args_to_unix(cls, args: T.List[str]) -> T.List[str]:
        from .compilers import VisualStudioCCompiler
        return VisualStudioCCompiler.native_args_to_unix(args)


class VisualStudioLinker(VisualStudioLikeLinker, StaticLinker):

    """Microsoft's lib static linker."""

    def __init__(self, exelist: T.List[str], machine: str):
        StaticLinker.__init__(self, exelist)
        VisualStudioLikeLinker.__init__(self, machine)


class IntelVisualStudioLinker(VisualStudioLikeLinker, StaticLinker):

    """Intel's xilib static linker."""

    def __init__(self, exelist: T.List[str], machine: str):
        StaticLinker.__init__(self, exelist)
        VisualStudioLikeLinker.__init__(self, machine)


class ArLinker(StaticLinker):

    def __init__(self, exelist: T.List[str]):
        super().__init__(exelist)
        self.id = 'ar'
        pc, stdo = mesonlib.Popen_safe(self.exelist + ['-h'])[0:2]
        # Enable deterministic builds if they are available.
        if '[D]' in stdo:
            self.std_args = ['csrD']
        else:
            self.std_args = ['csr']
        self.can_rsp = '@<' in stdo

    def can_linker_accept_rsp(self) -> bool:
        return self.can_rsp

    def get_std_link_args(self) -> T.List[str]:
        return self.std_args

    def get_output_args(self, target: str) -> T.List[str]:
        return [target]


class ArmarLinker(ArLinker):  # lgtm [py/missing-call-to-init]

    def __init__(self, exelist: T.List[str]):
        StaticLinker.__init__(self, exelist)
        self.id = 'armar'
        self.std_args = ['-csr']

    def can_linker_accept_rsp(self) -> bool:
        # armar can't accept arguments using the @rsp syntax
        return False


class DLinker(StaticLinker):
    def __init__(self, exelist: T.List[str], arch: str):
        super().__init__(exelist)
        self.id = exelist[0]
        self.arch = arch

    def get_std_link_args(self) -> T.List[str]:
        return ['-lib']

    def get_output_args(self, target: str) -> T.List[str]:
        return ['-of=' + target]

    def get_linker_always_args(self) -> T.List[str]:
        if mesonlib.is_windows():
            if self.arch == 'x86_64':
                return ['-m64']
            elif self.arch == 'x86_mscoff' and self.id == 'dmd':
                return ['-m32mscoff']
            return ['-m32']
        return []


class CcrxLinker(StaticLinker):

    def __init__(self, exelist: T.List[str]):
        super().__init__(exelist)
        self.id = 'rlink'

    def can_linker_accept_rsp(self) -> bool:
        return False

    def get_output_args(self, target: str) -> T.List[str]:
        return ['-output={}'.format(target)]

    def get_linker_always_args(self) -> T.List[str]:
        return ['-nologo', '-form=library']


class Xc16Linker(StaticLinker):

    def __init__(self, exelist: T.List[str]):
        super().__init__(exelist)
        self.id = 'xc16-ar'

    def can_linker_accept_rsp(self) -> bool:
        return False

    def get_output_args(self, target: str) -> T.List[str]:
        return ['{}'.format(target)]

    def get_linker_always_args(self) -> T.List[str]:
        return ['rcs']


class C2000Linker(StaticLinker):

    def __init__(self, exelist: T.List[str]):
        super().__init__(exelist)
        self.id = 'ar2000'

    def can_linker_accept_rsp(self) -> bool:
        return False

    def get_output_args(self, target: str) -> T.List[str]:
        return ['{}'.format(target)]

    def get_linker_always_args(self) -> T.List[str]:
        return ['-r']


class AIXArLinker(ArLinker):

    def __init__(self, exelist: T.List[str]):
        StaticLinker.__init__(self, exelist)
        self.id = 'aixar'
        self.std_args = ['-csr', '-Xany']

    def can_linker_accept_rsp(self) -> bool:
        # AIXAr can't accept arguments using the @rsp syntax
        return False


def prepare_rpaths(raw_rpaths: str, build_dir: str, from_dir: str) -> T.List[str]:
    # The rpaths we write must be relative if they point to the build dir,
    # because otherwise they have different length depending on the build
    # directory. This breaks reproducible builds.
    internal_format_rpaths = [evaluate_rpath(p, build_dir, from_dir) for p in raw_rpaths]
    ordered_rpaths = order_rpaths(internal_format_rpaths)
    return ordered_rpaths


def order_rpaths(rpath_list: T.List[str]) -> T.List[str]:
    # We want rpaths that point inside our build dir to always override
    # those pointing to other places in the file system. This is so built
    # binaries prefer our libraries to the ones that may lie somewhere
    # in the file system, such as /lib/x86_64-linux-gnu.
    #
    # The correct thing to do here would be C++'s std::stable_partition.
    # Python standard library does not have it, so replicate it with
    # sort, which is guaranteed to be stable.
    return sorted(rpath_list, key=os.path.isabs)


def evaluate_rpath(p: str, build_dir: str, from_dir: str) -> str:
    if p == from_dir:
        return '' # relpath errors out in this case
    elif os.path.isabs(p):
        return p # These can be outside of build dir.
    else:
        return os.path.relpath(os.path.join(build_dir, p), os.path.join(build_dir, from_dir))


class LinkerEnvVarsMixin(metaclass=abc.ABCMeta):

    """Mixin reading LDFLAGS from the environment."""

    @staticmethod
    def get_args_from_envvars(for_machine: mesonlib.MachineChoice,
                              is_cross: bool) -> T.List[str]:
        raw_value = get_env_var(for_machine, is_cross, 'LDFLAGS')
        if raw_value is not None:
            return mesonlib.split_args(raw_value)
        else:
            return []

class DynamicLinker(LinkerEnvVarsMixin, metaclass=abc.ABCMeta):

    """Base class for dynamic linkers."""

    _BUILDTYPE_ARGS = {
        'plain': [],
        'debug': [],
        'debugoptimized': [],
        'release': [],
        'minsize': [],
        'custom': [],
    }  # type: T.Dict[str, T.List[str]]

    def _apply_prefix(self, arg: T.Union[str, T.List[str]]) -> T.List[str]:
        args = [arg] if isinstance(arg, str) else arg
        if self.prefix_arg is None:
            return args
        elif isinstance(self.prefix_arg, str):
            return [self.prefix_arg + arg for arg in args]
        ret = []
        for arg in args:
            ret += self.prefix_arg + [arg]
        return ret

    def __init__(self, id_: str, exelist: T.List[str],
                 for_machine: mesonlib.MachineChoice, prefix_arg: T.Union[str, T.List[str]],
                 always_args: T.List[str], *, version: str = 'unknown version'):
        self.exelist = exelist
        self.for_machine = for_machine
        self.version = version
        self.id = id_
        self.prefix_arg = prefix_arg
        self.always_args = always_args

    def __repr__(self) -> str:
        return '<{}: v{} `{}`>'.format(type(self).__name__, self.version, ' '.join(self.exelist))

    def get_id(self) -> str:
        return self.id

    def get_version_string(self) -> str:
        return '({} {})'.format(self.id, self.version)

    def get_exelist(self) -> T.List[str]:
        return self.exelist.copy()

    def get_accepts_rsp(self) -> bool:
        # rsp files are only used when building on Windows because we want to
        # avoid issues with quoting and max argument length
        return mesonlib.is_windows()

    def get_always_args(self) -> T.List[str]:
        return self.always_args.copy()

    def get_lib_prefix(self) -> str:
        return ''

    # XXX: is use_ldflags a compiler or a linker attribute?

    def get_option_args(self, options: 'OptionDictType') -> T.List[str]:
        return []

    def has_multi_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]:
        m = 'Language {} does not support has_multi_link_arguments.'
        raise mesonlib.EnvironmentException(m.format(self.id))

    def get_debugfile_name(self, targetfile: str) -> str:
        '''Name of debug file written out (see below)'''
        return None

    def get_debugfile_args(self, targetfile: str) -> T.List[str]:
        """Some compilers (MSVC) write debug into a separate file.

        This method takes the target object path and returns a list of
        commands to append to the linker invocation to control where that
        file is written.
        """
        return []

    def get_std_shared_lib_args(self) -> T.List[str]:
        return []

    def get_std_shared_module_args(self, options: 'OptionDictType') -> T.List[str]:
        return self.get_std_shared_lib_args()

    def get_pie_args(self) -> T.List[str]:
        # TODO: this really needs to take a boolean and return the args to
        # disable pie, otherwise it only acts to enable pie if pie *isn't* the
        # default.
        m = 'Linker {} does not support position-independent executable'
        raise mesonlib.EnvironmentException(m.format(self.id))

    def get_lto_args(self) -> T.List[str]:
        return []

    def sanitizer_args(self, value: str) -> T.List[str]:
        return []

    def get_buildtype_args(self, buildtype: str) -> T.List[str]:
        # We can override these in children by just overriding the
        # _BUILDTYPE_ARGS value.
        return self._BUILDTYPE_ARGS[buildtype]

    def get_asneeded_args(self) -> T.List[str]:
        return []

    def get_link_whole_for(self, args: T.List[str]) -> T.List[str]:
        raise mesonlib.EnvironmentException(
            'Linker {} does not support link_whole'.format(self.id))

    def get_allow_undefined_args(self) -> T.List[str]:
        raise mesonlib.EnvironmentException(
            'Linker {} does not support allow undefined'.format(self.id))

    @abc.abstractmethod
    def get_output_args(self, outname: str) -> T.List[str]:
        pass

    def get_coverage_args(self) -> T.List[str]:
        m = "Linker {} doesn't implement coverage data generation.".format(self.id)
        raise mesonlib.EnvironmentException(m)

    @abc.abstractmethod
    def get_search_args(self, dirname: str) -> T.List[str]:
        pass

    def export_dynamic_args(self, env: 'Environment') -> T.List[str]:
        return []

    def import_library_args(self, implibname: str) -> T.List[str]:
        """The name of the outputted import library.

        This implementation is used only on Windows by compilers that use GNU ld
        """
        return []

    def thread_flags(self, env: 'Environment') -> T.List[str]:
        return []

    def no_undefined_args(self) -> T.List[str]:
        """Arguments to error if there are any undefined symbols at link time.

        This is the inverse of get_allow_undefined_args().

        TODO: A future cleanup might merge this and
              get_allow_undefined_args() into a single method taking a
              boolean
        """
        return []

    def fatal_warnings(self) -> T.List[str]:
        """Arguments to make all warnings errors."""
        return []

    def headerpad_args(self) -> T.List[str]:
        # Only used by the Apple linker
        return []

    def bitcode_args(self) -> T.List[str]:
        raise mesonlib.MesonException('This linker does not support bitcode bundles')

    def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
                         rpath_paths: str, build_rpath: str,
                         install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
        return ([], set())

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: T.Tuple[str, str],
                        is_shared_module: bool) -> T.List[str]:
        return []


class PosixDynamicLinkerMixin:

    """Mixin class for POSIX-ish linkers.

    This is obviously a pretty small subset of the linker interface, but
    enough dynamic linkers that meson supports are POSIX-like but not
    GNU-like that it makes sense to split this out.
    """

    def get_output_args(self, outname: str) -> T.List[str]:
        return ['-o', outname]

    def get_std_shared_lib_args(self) -> T.List[str]:
        return ['-shared']

    def get_search_args(self, dirname: str) -> T.List[str]:
        return ['-L' + dirname]


class GnuLikeDynamicLinkerMixin:

    """Mixin class for dynamic linkers that provides gnu-like interface.

    This acts as a base for the GNU linkers (bfd and gold), LLVM's lld, and
    other linkers like GNU-ld.
    """

    _BUILDTYPE_ARGS = {
        'plain': [],
        'debug': [],
        'debugoptimized': [],
        'release': ['-O1'],
        'minsize': [],
        'custom': [],
    }  # type: T.Dict[str, T.List[str]]

    def get_buildtype_args(self, buildtype: str) -> T.List[str]:
        # We can override these in children by just overriding the
        # _BUILDTYPE_ARGS value.
        return mesonlib.listify([self._apply_prefix(a) for a in self._BUILDTYPE_ARGS[buildtype]])

    def get_pie_args(self) -> T.List[str]:
        return ['-pie']

    def get_asneeded_args(self) -> T.List[str]:
        return self._apply_prefix('--as-needed')

    def get_link_whole_for(self, args: T.List[str]) -> T.List[str]:
        if not args:
            return args
        return self._apply_prefix('--whole-archive') + args + self._apply_prefix('--no-whole-archive')

    def get_allow_undefined_args(self) -> T.List[str]:
        return self._apply_prefix('--allow-shlib-undefined')

    def get_lto_args(self) -> T.List[str]:
        return ['-flto']

    def sanitizer_args(self, value: str) -> T.List[str]:
        if value == 'none':
            return []
        return ['-fsanitize=' + value]

    def get_coverage_args(self) -> T.List[str]:
        return ['--coverage']

    def export_dynamic_args(self, env: 'Environment') -> T.List[str]:
        m = env.machines[self.for_machine]
        if m.is_windows() or m.is_cygwin():
            return self._apply_prefix('--export-all-symbols')
        return self._apply_prefix('-export-dynamic')

    def import_library_args(self, implibname: str) -> T.List[str]:
        return self._apply_prefix('--out-implib=' + implibname)

    def thread_flags(self, env: 'Environment') -> T.List[str]:
        if env.machines[self.for_machine].is_haiku():
            return []
        return ['-pthread']

    def no_undefined_args(self) -> T.List[str]:
        return self._apply_prefix('--no-undefined')

    def fatal_warnings(self) -> T.List[str]:
        return self._apply_prefix('--fatal-warnings')

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: T.Tuple[str, str],
                        is_shared_module: bool) -> T.List[str]:
        m = env.machines[self.for_machine]
        if m.is_windows() or m.is_cygwin():
            # For PE/COFF the soname argument has no effect
            return []
        sostr = '' if soversion is None else '.' + soversion
        return self._apply_prefix('-soname,{}{}.{}{}'.format(prefix, shlib_name, suffix, sostr))

    def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
                         rpath_paths: str, build_rpath: str,
                         install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
        m = env.machines[self.for_machine]
        if m.is_windows() or m.is_cygwin():
            return ([], set())
        if not rpath_paths and not install_rpath and not build_rpath:
            return ([], set())
        args = []
        origin_placeholder = '$ORIGIN'
        processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir)
        # Need to deduplicate rpaths, as macOS's install_name_tool
        # is *very* allergic to duplicate -delete_rpath arguments
        # when calling depfixer on installation.
        all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths])
        rpath_dirs_to_remove = set()
        for p in all_paths:
            rpath_dirs_to_remove.add(p.encode('utf8'))
        # Build_rpath is used as-is (it is usually absolute).
        if build_rpath != '':
            all_paths.add(build_rpath)
            for p in build_rpath.split(':'):
                rpath_dirs_to_remove.add(p.encode('utf8'))

        # TODO: should this actually be "for (dragonfly|open)bsd"?
        if mesonlib.is_dragonflybsd() or mesonlib.is_openbsd():
            # This argument instructs the compiler to record the value of
            # ORIGIN in the .dynamic section of the elf. On Linux this is done
            # by default, but is not on dragonfly/openbsd for some reason. Without this
            # $ORIGIN in the runtime path will be undefined and any binaries
            # linked against local libraries will fail to resolve them.
            args.extend(self._apply_prefix('-z,origin'))

        # In order to avoid relinking for RPATH removal, the binary needs to contain just
        # enough space in the ELF header to hold the final installation RPATH.
        paths = ':'.join(all_paths)
        if len(paths) < len(install_rpath):
            padding = 'X' * (len(install_rpath) - len(paths))
            if not paths:
                paths = padding
            else:
                paths = paths + ':' + padding
        args.extend(self._apply_prefix('-rpath,' + paths))

        # TODO: should this actually be "for solaris/sunos"?
        if mesonlib.is_sunos():
            return (args, rpath_dirs_to_remove)

        # Rpaths to use while linking must be absolute. These are not
        # written to the binary. Needed only with GNU ld:
        # https://sourceware.org/bugzilla/show_bug.cgi?id=16936
        # Not needed on Windows or other platforms that don't use RPATH
        # https://github.com/mesonbuild/meson/issues/1897
        #
        # In addition, this linker option tends to be quite long and some
        # compilers have trouble dealing with it. That's why we will include
        # one option per folder, like this:
        #
        #   -Wl,-rpath-link,/path/to/folder1 -Wl,-rpath,/path/to/folder2 ...
        #
        # ...instead of just one single looooong option, like this:
        #
        #   -Wl,-rpath-link,/path/to/folder1:/path/to/folder2:...
        for p in rpath_paths:
            args.extend(self._apply_prefix('-rpath-link,' + os.path.join(build_dir, p)))

        return (args, rpath_dirs_to_remove)


class AppleDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):

    """Apple's ld implementation."""

    def __init__(self, *args, **kwargs):
        super().__init__('ld64', *args, **kwargs)

    def get_asneeded_args(self) -> T.List[str]:
        return self._apply_prefix('-dead_strip_dylibs')

    def get_allow_undefined_args(self) -> T.List[str]:
        return self._apply_prefix('-undefined,dynamic_lookup')

    def get_std_shared_module_args(self, options: 'OptionDictType') -> T.List[str]:
        return ['-bundle'] + self._apply_prefix('-undefined,dynamic_lookup')

    def get_pie_args(self) -> T.List[str]:
        return ['-pie']

    def get_link_whole_for(self, args: T.List[str]) -> T.List[str]:
        result = []  # type: T.List[str]
        for a in args:
            result.extend(self._apply_prefix('-force_load'))
            result.append(a)
        return result

    def get_coverage_args(self) -> T.List[str]:
        return ['--coverage']

    def sanitizer_args(self, value: str) -> T.List[str]:
        if value == 'none':
            return []
        return ['-fsanitize=' + value]

    def no_undefined_args(self) -> T.List[str]:
        return self._apply_prefix('-undefined,error')

    def headerpad_args(self) -> T.List[str]:
        return self._apply_prefix('-headerpad_max_install_names')

    def bitcode_args(self) -> T.List[str]:
        return self._apply_prefix('-bitcode_bundle')

    def fatal_warnings(self) -> T.List[str]:
        return self._apply_prefix('-fatal_warnings')

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: T.Tuple[str, str],
                        is_shared_module: bool) -> T.List[str]:
        if is_shared_module:
            return []
        install_name = ['@rpath/', prefix, shlib_name]
        if soversion is not None:
            install_name.append('.' + soversion)
        install_name.append('.dylib')
        args = ['-install_name', ''.join(install_name)]
        if darwin_versions:
            args.extend(['-compatibility_version', darwin_versions[0],
                         '-current_version', darwin_versions[1]])
        return args

    def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
                         rpath_paths: str, build_rpath: str,
                         install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
        if not rpath_paths and not install_rpath and not build_rpath:
            return ([], set())
        args = []
        # @loader_path is the equivalent of $ORIGIN on macOS
        # https://stackoverflow.com/q/26280738
        origin_placeholder = '@loader_path'
        processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir)
        all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths])
        if build_rpath != '':
            all_paths.add(build_rpath)
        for rp in all_paths:
            args.extend(self._apply_prefix('-rpath,' + rp))

        return (args, set())


class GnuDynamicLinker(GnuLikeDynamicLinkerMixin, PosixDynamicLinkerMixin, DynamicLinker):

    """Representation of GNU ld.bfd and ld.gold."""

    def get_accepts_rsp(self) -> bool:
        return True


class GnuGoldDynamicLinker(GnuDynamicLinker):

    def __init__(self, *args, **kwargs):
        super().__init__('ld.gold', *args, **kwargs)


class GnuBFDDynamicLinker(GnuDynamicLinker):

    def __init__(self, *args, **kwargs):
        super().__init__('ld.bfd', *args, **kwargs)


class LLVMDynamicLinker(GnuLikeDynamicLinkerMixin, PosixDynamicLinkerMixin, DynamicLinker):

    """Representation of LLVM's ld.lld linker.

    This is only the gnu-like linker, not the apple like or link.exe like
    linkers.
    """

    def __init__(self, *args, **kwargs):
        super().__init__('ld.lld', *args, **kwargs)

        # Some targets don't seem to support this argument (windows, wasm, ...)
        _, _, e = mesonlib.Popen_safe(self.exelist + self._apply_prefix('--allow-shlib-undefined'))
        self.has_allow_shlib_undefined = not ('unknown argument: --allow-shlib-undefined' in e)

    def get_allow_undefined_args(self) -> T.List[str]:
        if self.has_allow_shlib_undefined:
            return self._apply_prefix('--allow-shlib-undefined')
        return []


class WASMDynamicLinker(GnuLikeDynamicLinkerMixin, PosixDynamicLinkerMixin, DynamicLinker):

    """Emscripten's wasm-ld."""

    def __init__(self, *args, **kwargs):
        super().__init__('ld.wasm', *args, **kwargs)

    def thread_link_flags(self, env: 'Environment') -> T.List[str]:
        args = ['-s', 'USE_PTHREADS=1']
        count = env.coredata.compiler_options[self.for_machine]['{}_thread_count'.format(self.language)].value  # type: int
        if count:
            args.extend(['-s', 'PTHREAD_POOL_SIZE={}'.format(count)])
        return args

    def get_allow_undefined_args(self) -> T.List[str]:
        return ['-s', 'ERROR_ON_UNDEFINED_SYMBOLS=0']

    def no_undefined_args(self) -> T.List[str]:
        return ['-s', 'ERROR_ON_UNDEFINED_SYMBOLS=1']

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: T.Tuple[str, str],
                        is_shared_module: bool) -> T.List[str]:
        raise mesonlib.MesonException('{} does not support shared libraries.'.format(self.id))

    def get_asneeded_args(self) -> T.List[str]:
        return []

    def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
                         rpath_paths: str, build_rpath: str,
                         install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
        return ([], set())


class CcrxDynamicLinker(DynamicLinker):

    """Linker for Renesis CCrx compiler."""

    def __init__(self, for_machine: mesonlib.MachineChoice,
                 *, version: str = 'unknown version'):
        super().__init__('rlink', ['rlink.exe'], for_machine, '', [],
                         version=version)

    def get_accepts_rsp(self) -> bool:
        return False

    def get_lib_prefix(self) -> str:
        return '-lib='

    def get_std_shared_lib_args(self) -> T.List[str]:
        return []

    def get_output_args(self, outputname: str) -> T.List[str]:
        return ['-output={}'.format(outputname)]

    def get_search_args(self, dirname: str) -> 'T.NoReturn':
        raise EnvironmentError('rlink.exe does not have a search dir argument')

    def get_allow_undefined_args(self) -> T.List[str]:
        return []

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: T.Tuple[str, str],
                        is_shared_module: bool) -> T.List[str]:
        return []


class Xc16DynamicLinker(DynamicLinker):

    """Linker for Microchip XC16 compiler."""

    def __init__(self, for_machine: mesonlib.MachineChoice,
                 *, version: str = 'unknown version'):
        super().__init__('xc16-gcc', ['xc16-gcc.exe'], for_machine, '', [],
                         version=version)

    def get_link_whole_for(self, args: T.List[str]) -> T.List[str]:
        if not args:
            return args
        return self._apply_prefix('--start-group') + args + self._apply_prefix('--end-group')

    def get_accepts_rsp(self) -> bool:
        return False

    def get_lib_prefix(self) -> str:
        return ''

    def get_std_shared_lib_args(self) -> T.List[str]:
        return []

    def get_output_args(self, outputname: str) -> T.List[str]:
        return ['-o{}'.format(outputname)]

    def get_search_args(self, dirname: str) -> 'T.NoReturn':
        raise EnvironmentError('xc16-gcc.exe does not have a search dir argument')

    def get_allow_undefined_args(self) -> T.List[str]:
        return []

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: T.Tuple[str, str],
                        is_shared_module: bool) -> T.List[str]:
        return []

    def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
                         rpath_paths: str, build_rpath: str,
                         install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
        return ([], set())


class C2000DynamicLinker(DynamicLinker):

    """Linker for Texas Instruments C2000 compiler."""

    def __init__(self, for_machine: mesonlib.MachineChoice,
                 *, version: str = 'unknown version'):
        super().__init__('cl2000', ['cl2000.exe'], for_machine, '', [],
                         version=version)

    def get_link_whole_for(self, args: T.List[str]) -> T.List[str]:
        if not args:
            return args
        return self._apply_prefix('--start-group') + args + self._apply_prefix('--end-group')

    def get_accepts_rsp(self) -> bool:
        return False

    def get_lib_prefix(self) -> str:
        return '-l='

    def get_std_shared_lib_args(self) -> T.List[str]:
        return []

    def get_output_args(self, outputname: str) -> T.List[str]:
        return ['-z', '--output_file={}'.format(outputname)]

    def get_search_args(self, dirname: str) -> 'T.NoReturn':
        raise EnvironmentError('cl2000.exe does not have a search dir argument')

    def get_allow_undefined_args(self) -> T.List[str]:
        return []

    def get_always_args(self) -> T.List[str]:
        return []


class ArmDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):

    """Linker for the ARM compiler."""

    def __init__(self, for_machine: mesonlib.MachineChoice,
                 *, version: str = 'unknown version'):
        super().__init__('armlink', ['armlink'], for_machine, '', [],
                         version=version)

    def get_accepts_rsp(self) -> bool:
        return False

    def get_std_shared_lib_args(self) -> 'T.NoReturn':
        raise mesonlib.MesonException('The Arm Linkers do not support shared libraries')

    def get_allow_undefined_args(self) -> T.List[str]:
        return []


class ArmClangDynamicLinker(ArmDynamicLinker):

    """Linker used with ARM's clang fork.

    The interface is similar enough to the old ARM ld that it inherits and
    extends a few things as needed.
    """

    def export_dynamic_args(self, env: 'Environment') -> T.List[str]:
        return ['--export_dynamic']

    def import_library_args(self, implibname: str) -> T.List[str]:
        return ['--symdefs=' + implibname]

class QualcommLLVMDynamicLinker(LLVMDynamicLinker):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # ARM Linker from Snapdragon LLVM ARM Compiler
        self.id = 'ld.qcld'

class PGIDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):

    """PGI linker."""

    def __init__(self, *args, **kwargs):
        super().__init__('pgi', *args, **kwargs)

    def get_allow_undefined_args(self) -> T.List[str]:
        return []

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: T.Tuple[str, str],
                        is_shared_module: bool) -> T.List[str]:
        return []

    def get_std_shared_lib_args(self) -> T.List[str]:
        # PGI -shared is Linux only.
        if mesonlib.is_windows():
            return ['-Bdynamic', '-Mmakedll']
        elif mesonlib.is_linux():
            return ['-shared']
        return []

    def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
                         rpath_paths: str, build_rpath: str,
                         install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
        if not env.machines[self.for_machine].is_windows():
            return (['-R' + os.path.join(build_dir, p) for p in rpath_paths], set())
        return ([], set())

NvidiaHPC_DynamicLinker = PGIDynamicLinker


class PGIStaticLinker(StaticLinker):
    def __init__(self, exelist: T.List[str]):
        super().__init__(exelist)
        self.id = 'ar'
        self.std_args = ['-r']

    def get_std_link_args(self) -> T.List[str]:
        return self.std_args

    def get_output_args(self, target: str) -> T.List[str]:
        return [target]

NvidiaHPC_StaticLinker = PGIStaticLinker


class VisualStudioLikeLinkerMixin:

    _BUILDTYPE_ARGS = {
        'plain': [],
        'debug': [],
        'debugoptimized': [],
        # The otherwise implicit REF and ICF linker optimisations are disabled by
        # /DEBUG. REF implies ICF.
        'release': ['/OPT:REF'],
        'minsize': ['/INCREMENTAL:NO', '/OPT:REF'],
        'custom': [],
    }  # type: T.Dict[str, T.List[str]]

    def __init__(self, *args, direct: bool = True, machine: str = 'x86', **kwargs):
        super().__init__(*args, **kwargs)
        self.machine = machine

    def get_buildtype_args(self, buildtype: str) -> T.List[str]:
        return mesonlib.listify([self._apply_prefix(a) for a in self._BUILDTYPE_ARGS[buildtype]])

    def invoked_by_compiler(self) -> bool:
        return not self.direct

    def get_output_args(self, outputname: str) -> T.List[str]:
        return self._apply_prefix(['/MACHINE:' + self.machine, '/OUT:' + outputname])

    def get_always_args(self) -> T.List[str]:
        return self._apply_prefix('/nologo') + super().get_always_args()

    def get_search_args(self, dirname: str) -> T.List[str]:
        return self._apply_prefix('/LIBPATH:' + dirname)

    def get_std_shared_lib_args(self) -> T.List[str]:
        return self._apply_prefix('/DLL')

    def get_debugfile_name(self, targetfile: str) -> str:
        basename = targetfile.rsplit('.', maxsplit=1)[0]
        return basename + '.pdb'

    def get_debugfile_args(self, targetfile: str) -> T.List[str]:
        return self._apply_prefix(['/DEBUG', '/PDB:' + self.get_debugfile_name(targetfile)])

    def get_link_whole_for(self, args: T.List[str]) -> T.List[str]:
        # Only since VS2015
        args = mesonlib.listify(args)
        l = []  # T.List[str]
        for a in args:
            l.extend(self._apply_prefix('/WHOLEARCHIVE:' + a))
        return l

    def get_allow_undefined_args(self) -> T.List[str]:
        return []

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: T.Tuple[str, str],
                        is_shared_module: bool) -> T.List[str]:
        return []

    def import_library_args(self, implibname: str) -> T.List[str]:
        """The command to generate the import library."""
        return self._apply_prefix(['/IMPLIB:' + implibname])


class MSVCDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):

    """Microsoft's Link.exe."""

    def __init__(self, for_machine: mesonlib.MachineChoice, always_args: T.List[str], *,
                 exelist: T.Optional[T.List[str]] = None,
                 prefix: T.Union[str, T.List[str]] = '',
                 machine: str = 'x86', version: str = 'unknown version',
                 direct: bool = True):
        super().__init__('link', exelist or ['link.exe'], for_machine,
                         prefix, always_args, machine=machine, version=version, direct=direct)

    def get_always_args(self) -> T.List[str]:
        return self._apply_prefix(['/nologo', '/release']) + super().get_always_args()


class ClangClDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):

    """Clang's lld-link.exe."""

    def __init__(self, for_machine: mesonlib.MachineChoice, always_args: T.List[str], *,
                 exelist: T.Optional[T.List[str]] = None,
                 prefix: T.Union[str, T.List[str]] = '',
                 machine: str = 'x86', version: str = 'unknown version',
                 direct: bool = True):
        super().__init__('lld-link', exelist or ['lld-link.exe'], for_machine,
                         prefix, always_args, machine=machine, version=version, direct=direct)


class XilinkDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):

    """Intel's Xilink.exe."""

    def __init__(self, for_machine: mesonlib.MachineChoice, always_args: T.List[str],
                 *, version: str = 'unknown version'):
        super().__init__('xilink', ['xilink.exe'], for_machine, '', always_args, version=version)


class SolarisDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):

    """Sys-V derived linker used on Solaris and OpenSolaris."""

    def __init__(self, *args, **kwargs):
        super().__init__('ld.solaris', *args, **kwargs)

    def get_link_whole_for(self, args: T.List[str]) -> T.List[str]:
        if not args:
            return args
        return self._apply_prefix('--whole-archive') + args + self._apply_prefix('--no-whole-archive')

    def get_pie_args(self) -> T.List[str]:
        # Available in Solaris 11.2 and later
        pc, stdo, stde = mesonlib.Popen_safe(self.exelist + self._apply_prefix('-zhelp'))
        for line in (stdo + stde).split('\n'):
            if '-z type' in line:
                if 'pie' in line:
                    return ['-z', 'type=pie']
                break
        return []

    def get_asneeded_args(self) -> T.List[str]:
        return self._apply_prefix(['-z', 'ignore'])

    def no_undefined_args(self) -> T.List[str]:
        return ['-z', 'defs']

    def get_allow_undefined_args(self) -> T.List[str]:
        return ['-z', 'nodefs']

    def fatal_warnings(self) -> T.List[str]:
        return ['-z', 'fatal-warnings']

    def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
                         rpath_paths: str, build_rpath: str,
                         install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
        if not rpath_paths and not install_rpath and not build_rpath:
            return ([], set())
        processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir)
        all_paths = mesonlib.OrderedSet([os.path.join('$ORIGIN', p) for p in processed_rpaths])
        if build_rpath != '':
            all_paths.add(build_rpath)

        # In order to avoid relinking for RPATH removal, the binary needs to contain just
        # enough space in the ELF header to hold the final installation RPATH.
        paths = ':'.join(all_paths)
        if len(paths) < len(install_rpath):
            padding = 'X' * (len(install_rpath) - len(paths))
            if not paths:
                paths = padding
            else:
                paths = paths + ':' + padding
        return (self._apply_prefix('-rpath,{}'.format(paths)), set())

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: T.Tuple[str, str],
                        is_shared_module: bool) -> T.List[str]:
        sostr = '' if soversion is None else '.' + soversion
        return self._apply_prefix('-soname,{}{}.{}{}'.format(prefix, shlib_name, suffix, sostr))


class AIXDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):

    """Sys-V derived linker used on AIX"""

    def __init__(self, *args, **kwargs):
        super().__init__('ld.aix', *args, **kwargs)

    def get_always_args(self) -> T.List[str]:
        return self._apply_prefix(['-bsvr4', '-bnoipath', '-bbigtoc']) + super().get_always_args()

    def no_undefined_args(self) -> T.List[str]:
        return self._apply_prefix(['-z', 'defs'])

    def get_allow_undefined_args(self) -> T.List[str]:
        return self._apply_prefix(['-z', 'nodefs'])

    def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
                         rpath_paths: str, build_rpath: str,
                         install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
        all_paths = mesonlib.OrderedSet(['/opt/freeware/lib']) # for libgcc_s.a
        for p in rpath_paths:
            all_paths.add(os.path.join(build_dir, p))
        if build_rpath != '':
            all_paths.add(build_rpath)
        if install_rpath != '':
            all_paths.add(install_rpath)
        return (self._apply_prefix([x for p in all_paths for x in ('-R', p)]), set())

    def thread_flags(self, env: 'Environment') -> T.List[str]:
        return ['-pthread']


class OptlinkDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):

    """Digital Mars dynamic linker for windows."""

    def __init__(self, exelist: T.List[str], for_machine: mesonlib.MachineChoice,
                 *, version: str = 'unknown version'):
        # Use optlink instead of link so we don't interfer with other link.exe
        # implementations.
        super().__init__('optlink', exelist, for_machine, '', [], version=version)

    def get_allow_undefined_args(self) -> T.List[str]:
        return []

    def get_debugfile_args(self, targetfile: str) -> T.List[str]:
        # Optlink does not generate pdb files.
        return []

    def get_always_args(self) -> T.List[str]:
        return []


class CudaLinker(PosixDynamicLinkerMixin, DynamicLinker):
    """Cuda linker (nvlink)"""

    def __init__(self, *args, **kwargs):
        super().__init__('nvlink', *args, **kwargs)

    @staticmethod
    def parse_version():
        version_cmd = ['nvlink', '--version']
        try:
            _, out, _ = mesonlib.Popen_safe(version_cmd)
        except OSError:
            return 'unknown version'
        # Output example:
        # nvlink: NVIDIA (R) Cuda linker
        # Copyright (c) 2005-2018 NVIDIA Corporation
        # Built on Sun_Sep_30_21:09:22_CDT_2018
        # Cuda compilation tools, release 10.0, V10.0.166
        # we need the most verbose version output. Luckily starting with V
        return out.strip().split('V')[-1]

    def get_accepts_rsp(self) -> bool:
        # nvcc does not support response files
        return False

    def get_lib_prefix(self) -> str:
        if not mesonlib.is_windows():
            return ''
        # nvcc doesn't recognize Meson's default .a extension for static libraries on
        # Windows and passes it to cl as an object file, resulting in 'warning D9024 :
        # unrecognized source file type 'xxx.a', object file assumed'.
        #
        # nvcc's --library= option doesn't help: it takes the library name without the
        # extension and assumes that the extension on Windows is .lib; prefixing the
        # library with -Xlinker= seems to work.
        from .compilers import CudaCompiler
        return CudaCompiler.LINKER_PREFIX

    def fatal_warnings(self) -> T.List[str]:
        return ['--warning-as-error']

    def get_allow_undefined_args(self) -> T.List[str]:
        return []

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: T.Tuple[str, str],
                        is_shared_module: bool) -> T.List[str]:
        return []
