# 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 shlex
import typing

from . import mesonlib

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


class StaticLinker:

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

    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') -> typing.List[str]:
        """Like compilers.get_base_link_args, but for the static linker."""
        return []

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

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

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

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

    def get_coverage_link_args(self) -> typing.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) -> typing.List[str]:
        return []

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

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

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

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

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

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

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


class VisualStudioLikeLinker:
    always_args = ['/NOLOGO']

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

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

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

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

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


class VisualStudioLinker(VisualStudioLikeLinker, StaticLinker):

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

    def __init__(self, exelist: typing.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: typing.List[str], machine: str):
        StaticLinker.__init__(self, exelist)
        VisualStudioLikeLinker.__init__(self, machine)


class ArLinker(StaticLinker):

    def __init__(self, exelist: typing.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']

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

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


class ArmarLinker(ArLinker):

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

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


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

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

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

    def get_linker_always_args(self) -> typing.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: typing.List[str]):
        super().__init__(exelist)
        self.id = 'rlink'

    def can_linker_accept_rsp(self) -> bool:
        return False

    def get_output_args(self, target: str) -> typing.List[str]:
        return ['-output=%s' % target]

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


def prepare_rpaths(raw_rpaths: str, build_dir: str, from_dir: str) -> typing.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: typing.List[str]) -> typing.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 DynamicLinker(metaclass=abc.ABCMeta):

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

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

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

    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) -> typing.List[str]:
        return self.exelist.copy()

    def get_accepts_rsp(self) -> bool:
        # TODO: is it really a matter of is_windows or is it for_windows?
        return mesonlib.is_windows()

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

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

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

    def get_args_from_envvars(self) -> typing.List[str]:
        flags = os.environ.get('LDFLAGS')
        if not flags:
            return []
        return shlex.split(flags)

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

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

    def get_debugfile_args(self, targetfile: str) -> typing.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) -> typing.List[str]:
        return []

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

    def get_pie_args(self) -> typing.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) -> typing.List[str]:
        return []

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

    def get_buildtype_args(self, buildtype: str) -> typing.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) -> typing.List[str]:
        return []

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

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

    def invoked_by_compiler(self) -> bool:
        """True if meson uses the compiler to invoke the linker."""
        return True

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

    def get_coverage_args(self) -> typing.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) -> typing.List[str]:
        pass

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

    def import_library_args(self, implibname: str) -> typing.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') -> typing.List[str]:
        return []

    def no_undefined_args(self) -> typing.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) -> typing.List[str]:
        """Arguments to make all warnings errors."""
        return []

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

    def get_debug_crt_args(self) -> typing.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) -> typing.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) -> typing.List[str]:
        return ['-o', outname]

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

    def get_search_args(self, dirname: str) -> typing.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), the Intel Xild
    (which comes with ICC), LLVM's lld, and other linkers like GNU-ld.
    """

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

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

    def get_asneeded_args(self) -> typing.List[str]:
        return ['-Wl,--as-needed']

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

    def get_allow_undefined_args(self) -> typing.List[str]:
        return ['-Wl,--allow-shlib-undefined']

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

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

    def invoked_by_compiler(self) -> bool:
        """True if meson uses the compiler to invoke the linker."""
        return True

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

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

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

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

    def no_undefined_args(self) -> typing.List[str]:
        return ['-Wl,--no-undefined']

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

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: typing.Tuple[str, str],
                        is_shared_module: bool) -> typing.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 ['-Wl,-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) -> typing.List[str]:
        m = env.machines[self.for_machine]
        if m.is_windows() or m.is_cygwin():
            return []
        if not rpath_paths and not install_rpath and not build_rpath:
            return []
        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])
        # Build_rpath is used as-is (it is usually absolute).
        if build_rpath != '':
            all_paths.add(build_rpath)

        # 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.append('-Wl,-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.append('-Wl,-rpath,' + paths)

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

        # 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:...
        args.extend(['-Wl,-rpath-link,' + os.path.join(build_dir, p) for p in rpath_paths])

        return args


class AppleDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):

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

    def get_asneeded_args(self) -> typing.List[str]:
        return ['-Wl,-dead_strip_dylibs']

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

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

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

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

    def get_always_args(self) -> typing.List[str]:
        return ['-Wl,-headerpad_max_install_names']

    def bitcode_args(self) -> typing.List[str]:
        return ['-Wl,-bitcode_bundle']

    def fatal_warnings(self) -> typing.List[str]:
        return ['-Wl,-fatal_warnings']

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: typing.Tuple[str, str],
                        is_shared_module: bool) -> typing.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) -> typing.List[str]:
        if not rpath_paths and not install_rpath and not build_rpath:
            return []
        # Ensure that there is enough space for install_name_tool in-place
        # editing of large RPATHs
        args = ['-Wl,-headerpad_max_install_names']
        # @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)
        args.extend(['-Wl,-rpath,' + rp for rp in all_paths])

        return args


class GnuDynamicLinker(GnuLikeDynamicLinkerMixin, PosixDynamicLinkerMixin, DynamicLinker):

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

    pass


class LLVMDynamicLinker(GnuLikeDynamicLinkerMixin, PosixDynamicLinkerMixin, DynamicLinker):

    """Representation of LLVM's lld (not lld-link) linker.

    This is only the posix-like linker.
    """

    pass


class XildLinuxDynamicLinker(GnuLikeDynamicLinkerMixin, PosixDynamicLinkerMixin, DynamicLinker):

    """Representation of Intel's Xild linker.

    This is only the linux-like linker which dispatches to Gnu ld.
    """

    pass


class XildAppleDynamicLinker(AppleDynamicLinker):

    """Representation of Intel's Xild linker.

    This is the apple linker, which dispatches to Apple's ld.
    """

    pass


class CcrxDynamicLinker(DynamicLinker):

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

    def __init__(self, for_machine: mesonlib.MachineChoice,
                 *, version: str = 'unknown version'):
        super().__init__(['rlink.exe'], for_machine, 'rlink',
                         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) -> typing.List[str]:
        return []

    def get_output_args(self, outputname: str) -> typing.List[str]:
        return ['-output=%s' % outputname]

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

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

    def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
                        suffix: str, soversion: str, darwin_versions: typing.Tuple[str, str],
                        is_shared_module: bool) -> typing.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'], for_machine, 'armlink',
                         version=version)

    def get_accepts_rsp(self) -> bool:
        return False

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

    def get_allow_undefined_args(self) -> typing.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') -> typing.List[str]:
        return ['--export_dynamic']

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


class PGIDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):

    """PGI linker."""

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

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

    def get_std_shared_lib_args(self) -> typing.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) -> typing.List[str]:
        if env.machines[self.for_machine].is_windows():
            return ['-R' + os.path.join(build_dir, p) for p in rpath_paths]
        return []


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: typing.Dict[str, typing.List[str]]

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

    def get_debug_crt_args(self) -> typing.List[str]:
        """Arguments needed to select a debug crt for the linker.

        Sometimes we need to manually select the CRT (C runtime) to use with
        MSVC. One example is when trying to link with static libraries since
        MSVC won't auto-select a CRT for us in that case and will error out
        asking us to select one.
        """
        return ['/MDd']

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

    def get_always_args(self) -> typing.List[str]:
        return ['/nologo']

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

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

    def get_debugfile_args(self, targetfile: str) -> typing.List[str]:
        pdbarr = targetfile.split('.')[:-1]
        pdbarr += ['pdb']
        return ['/DEBUG', '/PDB:' + '.'.join(pdbarr)]

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

    def get_allow_undefined_args(self) -> typing.List[str]:
        # link.exe
        return ['/FORCE:UNRESOLVED']

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


class MSVCDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):

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

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


class ClangClDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):

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

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


class XilinkDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):

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

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


class SolarisDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):

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

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

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

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

    def fatal_warnings(self) -> typing.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) -> typing.List[str]:
        if not rpath_paths and not install_rpath and not build_rpath:
            return []
        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 ['-Wl,-rpath,{}'.format(paths)]

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


class OptlinkDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):

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

    def __init__(self, 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.exe'], for_machine, 'optlink', version=version)

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