# SPDX-License-Identifier: Apache-2.0
# Copyright 2014-2016 The Meson development team

from __future__ import annotations
import copy
import itertools
import os
import xml.dom.minidom
import xml.etree.ElementTree as ET
import uuid
import typing as T
from pathlib import Path, PurePath, PureWindowsPath
import re
from collections import Counter

from . import backends
from .. import build
from .. import mlog
from .. import compilers
from .. import mesonlib
from ..mesonlib import (
    File, MesonBugException, MesonException, replace_if_different, OptionKey, version_compare, MachineChoice
)
from ..environment import Environment, build_filename
from .. import coredata

if T.TYPE_CHECKING:
    from ..arglist import CompilerArgs
    from ..interpreter import Interpreter

    Project = T.Tuple[str, Path, str, MachineChoice]

def autodetect_vs_version(build: T.Optional[build.Build], interpreter: T.Optional[Interpreter]) -> backends.Backend:
    vs_version = os.getenv('VisualStudioVersion', None)
    vs_install_dir = os.getenv('VSINSTALLDIR', None)
    if not vs_install_dir:
        raise MesonException('Could not detect Visual Studio: Environment variable VSINSTALLDIR is not set!\n'
                             'Are you running meson from the Visual Studio Developer Command Prompt?')
    # VisualStudioVersion is set since Visual Studio 11.0, but sometimes
    # vcvarsall.bat doesn't set it, so also use VSINSTALLDIR
    if vs_version == '11.0' or 'Visual Studio 11' in vs_install_dir:
        from mesonbuild.backend.vs2012backend import Vs2012Backend
        return Vs2012Backend(build, interpreter)
    if vs_version == '12.0' or 'Visual Studio 12' in vs_install_dir:
        from mesonbuild.backend.vs2013backend import Vs2013Backend
        return Vs2013Backend(build, interpreter)
    if vs_version == '14.0' or 'Visual Studio 14' in vs_install_dir:
        from mesonbuild.backend.vs2015backend import Vs2015Backend
        return Vs2015Backend(build, interpreter)
    if vs_version == '15.0' or 'Visual Studio 17' in vs_install_dir or \
       'Visual Studio\\2017' in vs_install_dir:
        from mesonbuild.backend.vs2017backend import Vs2017Backend
        return Vs2017Backend(build, interpreter)
    if vs_version == '16.0' or 'Visual Studio 19' in vs_install_dir or \
       'Visual Studio\\2019' in vs_install_dir:
        from mesonbuild.backend.vs2019backend import Vs2019Backend
        return Vs2019Backend(build, interpreter)
    if vs_version == '17.0' or 'Visual Studio 22' in vs_install_dir or \
       'Visual Studio\\2022' in vs_install_dir:
        from mesonbuild.backend.vs2022backend import Vs2022Backend
        return Vs2022Backend(build, interpreter)
    if 'Visual Studio 10.0' in vs_install_dir:
        return Vs2010Backend(build, interpreter)
    raise MesonException('Could not detect Visual Studio using VisualStudioVersion: {!r} or VSINSTALLDIR: {!r}!\n'
                         'Please specify the exact backend to use.'.format(vs_version, vs_install_dir))


def split_o_flags_args(args: T.List[str]) -> T.List[str]:
    """
    Splits any /O args and returns them. Does not take care of flags overriding
    previous ones. Skips non-O flag arguments.

    ['/Ox', '/Ob1'] returns ['/Ox', '/Ob1']
    ['/Oxj', '/MP'] returns ['/Ox', '/Oj']
    """
    o_flags = []
    for arg in args:
        if not arg.startswith('/O'):
            continue
        flags = list(arg[2:])
        # Assume that this one can't be clumped with the others since it takes
        # an argument itself
        if 'b' in flags:
            o_flags.append(arg)
        else:
            o_flags += ['/O' + f for f in flags]
    return o_flags

def generate_guid_from_path(path, path_type) -> str:
    return str(uuid.uuid5(uuid.NAMESPACE_URL, 'meson-vs-' + path_type + ':' + str(path))).upper()

def detect_microsoft_gdk(platform: str) -> bool:
    return re.match(r'Gaming\.(Desktop|Xbox.XboxOne|Xbox.Scarlett)\.x64', platform, re.IGNORECASE)

def filtered_src_langs_generator(sources: T.List[str]):
    for src in sources:
        ext = src.split('.')[-1]
        if compilers.compilers.is_source_suffix(ext):
            yield compilers.compilers.SUFFIX_TO_LANG[ext]

# Returns the source language (i.e. a key from 'lang_suffixes') of the most frequent source language in the given
# list of sources.
# We choose the most frequent language as 'primary' because it means the most sources in a target/project can
# simply refer to the project's shared intellisense define and include fields, rather than have to fill out their
# own duplicate full set of defines/includes/opts intellisense fields.  All of which helps keep the vcxproj file
# size down.
def get_primary_source_lang(target_sources: T.List[File], custom_sources: T.List[str]) -> T.Optional[str]:
    lang_counts = Counter([compilers.compilers.SUFFIX_TO_LANG[src.suffix] for src in target_sources if compilers.compilers.is_source_suffix(src.suffix)])
    lang_counts += Counter(filtered_src_langs_generator(custom_sources))
    most_common_lang_list = lang_counts.most_common(1)
    # It may be possible that we have a target with no actual src files of interest (e.g. a generator target),
    # leaving us with an empty list, which we should handle -
    return most_common_lang_list[0][0] if most_common_lang_list else None

# Returns a dictionary (by [src type][build type]) that contains a tuple of -
# (pre-processor defines, include paths, additional compiler options)
# fields to use to fill in the respective intellisense fields of sources that can't simply
# reference and re-use the shared 'primary' language intellisense fields of the vcxproj.
def get_non_primary_lang_intellisense_fields(vslite_ctx: dict,
                                             target_id: str,
                                             primary_src_lang: str) -> T.Dict[str, T.Dict[str, T.Tuple[str, str, str]]]:
    defs_paths_opts_per_lang_and_buildtype = {}
    for buildtype in coredata.get_genvs_default_buildtype_list():
        captured_build_args = vslite_ctx[buildtype][target_id] # Results in a 'Src types to compile args' dict
        non_primary_build_args_per_src_lang = [(lang, build_args) for lang, build_args in captured_build_args.items() if lang != primary_src_lang] # Only need to individually populate intellisense fields for sources of non-primary types.
        for src_lang, args_list in non_primary_build_args_per_src_lang:
            if src_lang not in defs_paths_opts_per_lang_and_buildtype:
                defs_paths_opts_per_lang_and_buildtype[src_lang] = {}
            defs_paths_opts_per_lang_and_buildtype[src_lang][buildtype] = Vs2010Backend._extract_nmake_fields(args_list)
    return defs_paths_opts_per_lang_and_buildtype

class Vs2010Backend(backends.Backend):

    name = 'vs2010'

    def __init__(self, build: T.Optional[build.Build], interpreter: T.Optional[Interpreter], gen_lite: bool = False):
        super().__init__(build, interpreter)
        self.project_file_version = '10.0.30319.1'
        self.sln_file_version = '11.00'
        self.sln_version_comment = '2010'
        self.platform_toolset = None
        self.vs_version = '2010'
        self.windows_target_platform_version = None
        self.subdirs = {}
        self.handled_target_deps = {}
        self.gen_lite = gen_lite  # Synonymous with generating the simpler makefile-style multi-config projects that invoke 'meson compile' builds, avoiding native MSBuild complications

    def get_target_private_dir(self, target):
        return os.path.join(self.get_target_dir(target), target.get_id())

    def generate_genlist_for_target(self, genlist: T.Union[build.GeneratedList, build.CustomTarget, build.CustomTargetIndex], target: build.BuildTarget, parent_node: ET.Element, generator_output_files: T.List[str], custom_target_include_dirs: T.List[str], custom_target_output_files: T.List[str]) -> None:
        if isinstance(genlist, build.GeneratedList):
            for x in genlist.depends:
                self.generate_genlist_for_target(x, target, parent_node, [], [], [])
        target_private_dir = self.relpath(self.get_target_private_dir(target), self.get_target_dir(target))
        down = self.target_to_build_root(target)
        if isinstance(genlist, (build.CustomTarget, build.CustomTargetIndex)):
            for i in genlist.get_outputs():
                # Path to the generated source from the current vcxproj dir via the build root
                ipath = os.path.join(down, self.get_target_dir(genlist), i)
                custom_target_output_files.append(ipath)
            idir = self.relpath(self.get_target_dir(genlist), self.get_target_dir(target))
            if idir not in custom_target_include_dirs:
                custom_target_include_dirs.append(idir)
        else:
            generator = genlist.get_generator()
            exe = generator.get_exe()
            infilelist = genlist.get_inputs()
            outfilelist = genlist.get_outputs()
            source_dir = os.path.join(down, self.build_to_src, genlist.subdir)
            idgroup = ET.SubElement(parent_node, 'ItemGroup')
            samelen = len(infilelist) == len(outfilelist)
            for i, curfile in enumerate(infilelist):
                if samelen:
                    sole_output = os.path.join(target_private_dir, outfilelist[i])
                else:
                    sole_output = ''
                infilename = os.path.join(down, curfile.rel_to_builddir(self.build_to_src, target_private_dir))
                deps = self.get_target_depend_files(genlist, True)
                base_args = generator.get_arglist(infilename)
                outfiles_rel = genlist.get_outputs_for(curfile)
                outfiles = [os.path.join(target_private_dir, of) for of in outfiles_rel]
                generator_output_files += outfiles
                args = [x.replace("@INPUT@", infilename).replace('@OUTPUT@', sole_output)
                        for x in base_args]
                args = self.replace_outputs(args, target_private_dir, outfiles_rel)
                args = [x.replace("@SOURCE_DIR@", self.environment.get_source_dir())
                        .replace("@BUILD_DIR@", target_private_dir)
                        for x in args]
                args = [x.replace("@CURRENT_SOURCE_DIR@", source_dir) for x in args]
                args = [x.replace("@SOURCE_ROOT@", self.environment.get_source_dir())
                        .replace("@BUILD_ROOT@", self.environment.get_build_dir())
                        for x in args]
                args = [x.replace('\\', '/') for x in args]
                # Always use a wrapper because MSBuild eats random characters when
                # there are many arguments.
                tdir_abs = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))
                cmd, _ = self.as_meson_exe_cmdline(
                    exe,
                    self.replace_extra_args(args, genlist),
                    workdir=tdir_abs,
                    capture=outfiles[0] if generator.capture else None,
                    force_serialize=True,
                    env=genlist.env
                )
                deps = cmd[-1:] + deps
                abs_pdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))
                os.makedirs(abs_pdir, exist_ok=True)
                cbs = ET.SubElement(idgroup, 'CustomBuild', Include=infilename)
                ET.SubElement(cbs, 'Command').text = ' '.join(self.quote_arguments(cmd))
                ET.SubElement(cbs, 'Outputs').text = ';'.join(outfiles)
                ET.SubElement(cbs, 'AdditionalInputs').text = ';'.join(deps)

    def generate_custom_generator_commands(self, target, parent_node):
        generator_output_files = []
        custom_target_include_dirs = []
        custom_target_output_files = []
        for genlist in target.get_generated_sources():
            self.generate_genlist_for_target(genlist, target, parent_node, generator_output_files, custom_target_include_dirs, custom_target_output_files)
        return generator_output_files, custom_target_output_files, custom_target_include_dirs

    def generate(self,
                 capture: bool = False,
                 vslite_ctx: T.Optional[T.Dict] = None) -> T.Optional[T.Dict]:
        # Check for (currently) unexpected capture arg use cases -
        if capture:
            raise MesonBugException('We do not expect any vs backend to generate with \'capture = True\'')
        host_machine = self.environment.machines.host.cpu_family
        if host_machine in {'64', 'x86_64'}:
            # amd64 or x86_64
            target_system = self.environment.machines.host.system
            if detect_microsoft_gdk(target_system):
                self.platform = target_system
            else:
                self.platform = 'x64'
        elif host_machine == 'x86':
            # x86
            self.platform = 'Win32'
        elif host_machine in {'aarch64', 'arm64'}:
            target_cpu = self.environment.machines.host.cpu
            if target_cpu == 'arm64ec':
                self.platform = 'arm64ec'
            else:
                self.platform = 'arm64'
        elif 'arm' in host_machine.lower():
            self.platform = 'ARM'
        else:
            raise MesonException('Unsupported Visual Studio platform: ' + host_machine)

        build_machine = self.environment.machines.build.cpu_family
        if build_machine in {'64', 'x86_64'}:
            # amd64 or x86_64
            self.build_platform = 'x64'
        elif build_machine == 'x86':
            # x86
            self.build_platform = 'Win32'
        elif build_machine in {'aarch64', 'arm64'}:
            target_cpu = self.environment.machines.build.cpu
            if target_cpu == 'arm64ec':
                self.build_platform = 'arm64ec'
            else:
                self.build_platform = 'arm64'
        elif 'arm' in build_machine.lower():
            self.build_platform = 'ARM'
        else:
            raise MesonException('Unsupported Visual Studio platform: ' + build_machine)

        self.buildtype = self.environment.coredata.get_option(OptionKey('buildtype'))
        self.optimization = self.environment.coredata.get_option(OptionKey('optimization'))
        self.debug = self.environment.coredata.get_option(OptionKey('debug'))
        try:
            self.sanitize = self.environment.coredata.get_option(OptionKey('b_sanitize'))
        except MesonException:
            self.sanitize = 'none'
        sln_filename = os.path.join(self.environment.get_build_dir(), self.build.project_name + '.sln')
        projlist = self.generate_projects(vslite_ctx)
        self.gen_testproj()
        self.gen_installproj()
        self.gen_regenproj()
        self.generate_solution(sln_filename, projlist)
        self.generate_regen_info()
        Vs2010Backend.touch_regen_timestamp(self.environment.get_build_dir())

    @staticmethod
    def get_regen_stampfile(build_dir: str) -> None:
        return os.path.join(os.path.join(build_dir, Environment.private_dir), 'regen.stamp')

    @staticmethod
    def touch_regen_timestamp(build_dir: str) -> None:
        with open(Vs2010Backend.get_regen_stampfile(build_dir), 'w', encoding='utf-8'):
            pass

    def get_vcvars_command(self):
        has_arch_values = 'VSCMD_ARG_TGT_ARCH' in os.environ and 'VSCMD_ARG_HOST_ARCH' in os.environ

        # Use vcvarsall.bat if we found it.
        if 'VCINSTALLDIR' in os.environ:
            vs_version = os.environ['VisualStudioVersion'] \
                if 'VisualStudioVersion' in os.environ else None
            relative_path = 'Auxiliary\\Build\\' if vs_version is not None and vs_version >= '15.0' else ''
            script_path = os.environ['VCINSTALLDIR'] + relative_path + 'vcvarsall.bat'
            if os.path.exists(script_path):
                if has_arch_values:
                    target_arch = os.environ['VSCMD_ARG_TGT_ARCH']
                    host_arch = os.environ['VSCMD_ARG_HOST_ARCH']
                else:
                    target_arch = os.environ.get('Platform', 'x86')
                    host_arch = target_arch
                arch = host_arch + '_' + target_arch if host_arch != target_arch else target_arch
                return f'"{script_path}" {arch}'

        # Otherwise try the VS2017 Developer Command Prompt.
        if 'VS150COMNTOOLS' in os.environ and has_arch_values:
            script_path = os.environ['VS150COMNTOOLS'] + 'VsDevCmd.bat'
            if os.path.exists(script_path):
                return '"%s" -arch=%s -host_arch=%s' % \
                    (script_path, os.environ['VSCMD_ARG_TGT_ARCH'], os.environ['VSCMD_ARG_HOST_ARCH'])
        return ''

    def get_obj_target_deps(self, obj_list):
        result = {}
        for o in obj_list:
            if isinstance(o, build.ExtractedObjects):
                result[o.target.get_id()] = o.target
        return result.items()

    def get_target_deps(self, t: T.Dict[T.Any, T.Union[build.Target, build.CustomTargetIndex]], recursive=False):
        all_deps: T.Dict[str, build.Target] = {}
        for target in t.values():
            if isinstance(target, build.CustomTargetIndex):
                # just transfer it to the CustomTarget code
                target = target.target
            if isinstance(target, build.CustomTarget):
                for d in target.get_target_dependencies():
                    # FIXME: this isn't strictly correct, as the target doesn't
                    # Get dependencies on non-targets, such as Files
                    if isinstance(d, build.Target):
                        all_deps[d.get_id()] = d
            elif isinstance(target, build.RunTarget):
                for d in target.get_dependencies():
                    all_deps[d.get_id()] = d
            elif isinstance(target, build.BuildTarget):
                for ldep in target.link_targets:
                    if isinstance(ldep, build.CustomTargetIndex):
                        all_deps[ldep.get_id()] = ldep.target
                    else:
                        all_deps[ldep.get_id()] = ldep
                for ldep in target.link_whole_targets:
                    if isinstance(ldep, build.CustomTargetIndex):
                        all_deps[ldep.get_id()] = ldep.target
                    else:
                        all_deps[ldep.get_id()] = ldep

                for ldep in target.link_depends:
                    if isinstance(ldep, build.CustomTargetIndex):
                        all_deps[ldep.get_id()] = ldep.target
                    elif isinstance(ldep, File):
                        # Already built, no target references needed
                        pass
                    else:
                        all_deps[ldep.get_id()] = ldep

                for obj_id, objdep in self.get_obj_target_deps(target.objects):
                    all_deps[obj_id] = objdep
            else:
                raise MesonException(f'Unknown target type for target {target}')

            for gendep in target.get_generated_sources():
                if isinstance(gendep, build.CustomTarget):
                    all_deps[gendep.get_id()] = gendep
                elif isinstance(gendep, build.CustomTargetIndex):
                    all_deps[gendep.target.get_id()] = gendep.target
                else:
                    generator = gendep.get_generator()
                    gen_exe = generator.get_exe()
                    if isinstance(gen_exe, build.Executable):
                        all_deps[gen_exe.get_id()] = gen_exe
                    for d in itertools.chain(generator.depends, gendep.depends):
                        if isinstance(d, build.CustomTargetIndex):
                            all_deps[d.get_id()] = d.target
                        elif isinstance(d, build.Target):
                            all_deps[d.get_id()] = d
                        # FIXME: we don't handle other kinds of deps correctly here, such
                        # as GeneratedLists, StructuredSources, and generated File.

        if not t or not recursive:
            return all_deps
        ret = self.get_target_deps(all_deps, recursive)
        ret.update(all_deps)
        return ret

    def generate_solution_dirs(self, ofile: str, parents: T.Sequence[Path]) -> None:
        prj_templ = 'Project("{%s}") = "%s", "%s", "{%s}"\n'
        iterpaths = reversed(parents)
        # Skip first path
        next(iterpaths)
        for path in iterpaths:
            if path not in self.subdirs:
                basename = path.name
                identifier = generate_guid_from_path(path, 'subdir')
                # top-level directories have None as their parent_dir
                parent_dir = path.parent
                parent_identifier = self.subdirs[parent_dir][0] \
                    if parent_dir != PurePath('.') else None
                self.subdirs[path] = (identifier, parent_identifier)
                prj_line = prj_templ % (
                    self.environment.coredata.lang_guids['directory'],
                    basename, basename, self.subdirs[path][0])
                ofile.write(prj_line)
                ofile.write('EndProject\n')

    def generate_solution(self, sln_filename: str, projlist: T.List[Project]) -> None:
        default_projlist = self.get_build_by_default_targets()
        default_projlist.update(self.get_testlike_targets())
        sln_filename_tmp = sln_filename + '~'
        # Note using the utf-8 BOM requires the blank line, otherwise Visual Studio Version Selector fails.
        # Without the BOM, VSVS fails if there is a blank line.
        with open(sln_filename_tmp, 'w', encoding='utf-8-sig') as ofile:
            ofile.write('\nMicrosoft Visual Studio Solution File, Format Version %s\n' % self.sln_file_version)
            ofile.write('# Visual Studio %s\n' % self.sln_version_comment)
            prj_templ = 'Project("{%s}") = "%s", "%s", "{%s}"\n'
            for prj in projlist:
                if self.environment.coredata.get_option(OptionKey('layout')) == 'mirror':
                    self.generate_solution_dirs(ofile, prj[1].parents)
                target = self.build.targets[prj[0]]
                lang = 'default'
                if hasattr(target, 'compilers') and target.compilers:
                    for lang_out in target.compilers.keys():
                        lang = lang_out
                        break
                prj_line = prj_templ % (
                    self.environment.coredata.lang_guids[lang],
                    prj[0], prj[1], prj[2])
                ofile.write(prj_line)
                target_dict = {target.get_id(): target}
                # Get recursive deps
                recursive_deps = self.get_target_deps(
                    target_dict, recursive=True)
                ofile.write('EndProject\n')
                for dep, target in recursive_deps.items():
                    if prj[0] in default_projlist:
                        default_projlist[dep] = target

            test_line = prj_templ % (self.environment.coredata.lang_guids['default'],
                                     'RUN_TESTS', 'RUN_TESTS.vcxproj',
                                     self.environment.coredata.test_guid)
            ofile.write(test_line)
            ofile.write('EndProject\n')
            if self.gen_lite: # REGEN is replaced by the lighter-weight RECONFIGURE utility, for now.  See comment in 'gen_regenproj'
                regen_proj_name = 'RECONFIGURE'
                regen_proj_fname = 'RECONFIGURE.vcxproj'
            else:
                regen_proj_name = 'REGEN'
                regen_proj_fname = 'REGEN.vcxproj'
            regen_line = prj_templ % (self.environment.coredata.lang_guids['default'],
                                      regen_proj_name, regen_proj_fname,
                                      self.environment.coredata.regen_guid)
            ofile.write(regen_line)
            ofile.write('EndProject\n')
            install_line = prj_templ % (self.environment.coredata.lang_guids['default'],
                                        'RUN_INSTALL', 'RUN_INSTALL.vcxproj',
                                        self.environment.coredata.install_guid)
            ofile.write(install_line)
            ofile.write('EndProject\n')
            ofile.write('Global\n')
            ofile.write('\tGlobalSection(SolutionConfigurationPlatforms) = '
                        'preSolution\n')
            multi_config_buildtype_list = coredata.get_genvs_default_buildtype_list() if self.gen_lite else [self.buildtype]
            for buildtype in multi_config_buildtype_list:
                ofile.write('\t\t%s|%s = %s|%s\n' %
                            (buildtype, self.platform, buildtype,
                             self.platform))
            ofile.write('\tEndGlobalSection\n')
            ofile.write('\tGlobalSection(ProjectConfigurationPlatforms) = '
                        'postSolution\n')
            # REGEN project (multi-)configurations
            for buildtype in multi_config_buildtype_list:
                ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' %
                            (self.environment.coredata.regen_guid, buildtype,
                                self.platform, buildtype, self.platform))
                if not self.gen_lite: # With a 'genvslite'-generated solution, the regen (i.e. reconfigure) utility is only intended to run when the user explicitly builds this proj.
                    ofile.write('\t\t{%s}.%s|%s.Build.0 = %s|%s\n' %
                                (self.environment.coredata.regen_guid, buildtype,
                                    self.platform, buildtype, self.platform))
            # Create the solution configuration
            for project_index, p in enumerate(projlist):
                if p[3] is MachineChoice.BUILD:
                    config_platform = self.build_platform
                else:
                    config_platform = self.platform
                # Add to the list of projects in this solution
                for buildtype in multi_config_buildtype_list:
                    ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' %
                                (p[2], buildtype, self.platform,
                                 buildtype, config_platform))
                    # If we're building the solution with Visual Studio's build system, enable building of buildable
                    # projects.  However, if we're building with meson (via --genvslite), then, since each project's
                    # 'build' action just ends up doing the same 'meson compile ...' we don't want the 'solution build'
                    # repeatedly going off and doing the same 'meson compile ...' multiple times over, so we default
                    # to building the startup project, which is the first listed project in the solution file by
                    # default for Visual Studio. The user is free to change this afterwards, but this provides a
                    # sensible default.
                    if (not self.gen_lite or project_index == 0) and \
                       p[0] in default_projlist and \
                       not isinstance(self.build.targets[p[0]], build.RunTarget):
                        ofile.write('\t\t{%s}.%s|%s.Build.0 = %s|%s\n' %
                                    (p[2], buildtype, self.platform,
                                     buildtype, config_platform))
            # RUN_TESTS and RUN_INSTALL project (multi-)configurations
            for buildtype in multi_config_buildtype_list:
                ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' %
                            (self.environment.coredata.test_guid, buildtype,
                             self.platform, buildtype, self.platform))
                ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' %
                            (self.environment.coredata.install_guid, buildtype,
                             self.platform, buildtype, self.platform))
            ofile.write('\tEndGlobalSection\n')
            ofile.write('\tGlobalSection(SolutionProperties) = preSolution\n')
            ofile.write('\t\tHideSolutionNode = FALSE\n')
            ofile.write('\tEndGlobalSection\n')
            if self.subdirs:
                ofile.write('\tGlobalSection(NestedProjects) = '
                            'preSolution\n')
                for p in projlist:
                    if p[1].parent != PurePath('.'):
                        ofile.write("\t\t{{{}}} = {{{}}}\n".format(p[2], self.subdirs[p[1].parent][0]))
                for subdir in self.subdirs.values():
                    if subdir[1]:
                        ofile.write("\t\t{{{}}} = {{{}}}\n".format(subdir[0], subdir[1]))
                ofile.write('\tEndGlobalSection\n')
            ofile.write('EndGlobal\n')
        replace_if_different(sln_filename, sln_filename_tmp)

    def generate_projects(self, vslite_ctx: dict = None) -> T.List[Project]:
        startup_project = self.environment.coredata.optstore.get_value('backend_startup_project')
        projlist: T.List[Project] = []
        startup_idx = 0
        for (i, (name, target)) in enumerate(self.build.targets.items()):
            if startup_project and startup_project == target.get_basename():
                startup_idx = i
            outdir = Path(
                self.environment.get_build_dir(),
                self.get_target_dir(target)
            )
            outdir.mkdir(exist_ok=True, parents=True)
            fname = name + '.vcxproj'
            target_dir = PurePath(self.get_target_dir(target))
            relname = target_dir / fname
            projfile_path = outdir / fname
            proj_uuid = self.environment.coredata.target_guids[name]
            generated = self.gen_vcxproj(target, str(projfile_path), proj_uuid, vslite_ctx)
            if generated:
                projlist.append((name, relname, proj_uuid, target.for_machine))

        # Put the startup project first in the project list
        if startup_idx:
            projlist.insert(0, projlist.pop(startup_idx))

        return projlist

    def split_sources(self, srclist):
        sources = []
        headers = []
        objects = []
        languages = []
        for i in srclist:
            if self.environment.is_header(i):
                headers.append(i)
            elif self.environment.is_object(i):
                objects.append(i)
            elif self.environment.is_source(i):
                sources.append(i)
                lang = self.lang_from_source_file(i)
                if lang not in languages:
                    languages.append(lang)
            elif self.environment.is_library(i):
                pass
            else:
                # Everything that is not an object or source file is considered a header.
                headers.append(i)
        return sources, headers, objects, languages

    def target_to_build_root(self, target):
        if self.get_target_dir(target) == '':
            return ''

        directories = os.path.normpath(self.get_target_dir(target)).split(os.sep)
        return os.sep.join(['..'] * len(directories))

    def quote_arguments(self, arr):
        return ['"%s"' % i for i in arr]

    def add_project_reference(self, root: ET.Element, include: str, projid: str, link_outputs: bool = False) -> None:
        ig = ET.SubElement(root, 'ItemGroup')
        pref = ET.SubElement(ig, 'ProjectReference', Include=include)
        ET.SubElement(pref, 'Project').text = '{%s}' % projid
        if not link_outputs:
            # Do not link in generated .lib files from dependencies automatically.
            # We only use the dependencies for ordering and link in the generated
            # objects and .lib files manually.
            ET.SubElement(pref, 'LinkLibraryDependencies').text = 'false'

    def add_target_deps(self, root: ET.Element, target):
        target_dict = {target.get_id(): target}
        for dep in self.get_target_deps(target_dict).values():
            if dep.get_id() in self.handled_target_deps[target.get_id()]:
                # This dependency was already handled manually.
                continue
            relpath = self.get_target_dir_relative_to(dep, target)
            vcxproj = os.path.join(relpath, dep.get_id() + '.vcxproj')
            tid = self.environment.coredata.target_guids[dep.get_id()]
            self.add_project_reference(root, vcxproj, tid)

    def create_basic_project(self, target_name, *,
                             temp_dir,
                             guid,
                             conftype='Utility',
                             target_ext=None,
                             target_platform=None,
                             gen_manifest=True) -> T.Tuple[ET.Element, ET.Element]:
        root = ET.Element('Project', {'DefaultTargets': "Build",
                                      'ToolsVersion': '4.0',
                                      'xmlns': 'http://schemas.microsoft.com/developer/msbuild/2003'})

        confitems = ET.SubElement(root, 'ItemGroup', {'Label': 'ProjectConfigurations'})
        if not target_platform:
            target_platform = self.platform

        multi_config_buildtype_list = coredata.get_genvs_default_buildtype_list() if self.gen_lite else [self.buildtype]
        if "debug" not in multi_config_buildtype_list:
            multi_config_buildtype_list.append('debug')
        for buildtype in multi_config_buildtype_list:
            prjconf = ET.SubElement(confitems, 'ProjectConfiguration',
                                    {'Include': buildtype + '|' + target_platform})
            ET.SubElement(prjconf, 'Configuration').text = buildtype
            ET.SubElement(prjconf, 'Platform').text = target_platform

        # Globals
        globalgroup = ET.SubElement(root, 'PropertyGroup', Label='Globals')
        guidelem = ET.SubElement(globalgroup, 'ProjectGuid')
        guidelem.text = '{%s}' % guid
        kw = ET.SubElement(globalgroup, 'Keyword')
        kw.text = self.platform + 'Proj'

        ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.Default.props')

        # Configuration
        type_config = ET.SubElement(root, 'PropertyGroup', Label='Configuration')
        ET.SubElement(type_config, 'ConfigurationType').text = conftype
        if self.platform_toolset:
            ET.SubElement(type_config, 'PlatformToolset').text = self.platform_toolset

        # This must come AFTER the '<PropertyGroup Label="Configuration">' element;  importing before the 'PlatformToolset' elt
        # gets set leads to msbuild failures reporting -
        #   "The build tools for v142 (Platform Toolset = 'v142') cannot be found. ... please install v142 build tools."
        # This is extremely unhelpful and misleading since the v14x build tools ARE installed.
        ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.props')

        # This attribute makes sure project names are displayed as expected in solution files even when their project file names differ
        pname = ET.SubElement(globalgroup, 'ProjectName')
        pname.text = target_name

        if not self.gen_lite: # Plenty of elements aren't necessary for 'makefile'-style project that just redirects to meson builds
            # XXX Wasn't here before for anything but gen_vcxproj , but seems fine?
            ns = ET.SubElement(globalgroup, 'RootNamespace')
            ns.text = target_name

            p = ET.SubElement(globalgroup, 'Platform')
            p.text = target_platform
            if self.windows_target_platform_version:
                ET.SubElement(globalgroup, 'WindowsTargetPlatformVersion').text = self.windows_target_platform_version
            ET.SubElement(globalgroup, 'UseMultiToolTask').text = 'true'

            ET.SubElement(type_config, 'CharacterSet').text = 'MultiByte'
            # Fixme: wasn't here before for gen_vcxproj()
            ET.SubElement(type_config, 'UseOfMfc').text = 'false'

            # Project information
            direlem = ET.SubElement(root, 'PropertyGroup')
            fver = ET.SubElement(direlem, '_ProjectFileVersion')
            fver.text = self.project_file_version
            outdir = ET.SubElement(direlem, 'OutDir')
            outdir.text = '.\\'
            intdir = ET.SubElement(direlem, 'IntDir')
            intdir.text = temp_dir + '\\'

            tname = ET.SubElement(direlem, 'TargetName')
            tname.text = target_name

            if target_ext:
                ET.SubElement(direlem, 'TargetExt').text = target_ext

            ET.SubElement(direlem, 'EmbedManifest').text = 'false'
            if not gen_manifest:
                ET.SubElement(direlem, 'GenerateManifest').text = 'false'

        return (root, type_config)

    def gen_run_target_vcxproj(self, target: build.RunTarget, ofname: str, guid: str) -> None:
        (root, type_config) = self.create_basic_project(target.name,
                                                        temp_dir=target.get_id(),
                                                        guid=guid,
                                                        gen_manifest=self.get_gen_manifest(target))
        depend_files = self.get_target_depend_files(target)

        if not target.command:
            # This is an alias target and thus doesn't run any command. It's
            # enough to emit the references to the other projects for them to
            # be built/run/..., if necessary.
            assert isinstance(target, build.AliasTarget)
            assert len(depend_files) == 0
        else:
            assert not isinstance(target, build.AliasTarget)

            target_env = self.get_run_target_env(target)
            _, _, cmd_raw = self.eval_custom_target_command(target)
            wrapper_cmd, _ = self.as_meson_exe_cmdline(target.command[0], cmd_raw[1:],
                                                       force_serialize=True, env=target_env,
                                                       verbose=True)
            self.add_custom_build(root, 'run_target', ' '.join(self.quote_arguments(wrapper_cmd)),
                                  deps=depend_files)

        # The import is needed even for alias targets, otherwise the build
        # target isn't defined
        ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.targets')
        self.add_regen_dependency(root)
        self.add_target_deps(root, target)
        self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)

    def gen_custom_target_vcxproj(self, target: build.CustomTarget, ofname: str, guid: str) -> None:
        if target.for_machine is MachineChoice.BUILD:
            platform = self.build_platform
        else:
            platform = self.platform
        (root, type_config) = self.create_basic_project(target.name,
                                                        temp_dir=target.get_id(),
                                                        guid=guid,
                                                        target_platform=platform,
                                                        gen_manifest=self.get_gen_manifest(target))
        # We need to always use absolute paths because our invocation is always
        # from the target dir, not the build root.
        target.absolute_paths = True
        (srcs, ofilenames, cmd) = self.eval_custom_target_command(target, True)
        depend_files = self.get_target_depend_files(target, True)
        # Always use a wrapper because MSBuild eats random characters when
        # there are many arguments.
        tdir_abs = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))
        extra_bdeps = target.get_transitive_build_target_deps()
        wrapper_cmd, _ = self.as_meson_exe_cmdline(target.command[0], cmd[1:],
                                                   # All targets run from the target dir
                                                   workdir=tdir_abs,
                                                   extra_bdeps=extra_bdeps,
                                                   capture=ofilenames[0] if target.capture else None,
                                                   feed=srcs[0] if target.feed else None,
                                                   force_serialize=True,
                                                   env=target.env,
                                                   verbose=target.console)
        if target.build_always_stale:
            # Use a nonexistent file to always consider the target out-of-date.
            ofilenames += [self.nonexistent_file(os.path.join(self.environment.get_scratch_dir(),
                                                 'outofdate.file'))]
        self.add_custom_build(root, 'custom_target', ' '.join(self.quote_arguments(wrapper_cmd)),
                              deps=wrapper_cmd[-1:] + srcs + depend_files, outputs=ofilenames,
                              verify_files=not target.build_always_stale)
        ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.targets')
        self.generate_custom_generator_commands(target, root)
        self.add_regen_dependency(root)
        self.add_target_deps(root, target)
        self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)

    def gen_compile_target_vcxproj(self, target: build.CompileTarget, ofname: str, guid: str) -> None:
        if target.for_machine is MachineChoice.BUILD:
            platform = self.build_platform
        else:
            platform = self.platform
        (root, type_config) = self.create_basic_project(target.name,
                                                        temp_dir=target.get_id(),
                                                        guid=guid,
                                                        target_platform=platform,
                                                        gen_manifest=self.get_gen_manifest(target))
        ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.targets')
        target.generated = [self.compile_target_to_generator(target)]
        target.sources = []
        self.generate_custom_generator_commands(target, root)
        self.add_regen_dependency(root)
        self.add_target_deps(root, target)
        self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)

    @classmethod
    def lang_from_source_file(cls, src):
        ext = src.split('.')[-1]
        if ext in compilers.c_suffixes:
            return 'c'
        if ext in compilers.cpp_suffixes:
            return 'cpp'
        raise MesonException(f'Could not guess language from source file {src}.')

    def add_pch(self, pch_sources, lang, inc_cl):
        if lang in pch_sources:
            self.use_pch(pch_sources, lang, inc_cl)

    def create_pch(self, pch_sources, lang, inc_cl):
        pch = ET.SubElement(inc_cl, 'PrecompiledHeader')
        pch.text = 'Create'
        self.add_pch_files(pch_sources, lang, inc_cl)

    def use_pch(self, pch_sources, lang, inc_cl):
        pch = ET.SubElement(inc_cl, 'PrecompiledHeader')
        pch.text = 'Use'
        header = self.add_pch_files(pch_sources, lang, inc_cl)
        pch_include = ET.SubElement(inc_cl, 'ForcedIncludeFiles')
        pch_include.text = header + ';%(ForcedIncludeFiles)'

    def add_pch_files(self, pch_sources, lang, inc_cl):
        header = os.path.basename(pch_sources[lang][0])
        pch_file = ET.SubElement(inc_cl, 'PrecompiledHeaderFile')
        # When USING PCHs, MSVC will not do the regular include
        # directory lookup, but simply use a string match to find the
        # PCH to use. That means the #include directive must match the
        # pch_file.text used during PCH CREATION verbatim.
        # When CREATING a PCH, MSVC will do the include directory
        # lookup to find the actual PCH header to use. Thus, the PCH
        # header must either be in the include_directories of the target
        # or be in the same directory as the PCH implementation.
        pch_file.text = header
        pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile')
        pch_out.text = f'$(IntDir)$(TargetName)-{lang}.pch'

        # Need to set the name for the pdb, as cl otherwise gives it a static
        # name. Which leads to problems when there is more than one pch
        # (e.g. for different languages).
        pch_pdb = ET.SubElement(inc_cl, 'ProgramDataBaseFileName')
        pch_pdb.text = f'$(IntDir)$(TargetName)-{lang}.pdb'

        return header

    def is_argument_with_msbuild_xml_entry(self, entry):
        # Remove arguments that have a top level XML entry so
        # they are not used twice.
        # FIXME add args as needed.
        if entry[1:].startswith('fsanitize'):
            return True
        return entry[1:].startswith('M')

    def add_additional_options(self, lang, parent_node, file_args):
        args = []
        for arg in file_args[lang].to_native():
            if self.is_argument_with_msbuild_xml_entry(arg):
                continue
            if arg == '%(AdditionalOptions)':
                args.append(arg)
            else:
                args.append(self.escape_additional_option(arg))
        ET.SubElement(parent_node, "AdditionalOptions").text = ' '.join(args)

    # Set up each project's source file ('CLCompile') element with appropriate preprocessor, include dir, and compile option values for correct intellisense.
    def add_project_nmake_defs_incs_and_opts(self, parent_node, src: str, defs_paths_opts_per_lang_and_buildtype: dict, platform: str):
        # For compactness, sources whose type matches the primary src type (i.e. most frequent in the set of source types used in the target/project,
        # according to the 'captured_build_args' map), can simply reference the preprocessor definitions, include dirs, and compile option NMake fields of
        # the project itself.
        # However, if a src is of a non-primary type, it could have totally different defs/dirs/options so we're going to have to fill in the full, verbose
        # set of values for these fields, which needs to be fully expanded per build type / configuration.
        #
        # FIXME:  Suppose a project contains .cpp and .c src files with different compile defs/dirs/options, while also having .h files, some of which
        # are included by .cpp sources and others included by .c sources:  How do we know whether the .h source should be using the .cpp or .c src
        # defs/dirs/options?  Might it also be possible for a .h header to be shared between .cpp and .c sources?  If so, I don't see how we can
        # correctly configure these intellisense fields.
        # For now, all sources/headers that fail to find their extension's language in the '...nmake_defs_paths_opts...' map will just adopt the project
        # defs/dirs/opts that are set for the nominal 'primary' src type.
        ext = src.split('.')[-1]
        lang = compilers.compilers.SUFFIX_TO_LANG.get(ext, None)
        if lang in defs_paths_opts_per_lang_and_buildtype.keys():
            # This is a non-primary src type for which can't simply reference the project's nmake fields;
            # we must laboriously fill in the fields for all buildtypes.
            for buildtype in coredata.get_genvs_default_buildtype_list():
                (defs, paths, opts) = defs_paths_opts_per_lang_and_buildtype[lang][buildtype]
                condition = f'\'$(Configuration)|$(Platform)\'==\'{buildtype}|{platform}\''
                ET.SubElement(parent_node, 'PreprocessorDefinitions', Condition=condition).text = defs
                ET.SubElement(parent_node, 'AdditionalIncludeDirectories', Condition=condition).text = paths
                ET.SubElement(parent_node, 'AdditionalOptions', Condition=condition).text = opts
        else: # Can't find bespoke nmake defs/dirs/opts fields for this extention, so just reference the project's fields
            ET.SubElement(parent_node, 'PreprocessorDefinitions').text = '$(NMakePreprocessorDefinitions)'
            ET.SubElement(parent_node, 'AdditionalIncludeDirectories').text = '$(NMakeIncludeSearchPath)'
            ET.SubElement(parent_node, 'AdditionalOptions').text = '$(AdditionalOptions)'

    def add_preprocessor_defines(self, lang, parent_node, file_defines):
        defines = []
        for define in file_defines[lang]:
            if define == '%(PreprocessorDefinitions)':
                defines.append(define)
            else:
                defines.append(self.escape_preprocessor_define(define))
        ET.SubElement(parent_node, "PreprocessorDefinitions").text = ';'.join(defines)

    def add_include_dirs(self, lang, parent_node, file_inc_dirs):
        dirs = file_inc_dirs[lang]
        ET.SubElement(parent_node, "AdditionalIncludeDirectories").text = ';'.join(dirs)

    @staticmethod
    def escape_preprocessor_define(define: str) -> str:
        # See: https://msdn.microsoft.com/en-us/library/bb383819.aspx
        table = str.maketrans({'%': '%25', '$': '%24', '@': '%40',
                               "'": '%27', ';': '%3B', '?': '%3F', '*': '%2A',
                               # We need to escape backslash because it'll be un-escaped by
                               # Windows during process creation when it parses the arguments
                               # Basically, this converts `\` to `\\`.
                               '\\': '\\\\'})
        return define.translate(table)

    @staticmethod
    def escape_additional_option(option: str) -> str:
        # See: https://msdn.microsoft.com/en-us/library/bb383819.aspx
        table = str.maketrans({'%': '%25', '$': '%24', '@': '%40',
                               "'": '%27', ';': '%3B', '?': '%3F', '*': '%2A', ' ': '%20'})
        option = option.translate(table)
        # Since we're surrounding the option with ", if it ends in \ that will
        # escape the " when the process arguments are parsed and the starting
        # " will not terminate. So we escape it if that's the case.  I'm not
        # kidding, this is how escaping works for process args on Windows.
        if option.endswith('\\'):
            option += '\\'
        return f'"{option}"'

    @staticmethod
    def split_link_args(args):
        """
        Split a list of link arguments into three lists:
        * library search paths
        * library filenames (or paths)
        * other link arguments
        """
        lpaths = []
        libs = []
        other = []
        for arg in args:
            if arg.startswith('/LIBPATH:'):
                lpath = arg[9:]
                # De-dup library search paths by removing older entries when
                # a new one is found. This is necessary because unlike other
                # search paths such as the include path, the library is
                # searched for in the newest (right-most) search path first.
                if lpath in lpaths:
                    lpaths.remove(lpath)
                lpaths.append(lpath)
            elif arg.startswith(('/', '-')):
                other.append(arg)
            # It's ok if we miss libraries with non-standard extensions here.
            # They will go into the general link arguments.
            elif arg.endswith('.lib') or arg.endswith('.a'):
                # De-dup
                if arg not in libs:
                    libs.append(arg)
            else:
                other.append(arg)
        return lpaths, libs, other

    def _get_cl_compiler(self, target):
        for lang, c in target.compilers.items():
            if lang in {'c', 'cpp'}:
                return c
        # No source files, only objects, but we still need a compiler, so
        # return a found compiler
        if len(target.objects) > 0:
            for lang, c in self.environment.coredata.compilers[target.for_machine].items():
                if lang in {'c', 'cpp'}:
                    return c
        raise MesonException('Could not find a C or C++ compiler. MSVC can only build C/C++ projects.')

    def _prettyprint_vcxproj_xml(self, tree: ET.ElementTree, ofname: str) -> None:
        ofname_tmp = ofname + '~'
        tree.write(ofname_tmp, encoding='utf-8', xml_declaration=True)

        # ElementTree cannot do pretty-printing, so do it manually
        doc = xml.dom.minidom.parse(ofname_tmp)
        with open(ofname_tmp, 'w', encoding='utf-8') as of:
            of.write(doc.toprettyxml())
        replace_if_different(ofname, ofname_tmp)

    # Returns:  (target_args,file_args), (target_defines,file_defines), (target_inc_dirs,file_inc_dirs)
    def get_args_defines_and_inc_dirs(self, target, compiler, generated_files_include_dirs, proj_to_src_root, proj_to_src_dir, build_args):
        # Arguments, include dirs, defines for all files in the current target
        target_args = []
        target_defines = []
        target_inc_dirs = []
        # Arguments, include dirs, defines passed to individual files in
        # a target; perhaps because the args are language-specific
        #
        # file_args is also later split out into defines and include_dirs in
        # case someone passed those in there
        file_args: T.Dict[str, CompilerArgs] = {l: c.compiler_args() for l, c in target.compilers.items()}
        file_defines = {l: [] for l in target.compilers}
        file_inc_dirs = {l: [] for l in target.compilers}
        # The order in which these compile args are added must match
        # generate_single_compile() and generate_basic_compiler_args()
        for l, comp in target.compilers.items():
            if l in file_args:
                file_args[l] += compilers.get_base_compile_args(
                    target.get_options(), comp, self.environment)
                file_args[l] += comp.get_option_compile_args(
                    target.get_options())

        # Add compile args added using add_project_arguments()
        for l, args in self.build.projects_args[target.for_machine].get(target.subproject, {}).items():
            if l in file_args:
                file_args[l] += args
        # Add compile args added using add_global_arguments()
        # These override per-project arguments
        for l, args in self.build.global_args[target.for_machine].items():
            if l in file_args:
                file_args[l] += args
        # Compile args added from the env or cross file: CFLAGS/CXXFLAGS, etc. We want these
        # to override all the defaults, but not the per-target compile args.
        for l in file_args.keys():
            file_args[l] += target.get_option(OptionKey('args', machine=target.for_machine, lang=l))
        for args in file_args.values():
            # This is where Visual Studio will insert target_args, target_defines,
            # etc, which are added later from external deps (see below).
            args += ['%(AdditionalOptions)', '%(PreprocessorDefinitions)', '%(AdditionalIncludeDirectories)']
            # Add custom target dirs as includes automatically, but before
            # target-specific include dirs. See _generate_single_compile() in
            # the ninja backend for caveats.
            args += ['-I' + arg for arg in generated_files_include_dirs]
            # Add include dirs from the `include_directories:` kwarg on the target
            # and from `include_directories:` of internal deps of the target.
            #
            # Target include dirs should override internal deps include dirs.
            # This is handled in BuildTarget.process_kwargs()
            #
            # Include dirs from internal deps should override include dirs from
            # external deps and must maintain the order in which they are
            # specified. Hence, we must reverse so that the order is preserved.
            #
            # These are per-target, but we still add them as per-file because we
            # need them to be looked in first.
            for d in reversed(target.get_include_dirs()):
                # reversed is used to keep order of includes
                for i in reversed(d.get_incdirs()):
                    curdir = os.path.join(d.get_curdir(), i)
                    try:
                        # Add source subdir first so that the build subdir overrides it
                        args.append('-I' + os.path.join(proj_to_src_root, curdir))  # src dir
                        args.append('-I' + self.relpath(curdir, target.subdir)) # build dir
                    except ValueError:
                        # Include is on different drive
                        args.append('-I' + os.path.normpath(curdir))
                for i in d.get_extra_build_dirs():
                    curdir = os.path.join(d.get_curdir(), i)
                    args.append('-I' + self.relpath(curdir, target.subdir))  # build dir
        # Add per-target compile args, f.ex, `c_args : ['/DFOO']`. We set these
        # near the end since these are supposed to override everything else.
        for l, args in target.extra_args.items():
            if l in file_args:
                file_args[l] += args
        # The highest priority includes. In order of directory search:
        # target private dir, target build dir, target source dir
        for args in file_args.values():
            t_inc_dirs = [self.relpath(self.get_target_private_dir(target),
                                       self.get_target_dir(target))]
            if target.implicit_include_directories:
                t_inc_dirs += ['.', proj_to_src_dir]
            args += ['-I' + arg for arg in t_inc_dirs]

        # Split preprocessor defines and include directories out of the list of
        # all extra arguments. The rest go into %(AdditionalOptions).
        for l, args in file_args.items():
            for arg in args[:]:
                if arg.startswith(('-D', '/D')) or arg == '%(PreprocessorDefinitions)':
                    file_args[l].remove(arg)
                    # Don't escape the marker
                    if arg == '%(PreprocessorDefinitions)':
                        define = arg
                    else:
                        define = arg[2:]
                    # De-dup
                    if define not in file_defines[l]:
                        file_defines[l].append(define)
                elif arg.startswith(('-I', '/I')) or arg == '%(AdditionalIncludeDirectories)':
                    file_args[l].remove(arg)
                    # Don't escape the marker
                    if arg == '%(AdditionalIncludeDirectories)':
                        inc_dir = arg
                    else:
                        inc_dir = arg[2:]
                    # De-dup
                    if inc_dir not in file_inc_dirs[l]:
                        file_inc_dirs[l].append(inc_dir)
                    # Add include dirs to target as well so that "Go to Document" works in headers
                    if inc_dir not in target_inc_dirs:
                        target_inc_dirs.append(inc_dir)

        # Split compile args needed to find external dependencies
        # Link args are added while generating the link command
        for d in reversed(target.get_external_deps()):
            # Cflags required by external deps might have UNIX-specific flags,
            # so filter them out if needed
            if d.name != 'openmp':
                d_compile_args = compiler.unix_args_to_native(d.get_compile_args())
                for arg in d_compile_args:
                    if arg.startswith(('-D', '/D')):
                        define = arg[2:]
                        # De-dup
                        if define in target_defines:
                            target_defines.remove(define)
                        target_defines.append(define)
                    elif arg.startswith(('-I', '/I')):
                        inc_dir = arg[2:]
                        # De-dup
                        if inc_dir not in target_inc_dirs:
                            target_inc_dirs.append(inc_dir)
                    else:
                        target_args.append(arg)

        if '/Gw' in build_args:
            target_args.append('/Gw')

        return (target_args, file_args), (target_defines, file_defines), (target_inc_dirs, file_inc_dirs)

    @staticmethod
    def get_build_args(compiler, optimization_level: str, debug: bool, sanitize: str) -> T.List[str]:
        build_args = compiler.get_optimization_args(optimization_level)
        build_args += compiler.get_debug_args(debug)
        build_args += compiler.sanitizer_compile_args(sanitize)

        return build_args

    # Used in populating a simple nmake-style project's intellisense fields.
    # Given a list of compile args, for example -
    #    [ '-I..\\some\\dir\\include', '-I../../some/other/dir', '/MDd', '/W2', '/std:c++17', '/Od', '/Zi', '-DSOME_DEF=1', '-DANOTHER_DEF=someval', ...]
    # returns a tuple of pre-processor defs (for this example) -
    #    'SOME_DEF=1;ANOTHER_DEF=someval;'
    # and include paths, e.g. -
    #    '..\\some\\dir\\include;../../some/other/dir;'
    # and finally any remaining compiler options, e.g. -
    #    '/MDd /W2 /std:c++17 /Od/Zi'
    @staticmethod
    def _extract_nmake_fields(captured_build_args: list[str]) -> T.Tuple[str, str, str]:
        include_dir_options = [
            '-I',
            '/I',
            '-isystem', # regular gcc / clang option to denote system header include search paths
            '/clang:-isystem', # clang-cl (msvc 'cl'-style clang wrapper) option to pass '-isystem' option to clang driver
            '/imsvc', # clang-cl option to 'Add directory to system include search path'
            '/external:I', # msvc cl option to add 'external' include search paths
        ]

        defs = ''
        paths = '$(VC_IncludePath);$(WindowsSDK_IncludePath);'
        additional_opts = ''
        for arg in captured_build_args:
            if arg.startswith(('-D', '/D')):
                defs += arg[2:] + ';'
            else:
                opt_match = next((opt for opt in include_dir_options if arg.startswith(opt)), None)
                if opt_match:
                    paths += arg[len(opt_match):] + ';'
                elif arg.startswith(('-', '/')):
                    additional_opts += arg + ' '
        return (defs, paths, additional_opts)

    @staticmethod
    def get_nmake_base_meson_command_and_exe_search_paths() -> T.Tuple[str, str]:
        meson_cmd_list = mesonlib.get_meson_command()
        assert (len(meson_cmd_list) == 1) or (len(meson_cmd_list) == 2)
        # We expect get_meson_command() to either be of the form -
        #   1:  ['path/to/meson.exe']
        # or -
        #   2:  ['path/to/python.exe', 'and/path/to/meson.py']
        # so we'd like to ensure our makefile-style project invokes the same meson executable or python src as this instance.
        exe_search_paths = os.path.dirname(meson_cmd_list[0])
        nmake_base_meson_command = os.path.basename(meson_cmd_list[0])
        if len(meson_cmd_list) != 1:
            # We expect to be dealing with case '2', shown above.
            # With Windows, it's also possible that we get a path to the second element of meson_cmd_list that contains spaces
            # (e.g. 'and/path to/meson.py').  So, because this will end up directly in the makefile/NMake command lines, we'd
            # better always enclose it in quotes.  Only strictly necessary for paths with spaces but no harm for paths without -
            nmake_base_meson_command += ' \"' + meson_cmd_list[1] + '\"'
            exe_search_paths += ';' + os.path.dirname(meson_cmd_list[1])

        # Additionally, in some cases, we appear to have to add 'C:\Windows\system32;C:\Windows' to the 'Path' environment (via the
        # ExecutablePath element), without which, the 'meson compile ...' (NMakeBuildCommandLine) command can fail (failure to find
        # stdio.h and similar), so something is quietly switching some critical build behaviour based on the presence of these in
        # the 'Path'.
        # Not sure if this ultimately comes down to some 'find and guess' hidden behaviours within meson or within MSVC tools, but
        # I guess some projects may implicitly rely on this behaviour.
        # Things would be cleaner, more robust, repeatable, and portable if meson (and msvc tools) replaced all this kind of
        # find/guess behaviour with the requirement that things just be explicitly specified by the user.
        # An example of this can be seen with -
        #   1:  Download https://github.com/facebook/zstd source
        #   2:  cd to the 'zstd-dev\build\meson' dir
        #   3:  meson setup -Dbin_programs=true -Dbin_contrib=true --genvslite vs2022 builddir_vslite
        #   4:  Open the generated 'builddir_vslite_vs\zstd.sln' and build through a project, which should explicitly add the above to
        #       the project's 'Executable Directories' paths and build successfully.
        #   5:  Remove 'C:\Windows\system32;C:\Windows;' from the same project's 'Executable Directories' paths and rebuild.
        #       This should now fail.
        # It feels uncomfortable to do this but what better alternative is there (and might this introduce new problems)? -
        exe_search_paths += ';C:\\Windows\\system32;C:\\Windows'
        # A meson project that explicitly specifies compiler/linker tools and sdk/include paths is not going to have any problems
        # with this addition.

        return (nmake_base_meson_command, exe_search_paths)

    def add_gen_lite_makefile_vcxproj_elements(self,
                                               root: ET.Element,
                                               platform: str,
                                               target_ext: str,
                                               vslite_ctx: dict,
                                               target,
                                               proj_to_build_root: str,
                                               primary_src_lang: T.Optional[str]) -> None:
        ET.SubElement(root, 'ImportGroup', Label='ExtensionSettings')
        ET.SubElement(root, 'ImportGroup', Label='Shared')
        prop_sheets_grp = ET.SubElement(root, 'ImportGroup', Label='PropertySheets')
        ET.SubElement(prop_sheets_grp, 'Import', {'Project': r'$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props',
                                                  'Condition': r"exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')",
                                                  'Label': 'LocalAppDataPlatform'
                                                  })
        ET.SubElement(root, 'PropertyGroup', Label='UserMacros')

        (nmake_base_meson_command, exe_search_paths) = Vs2010Backend.get_nmake_base_meson_command_and_exe_search_paths()

        # Relative path from this .vcxproj to the directory containing the set of '..._[debug/debugoptimized/release]' setup meson build dirs.
        proj_to_multiconfigured_builds_parent_dir = os.path.join(proj_to_build_root, '..')

        # Conditional property groups per configuration (buildtype). E.g. -
        #   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'">
        multi_config_buildtype_list = coredata.get_genvs_default_buildtype_list()
        for buildtype in multi_config_buildtype_list:
            per_config_prop_group = ET.SubElement(root, 'PropertyGroup', Condition=f'\'$(Configuration)|$(Platform)\'==\'{buildtype}|{platform}\'')
            (_, build_dir_tail) = os.path.split(self.src_to_build)
            meson_build_dir_for_buildtype = build_dir_tail[:-2] + buildtype # Get the buildtype suffixed 'builddir_[debug/release/etc]' from 'builddir_vs', for example.
            proj_to_build_dir_for_buildtype = str(os.path.join(proj_to_multiconfigured_builds_parent_dir, meson_build_dir_for_buildtype))
            ET.SubElement(per_config_prop_group, 'OutDir').text = f'{proj_to_build_dir_for_buildtype}\\'
            ET.SubElement(per_config_prop_group, 'IntDir').text = f'{proj_to_build_dir_for_buildtype}\\'
            ET.SubElement(per_config_prop_group, 'NMakeBuildCommandLine').text = f'{nmake_base_meson_command} compile -C "{proj_to_build_dir_for_buildtype}"'
            ET.SubElement(per_config_prop_group, 'NMakeOutput').text = f'$(OutDir){target.name}{target_ext}'
            captured_build_args = vslite_ctx[buildtype][target.get_id()]
            # 'captured_build_args' is a dictionary, mapping from each src file type to a list of compile args to use for that type.
            # Usually, there's just one but we could have multiple src types.  However, since there's only one field for the makefile
            # project's NMake... preprocessor/include intellisense fields, we'll just use the first src type we have to fill in
            # these fields.  Then, any src files in this VS project that aren't of this first src type will then need to override
            # its intellisense fields instead of simply referencing the values in the project.
            ET.SubElement(per_config_prop_group, 'NMakeReBuildCommandLine').text = f'{nmake_base_meson_command} compile -C "{proj_to_build_dir_for_buildtype}" --clean && {nmake_base_meson_command} compile -C "{proj_to_build_dir_for_buildtype}"'
            ET.SubElement(per_config_prop_group, 'NMakeCleanCommandLine').text = f'{nmake_base_meson_command} compile -C "{proj_to_build_dir_for_buildtype}" --clean'
            # Need to set the 'ExecutablePath' element for the above NMake... commands to be able to invoke the meson command.
            ET.SubElement(per_config_prop_group, 'ExecutablePath').text = exe_search_paths
            # We may not have any src files and so won't have a primary src language.  In which case, we've nothing to fill in for this target's intellisense fields -
            if primary_src_lang:
                primary_src_type_build_args = captured_build_args[primary_src_lang]
                preproc_defs, inc_paths, other_compile_opts = Vs2010Backend._extract_nmake_fields(primary_src_type_build_args)
                ET.SubElement(per_config_prop_group, 'NMakePreprocessorDefinitions').text = preproc_defs
                ET.SubElement(per_config_prop_group, 'NMakeIncludeSearchPath').text = inc_paths
                ET.SubElement(per_config_prop_group, 'AdditionalOptions').text = other_compile_opts

            # Unless we explicitly specify the following empty path elements, the project is assigned a load of nasty defaults that fill these
            # with values like -
            #    $(VC_IncludePath);$(WindowsSDK_IncludePath);
            # which are all based on the current install environment (a recipe for non-reproducibility problems), not the paths that will be used by
            # the actual meson compile jobs.  Although these elements look like they're only for MSBuild operations, they're not needed with our simple,
            # lite/makefile-style projects so let's just remove them in case they do get used/confused by intellisense.
            ET.SubElement(per_config_prop_group, 'IncludePath')
            ET.SubElement(per_config_prop_group, 'ExternalIncludePath')
            ET.SubElement(per_config_prop_group, 'ReferencePath')
            ET.SubElement(per_config_prop_group, 'LibraryPath')
            ET.SubElement(per_config_prop_group, 'LibraryWPath')
            ET.SubElement(per_config_prop_group, 'SourcePath')
            ET.SubElement(per_config_prop_group, 'ExcludePath')

    def add_non_makefile_vcxproj_elements(
            self,
            root: ET.Element,
            type_config: ET.Element,
            target,
            platform: str,
            subsystem,
            build_args,
            target_args,
            target_defines,
            target_inc_dirs,
            file_args
            ) -> None:
        compiler = self._get_cl_compiler(target)
        buildtype_link_args = compiler.get_optimization_link_args(self.optimization)

        # Prefix to use to access the build root from the vcxproj dir
        down = self.target_to_build_root(target)

        # FIXME: Should the following just be set in create_basic_project(), even if
        # irrelevant for current target?

        # FIXME: Meson's LTO support needs to be integrated here
        ET.SubElement(type_config, 'WholeProgramOptimization').text = 'false'
        # Let VS auto-set the RTC level
        ET.SubElement(type_config, 'BasicRuntimeChecks').text = 'Default'
        # Incremental linking increases code size
        if '/INCREMENTAL:NO' in buildtype_link_args:
            ET.SubElement(type_config, 'LinkIncremental').text = 'false'

        # Build information
        compiles = ET.SubElement(root, 'ItemDefinitionGroup')
        clconf = ET.SubElement(compiles, 'ClCompile')
        if True in ((dep.name == 'openmp') for dep in target.get_external_deps()):
            ET.SubElement(clconf, 'OpenMPSupport').text = 'true'
        # CRT type; debug or release
        vscrt_type = target.get_option(OptionKey('b_vscrt'))
        vscrt_val = compiler.get_crt_val(vscrt_type, self.buildtype)
        if vscrt_val == 'mdd':
            ET.SubElement(type_config, 'UseDebugLibraries').text = 'true'
            ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreadedDebugDLL'
        elif vscrt_val == 'mt':
            # FIXME, wrong
            ET.SubElement(type_config, 'UseDebugLibraries').text = 'false'
            ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreaded'
        elif vscrt_val == 'mtd':
            # FIXME, wrong
            ET.SubElement(type_config, 'UseDebugLibraries').text = 'true'
            ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreadedDebug'
        else:
            ET.SubElement(type_config, 'UseDebugLibraries').text = 'false'
            ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreadedDLL'
        # Sanitizers
        if '/fsanitize=address' in build_args:
            ET.SubElement(type_config, 'EnableASAN').text = 'true'
        # Debug format
        if '/ZI' in build_args:
            ET.SubElement(clconf, 'DebugInformationFormat').text = 'EditAndContinue'
        elif '/Zi' in build_args:
            ET.SubElement(clconf, 'DebugInformationFormat').text = 'ProgramDatabase'
        elif '/Z7' in build_args:
            ET.SubElement(clconf, 'DebugInformationFormat').text = 'OldStyle'
        else:
            ET.SubElement(clconf, 'DebugInformationFormat').text = 'None'
        # Runtime checks
        if '/RTC1' in build_args:
            ET.SubElement(clconf, 'BasicRuntimeChecks').text = 'EnableFastChecks'
        elif '/RTCu' in build_args:
            ET.SubElement(clconf, 'BasicRuntimeChecks').text = 'UninitializedLocalUsageCheck'
        elif '/RTCs' in build_args:
            ET.SubElement(clconf, 'BasicRuntimeChecks').text = 'StackFrameRuntimeCheck'
        # Exception handling has to be set in the xml in addition to the "AdditionalOptions" because otherwise
        # cl will give warning D9025: overriding '/Ehs' with cpp_eh value
        if 'cpp' in target.compilers:
            eh = target.get_option(OptionKey('eh', machine=target.for_machine, lang='cpp'))
            if eh == 'a':
                ET.SubElement(clconf, 'ExceptionHandling').text = 'Async'
            elif eh == 's':
                ET.SubElement(clconf, 'ExceptionHandling').text = 'SyncCThrow'
            elif eh == 'none':
                ET.SubElement(clconf, 'ExceptionHandling').text = 'false'
            else:  # 'sc' or 'default'
                ET.SubElement(clconf, 'ExceptionHandling').text = 'Sync'

        if len(target_args) > 0:
            target_args.append('%(AdditionalOptions)')
            ET.SubElement(clconf, "AdditionalOptions").text = ' '.join(target_args)
        ET.SubElement(clconf, 'AdditionalIncludeDirectories').text = ';'.join(target_inc_dirs)
        target_defines.append('%(PreprocessorDefinitions)')
        ET.SubElement(clconf, 'PreprocessorDefinitions').text = ';'.join(target_defines)
        ET.SubElement(clconf, 'FunctionLevelLinking').text = 'true'
        # Warning level
        warning_level = T.cast('str', target.get_option(OptionKey('warning_level')))
        warning_level = 'EnableAllWarnings' if warning_level == 'everything' else 'Level' + str(1 + int(warning_level))
        ET.SubElement(clconf, 'WarningLevel').text = warning_level
        if target.get_option(OptionKey('werror')):
            ET.SubElement(clconf, 'TreatWarningAsError').text = 'true'
        # Optimization flags
        o_flags = split_o_flags_args(build_args)
        if '/Ox' in o_flags:
            ET.SubElement(clconf, 'Optimization').text = 'Full'
        elif '/O2' in o_flags:
            ET.SubElement(clconf, 'Optimization').text = 'MaxSpeed'
        elif '/O1' in o_flags:
            ET.SubElement(clconf, 'Optimization').text = 'MinSpace'
        elif '/Od' in o_flags:
            ET.SubElement(clconf, 'Optimization').text = 'Disabled'
        if '/Oi' in o_flags:
            ET.SubElement(clconf, 'IntrinsicFunctions').text = 'true'
        if '/Ob1' in o_flags:
            ET.SubElement(clconf, 'InlineFunctionExpansion').text = 'OnlyExplicitInline'
        elif '/Ob2' in o_flags:
            ET.SubElement(clconf, 'InlineFunctionExpansion').text = 'AnySuitable'
        # Size-preserving flags
        if '/Os' in o_flags or '/O1' in o_flags:
            ET.SubElement(clconf, 'FavorSizeOrSpeed').text = 'Size'
        # Note: setting FavorSizeOrSpeed with clang-cl conflicts with /Od and can make debugging difficult, so don't.
        elif '/Od' not in o_flags:
            ET.SubElement(clconf, 'FavorSizeOrSpeed').text = 'Speed'
        # Note: SuppressStartupBanner is /NOLOGO and is 'true' by default
        self.generate_lang_standard_info(file_args, clconf)

        resourcecompile = ET.SubElement(compiles, 'ResourceCompile')
        ET.SubElement(resourcecompile, 'PreprocessorDefinitions')

        # Linker options
        link = ET.SubElement(compiles, 'Link')
        extra_link_args = compiler.compiler_args()
        extra_link_args += compiler.get_optimization_link_args(self.optimization)
        # Generate Debug info
        if self.debug:
            self.generate_debug_information(link)
        else:
            ET.SubElement(link, 'GenerateDebugInformation').text = 'false'
        if not isinstance(target, build.StaticLibrary):
            if isinstance(target, build.SharedModule):
                extra_link_args += compiler.get_std_shared_module_link_args(target.get_options())
            # Add link args added using add_project_link_arguments()
            extra_link_args += self.build.get_project_link_args(compiler, target.subproject, target.for_machine)
            # Add link args added using add_global_link_arguments()
            # These override per-project link arguments
            extra_link_args += self.build.get_global_link_args(compiler, target.for_machine)
            # Link args added from the env: LDFLAGS, or the cross file. We want
            # these to override all the defaults but not the per-target link
            # args.
            extra_link_args += self.environment.coredata.get_external_link_args(
                target.for_machine, compiler.get_language())
            # Only non-static built targets need link args and link dependencies
            extra_link_args += target.link_args
            # External deps must be last because target link libraries may depend on them.
            for dep in target.get_external_deps():
                # Extend without reordering or de-dup to preserve `-L -l` sets
                # https://github.com/mesonbuild/meson/issues/1718
                if dep.name == 'openmp':
                    ET.SubElement(clconf, 'OpenMPSupport').text = 'true'
                else:
                    extra_link_args.extend_direct(dep.get_link_args())
            for d in target.get_dependencies():
                if isinstance(d, build.StaticLibrary):
                    for dep in d.get_external_deps():
                        if dep.name == 'openmp':
                            ET.SubElement(clconf, 'OpenMPSupport').text = 'true'
                        else:
                            extra_link_args.extend_direct(dep.get_link_args())
        # Add link args for c_* or cpp_* build options. Currently this only
        # adds c_winlibs and cpp_winlibs when building for Windows. This needs
        # to be after all internal and external libraries so that unresolved
        # symbols from those can be found here. This is needed when the
        # *_winlibs that we want to link to are static mingw64 libraries.
        extra_link_args += compiler.get_option_link_args(target.get_options())
        (additional_libpaths, additional_links, extra_link_args) = self.split_link_args(extra_link_args.to_native())

        # Add more libraries to be linked if needed
        for t in target.get_dependencies():
            if isinstance(t, build.CustomTargetIndex):
                # We don't need the actual project here, just the library name
                lobj = t
            else:
                lobj = self.build.targets[t.get_id()]
            linkname = os.path.join(down, self.get_target_filename_for_linking(lobj))
            if t in target.link_whole_targets:
                if compiler.id == 'msvc' and version_compare(compiler.version, '<19.00.23918'):
                    # Expand our object lists manually if we are on pre-Visual Studio 2015 Update 2
                    l = t.extract_all_objects(False)

                    # Unfortunately, we can't use self.object_filename_from_source()
                    for gen in l.genlist:
                        for src in gen.get_outputs():
                            if self.environment.is_source(src):
                                path = self.get_target_generated_dir(t, gen, src)
                                gen_src_ext = '.' + os.path.splitext(path)[1][1:]
                                extra_link_args.append(path[:-len(gen_src_ext)] + '.obj')

                    for src in l.srclist:
                        if self.environment.is_source(src):
                            target_private_dir = self.relpath(self.get_target_private_dir(t),
                                                              self.get_target_dir(t))
                            rel_obj = self.object_filename_from_source(t, src, target_private_dir)
                            extra_link_args.append(rel_obj)

                    extra_link_args.extend(self.flatten_object_list(t))
                else:
                    # /WHOLEARCHIVE:foo must go into AdditionalOptions
                    extra_link_args += compiler.get_link_whole_for(linkname)
                # To force Visual Studio to build this project even though it
                # has no sources, we include a reference to the vcxproj file
                # that builds this target. Technically we should add this only
                # if the current target has no sources, but it doesn't hurt to
                # have 'extra' references.
                trelpath = self.get_target_dir_relative_to(t, target)
                tvcxproj = os.path.join(trelpath, t.get_id() + '.vcxproj')
                tid = self.environment.coredata.target_guids[t.get_id()]
                self.add_project_reference(root, tvcxproj, tid, link_outputs=True)
                # Mark the dependency as already handled to not have
                # multiple references to the same target.
                self.handled_target_deps[target.get_id()].append(t.get_id())
            else:
                # Other libraries go into AdditionalDependencies
                if linkname not in additional_links:
                    additional_links.append(linkname)
        for lib in self.get_custom_target_provided_libraries(target):
            additional_links.append(self.relpath(lib, self.get_target_dir(target)))

        if len(extra_link_args) > 0:
            extra_link_args.append('%(AdditionalOptions)')
            ET.SubElement(link, "AdditionalOptions").text = ' '.join(extra_link_args)
        if len(additional_libpaths) > 0:
            additional_libpaths.insert(0, '%(AdditionalLibraryDirectories)')
            ET.SubElement(link, 'AdditionalLibraryDirectories').text = ';'.join(additional_libpaths)
        if len(additional_links) > 0:
            additional_links.append('%(AdditionalDependencies)')
            ET.SubElement(link, 'AdditionalDependencies').text = ';'.join(additional_links)
        ofile = ET.SubElement(link, 'OutputFile')
        ofile.text = f'$(OutDir){target.get_filename()}'
        subsys = ET.SubElement(link, 'SubSystem')
        subsys.text = subsystem
        if isinstance(target, (build.SharedLibrary, build.Executable)) and target.get_import_filename():
            # DLLs built with MSVC always have an import library except when
            # they're data-only DLLs, but we don't support those yet.
            ET.SubElement(link, 'ImportLibrary').text = target.get_import_filename()
        if isinstance(target, (build.SharedLibrary, build.Executable)):
            # Add module definitions file, if provided
            if target.vs_module_defs:
                relpath = os.path.join(down, target.vs_module_defs.rel_to_builddir(self.build_to_src))
                ET.SubElement(link, 'ModuleDefinitionFile').text = relpath
        if self.debug:
            pdb = ET.SubElement(link, 'ProgramDataBaseFileName')
            pdb.text = f'$(OutDir){target.name}.pdb'
        targetmachine = ET.SubElement(link, 'TargetMachine')
        if target.for_machine is MachineChoice.BUILD:
            targetplatform = platform.lower()
        else:
            targetplatform = self.platform.lower()
        if targetplatform == 'win32':
            targetmachine.text = 'MachineX86'
        elif targetplatform == 'x64' or detect_microsoft_gdk(targetplatform):
            targetmachine.text = 'MachineX64'
        elif targetplatform == 'arm':
            targetmachine.text = 'MachineARM'
        elif targetplatform == 'arm64':
            targetmachine.text = 'MachineARM64'
        elif targetplatform == 'arm64ec':
            targetmachine.text = 'MachineARM64EC'
        else:
            raise MesonException('Unsupported Visual Studio target machine: ' + targetplatform)
        # /nologo
        ET.SubElement(link, 'SuppressStartupBanner').text = 'true'
        # /release
        if not target.get_option(OptionKey('debug')):
            ET.SubElement(link, 'SetChecksum').text = 'true'

    # Visual studio doesn't simply allow the src files of a project to be added with the 'Condition=...' attribute,
    # to allow us to point to the different debug/debugoptimized/release sets of generated src files for each of
    # the solution's configurations.  Similarly, 'ItemGroup' also doesn't support 'Condition'.  So, without knowing
    # a better (simple) alternative, for now, we'll repoint these generated sources (which will be incorrectly
    # pointing to non-existent files under our '[builddir]_vs' directory) to the appropriate location under one of
    # our buildtype build directores (e.g. '[builddir]_debug').
    # This will at least allow the user to open the files of generated sources listed in the solution explorer,
    # once a build/compile has generated these sources.
    #
    # This modifies the paths in 'gen_files' in place, as opposed to returning a new list of modified paths.
    def relocate_generated_file_paths_to_concrete_build_dir(self, gen_files: T.List[str], target: T.Union[build.Target, build.CustomTargetIndex]) -> None:
        (_, build_dir_tail) = os.path.split(self.src_to_build)
        meson_build_dir_for_buildtype = build_dir_tail[:-2] + coredata.get_genvs_default_buildtype_list()[0] # Get the first buildtype suffixed dir (i.e. '[builddir]_debug') from '[builddir]_vs'
        # Relative path from this .vcxproj to the directory containing the set of '..._[debug/debugoptimized/release]' setup meson build dirs.
        proj_to_build_root = self.target_to_build_root(target)
        proj_to_multiconfigured_builds_parent_dir = os.path.join(proj_to_build_root, '..')
        proj_to_build_dir_for_buildtype = str(os.path.join(proj_to_multiconfigured_builds_parent_dir, meson_build_dir_for_buildtype))
        relocate_to_concrete_builddir_target = os.path.normpath(os.path.join(proj_to_build_dir_for_buildtype, self.get_target_dir(target)))
        for idx, file_path in enumerate(gen_files):
            gen_files[idx] = os.path.normpath(os.path.join(relocate_to_concrete_builddir_target, file_path))

    # Returns bool indicating whether the .vcxproj has been generated.
    # Under some circumstances, it's unnecessary to create some .vcxprojs, so, when generating the .sln,
    # we need to respect that not all targets will have generated a project.
    def gen_vcxproj(self, target: build.BuildTarget, ofname: str, guid: str, vslite_ctx: dict = None) -> bool:
        mlog.debug(f'Generating vcxproj {target.name}.')
        subsystem = 'Windows'
        self.handled_target_deps[target.get_id()] = []

        if self.gen_lite:
            if not isinstance(target, build.BuildTarget):
                # Since we're going to delegate all building to the one true meson build command, we don't need
                # to generate .vcxprojs for targets that don't add any source files or just perform custom build
                # commands.  These are targets of types CustomTarget or RunTarget.  So let's just skip generating
                # these otherwise insubstantial non-BuildTarget targets.
                return False
            conftype = 'Makefile'
        elif isinstance(target, build.Executable):
            conftype = 'Application'
            # If someone knows how to set the version properly,
            # please send a patch.
            subsystem = target.win_subsystem.split(',')[0]
        elif isinstance(target, build.StaticLibrary):
            conftype = 'StaticLibrary'
        elif isinstance(target, build.SharedLibrary):
            conftype = 'DynamicLibrary'
        elif isinstance(target, build.CustomTarget):
            self.gen_custom_target_vcxproj(target, ofname, guid)
            return True
        elif isinstance(target, build.RunTarget):
            self.gen_run_target_vcxproj(target, ofname, guid)
            return True
        elif isinstance(target, build.CompileTarget):
            self.gen_compile_target_vcxproj(target, ofname, guid)
            return True
        else:
            raise MesonException(f'Unknown target type for {target.get_basename()}')

        (sources, headers, objects, _languages) = self.split_sources(target.sources)
        if target.is_unity:
            sources = self.generate_unity_files(target, sources)
        if target.for_machine is MachineChoice.BUILD:
            platform = self.build_platform
        else:
            platform = self.platform

        tfilename = os.path.splitext(target.get_filename())

        (root, type_config) = self.create_basic_project(tfilename[0],
                                                        temp_dir=target.get_id(),
                                                        guid=guid,
                                                        conftype=conftype,
                                                        target_ext=tfilename[1],
                                                        target_platform=platform,
                                                        gen_manifest=self.get_gen_manifest(target))

        generated_files, custom_target_output_files, generated_files_include_dirs = self.generate_custom_generator_commands(
            target, root)
        (gen_src, gen_hdrs, gen_objs, _gen_langs) = self.split_sources(generated_files)
        (custom_src, custom_hdrs, custom_objs, _custom_langs) = self.split_sources(custom_target_output_files)
        gen_src += custom_src
        gen_hdrs += custom_hdrs

        compiler = self._get_cl_compiler(target)
        build_args = Vs2010Backend.get_build_args(compiler, self.optimization, self.debug, self.sanitize)

        assert isinstance(target, (build.Executable, build.SharedLibrary, build.StaticLibrary, build.SharedModule)), 'for mypy'
        # Prefix to use to access the build root from the vcxproj dir
        proj_to_build_root = self.target_to_build_root(target)
        # Prefix to use to access the source tree's root from the vcxproj dir
        proj_to_src_root = os.path.join(proj_to_build_root, self.build_to_src)
        # Prefix to use to access the source tree's subdir from the vcxproj dir
        proj_to_src_dir = os.path.join(proj_to_src_root, self.get_target_dir(target))

        (target_args, file_args), (target_defines, file_defines), (target_inc_dirs, file_inc_dirs) = self.get_args_defines_and_inc_dirs(
            target, compiler, generated_files_include_dirs, proj_to_src_root, proj_to_src_dir, build_args)

        if self.gen_lite:
            assert vslite_ctx is not None
            primary_src_lang = get_primary_source_lang(target.sources, custom_src)
            self.add_gen_lite_makefile_vcxproj_elements(root, platform, tfilename[1], vslite_ctx, target, proj_to_build_root, primary_src_lang)
        else:
            self.add_non_makefile_vcxproj_elements(root, type_config, target, platform, subsystem, build_args, target_args, target_defines, target_inc_dirs, file_args)

        meson_file_group = ET.SubElement(root, 'ItemGroup')
        ET.SubElement(meson_file_group, 'None', Include=os.path.join(proj_to_src_dir, build_filename))

        # Visual Studio can't load projects that present duplicated items. Filter them out
        # by keeping track of already added paths.
        def path_normalize_add(path, lis):
            normalized = os.path.normcase(os.path.normpath(path))
            if normalized not in lis:
                lis.append(normalized)
                return True
            else:
                return False

        pch_sources = {}
        if self.target_uses_pch(target):
            for lang in ['c', 'cpp']:
                pch = target.get_pch(lang)
                if not pch:
                    continue
                if compiler.id == 'msvc':
                    if len(pch) == 1:
                        # Auto generate PCH.
                        src = os.path.join(proj_to_build_root, self.create_msvc_pch_implementation(target, lang, pch[0]))
                        pch_header_dir = os.path.dirname(os.path.join(proj_to_src_dir, pch[0]))
                    else:
                        src = os.path.join(proj_to_src_dir, pch[1])
                        pch_header_dir = None
                    pch_sources[lang] = [pch[0], src, lang, pch_header_dir]
                else:
                    # I don't know whether its relevant but let's handle other compilers
                    # used with a vs backend
                    pch_sources[lang] = [pch[0], None, lang, None]

        previous_includes = []
        if len(headers) + len(gen_hdrs) + len(target.extra_files) + len(pch_sources) > 0:
            if self.gen_lite and gen_hdrs:
                # Although we're constructing our .vcxproj under our '..._vs' directory, we want to reference generated files
                # in our concrete build directories (e.g. '..._debug'), where generated files will exist after building.
                self.relocate_generated_file_paths_to_concrete_build_dir(gen_hdrs, target)

            inc_hdrs = ET.SubElement(root, 'ItemGroup')
            for h in headers:
                relpath = os.path.join(proj_to_build_root, h.rel_to_builddir(self.build_to_src))
                if path_normalize_add(relpath, previous_includes):
                    ET.SubElement(inc_hdrs, 'CLInclude', Include=relpath)
            for h in gen_hdrs:
                if path_normalize_add(h, previous_includes):
                    ET.SubElement(inc_hdrs, 'CLInclude', Include=h)
            for h in target.extra_files:
                relpath = os.path.join(proj_to_build_root, h.rel_to_builddir(self.build_to_src))
                if path_normalize_add(relpath, previous_includes):
                    ET.SubElement(inc_hdrs, 'CLInclude', Include=relpath)
            for headers in pch_sources.values():
                path = os.path.join(proj_to_src_dir, headers[0])
                if path_normalize_add(path, previous_includes):
                    ET.SubElement(inc_hdrs, 'CLInclude', Include=path)

        previous_sources = []
        if len(sources) + len(gen_src) + len(pch_sources) > 0:
            if self.gen_lite:
                # Get data to fill in intellisense fields for sources that can't reference the project-wide values
                defs_paths_opts_per_lang_and_buildtype = get_non_primary_lang_intellisense_fields(
                    vslite_ctx,
                    target.get_id(),
                    primary_src_lang)
                if gen_src:
                    # Although we're constructing our .vcxproj under our '..._vs' directory, we want to reference generated files
                    # in our concrete build directories (e.g. '..._debug'), where generated files will exist after building.
                    self.relocate_generated_file_paths_to_concrete_build_dir(gen_src, target)

            inc_src = ET.SubElement(root, 'ItemGroup')
            for s in sources:
                relpath = os.path.join(proj_to_build_root, s.rel_to_builddir(self.build_to_src))
                if path_normalize_add(relpath, previous_sources):
                    inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath)
                    if self.gen_lite:
                        self.add_project_nmake_defs_incs_and_opts(inc_cl, relpath, defs_paths_opts_per_lang_and_buildtype, platform)
                    else:
                        lang = Vs2010Backend.lang_from_source_file(s)
                        self.add_pch(pch_sources, lang, inc_cl)
                        self.add_additional_options(lang, inc_cl, file_args)
                        self.add_preprocessor_defines(lang, inc_cl, file_defines)
                        self.add_include_dirs(lang, inc_cl, file_inc_dirs)
                        ET.SubElement(inc_cl, 'ObjectFileName').text = "$(IntDir)" + \
                            self.object_filename_from_source(target, s)
            for s in gen_src:
                if path_normalize_add(s, previous_sources):
                    inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=s)
                    if self.gen_lite:
                        self.add_project_nmake_defs_incs_and_opts(inc_cl, s, defs_paths_opts_per_lang_and_buildtype, platform)
                    else:
                        lang = Vs2010Backend.lang_from_source_file(s)
                        self.add_pch(pch_sources, lang, inc_cl)
                        self.add_additional_options(lang, inc_cl, file_args)
                        self.add_preprocessor_defines(lang, inc_cl, file_defines)
                        self.add_include_dirs(lang, inc_cl, file_inc_dirs)
                        s = File.from_built_file(target.get_subdir(), s)
                        ET.SubElement(inc_cl, 'ObjectFileName').text = "$(IntDir)" + \
                            self.object_filename_from_source(target, s)
            for lang, headers in pch_sources.items():
                impl = headers[1]
                if impl and path_normalize_add(impl, previous_sources):
                    inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=impl)
                    self.create_pch(pch_sources, lang, inc_cl)
                    if self.gen_lite:
                        self.add_project_nmake_defs_incs_and_opts(inc_cl, impl, defs_paths_opts_per_lang_and_buildtype, platform)
                    else:
                        self.add_additional_options(lang, inc_cl, file_args)
                        self.add_preprocessor_defines(lang, inc_cl, file_defines)
                        pch_header_dir = pch_sources[lang][3]
                        if pch_header_dir:
                            inc_dirs = copy.deepcopy(file_inc_dirs)
                            inc_dirs[lang] = [pch_header_dir] + inc_dirs[lang]
                        else:
                            inc_dirs = file_inc_dirs
                        self.add_include_dirs(lang, inc_cl, inc_dirs)
                        # XXX: Do we need to set the object file name here too?

        additional_objects = []
        for o in self.flatten_object_list(target, proj_to_build_root)[0]:
            assert isinstance(o, str)
            additional_objects.append(o)
        for o in custom_objs:
            additional_objects.append(o)

        # VS automatically links CustomBuild outputs whose name ends in .obj or .res,
        # but the others need to be included explicitly
        explicit_link_gen_objs = [obj for obj in gen_objs if not obj.endswith(('.obj', '.res'))]

        previous_objects = []
        if len(objects) + len(additional_objects) + len(explicit_link_gen_objs) > 0:
            inc_objs = ET.SubElement(root, 'ItemGroup')
            for s in objects:
                relpath = os.path.join(proj_to_build_root, s.rel_to_builddir(self.build_to_src))
                if path_normalize_add(relpath, previous_objects):
                    ET.SubElement(inc_objs, 'Object', Include=relpath)
            for s in additional_objects + explicit_link_gen_objs:
                if path_normalize_add(s, previous_objects):
                    ET.SubElement(inc_objs, 'Object', Include=s)

        ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.targets')
        self.add_regen_dependency(root)
        if not self.gen_lite:
            # Injecting further target dependencies into this vcxproj implies and forces a Visual Studio BUILD dependency,
            # which we don't want when using 'genvslite'.  A gen_lite build as little involvement with the visual studio's
            # build system as possible.
            self.add_target_deps(root, target)
        self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)
        if self.environment.coredata.get_option(OptionKey('layout')) == 'mirror':
            self.gen_vcxproj_filters(target, ofname)
        return True

    def gen_vcxproj_filters(self, target, ofname):
        # Generate pitchfork of filters based on directory structure.
        root = ET.Element('Project', {'ToolsVersion': '4.0',
                                      'xmlns': 'http://schemas.microsoft.com/developer/msbuild/2003'})
        filter_folders = ET.SubElement(root, 'ItemGroup')
        filter_items = ET.SubElement(root, 'ItemGroup')
        mlog.debug(f'Generating vcxproj filters {target.name}.')

        def relative_to_defined_in(file):
            # Get the relative path to file's directory from the location of the meson.build that defines this target.
            return os.path.dirname(self.relpath(PureWindowsPath(file.subdir, file.fname), self.get_target_dir(target)))

        found_folders_to_filter = {}
        all_files = target.sources + target.extra_files

        # Build a dictionary of all used relative paths (i.e. from the meson.build defining this target)
        # for all sources.
        for i in all_files:
            if not os.path.isabs(i.fname):
                dirname = relative_to_defined_in(i)
                if dirname:
                    found_folders_to_filter[dirname] = ''

        # Now walk up each of those relative paths checking for empty intermediate dirs to generate the filter.
        for folder in found_folders_to_filter:
            dirname = folder
            filter = ''

            while dirname:
                basename = os.path.basename(dirname)

                if filter == '':
                    filter = basename
                else:
                    # Use '/' to squash empty dirs. To actually get a '\', use '%255c'.
                    filter = basename + ('\\' if dirname in found_folders_to_filter else '/') + filter

                dirname = os.path.dirname(dirname)

            # Don't add an empty filter, breaks all other (?) filters.
            if filter != '':
                found_folders_to_filter[folder] = filter
                filter_element = ET.SubElement(filter_folders, 'Filter', {'Include': filter})
                uuid_element = ET.SubElement(filter_element, 'UniqueIdentifier')
                uuid_element.text = '{' + str(uuid.uuid4()).upper() + '}'

        sources, headers, objects, _ = self.split_sources(all_files)
        down = self.target_to_build_root(target)

        def add_element(type_name, elements):
            for i in elements:
                if not os.path.isabs(i.fname):
                    dirname = relative_to_defined_in(i)

                    if dirname and dirname in found_folders_to_filter:
                        relpath = os.path.join(down, i.rel_to_builddir(self.build_to_src))
                        target_element = ET.SubElement(filter_items, type_name, {'Include': relpath})
                        filter_element = ET.SubElement(target_element, 'Filter')
                        filter_element.text = found_folders_to_filter[dirname]

        add_element('ClCompile', sources)
        add_element('ClInclude', headers)
        add_element('Object', objects)

        self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname + '.filters')

    def gen_regenproj(self):
        # To fully adapt the REGEN work for a 'genvslite' solution, to check timestamps, settings, and regenerate the
        # '[builddir]_vs' solution/vcxprojs, as well as regenerating the accompanying buildtype-suffixed ninja build
        # directories (from which we need to first collect correct, updated preprocessor defs and compiler options in
        # order to fill in the regenerated solution's intellisense settings) would require some non-trivial intrusion
        # into the 'meson --internal regencheck ./meson-private' execution path (and perhaps also the '--internal
        # regenerate' and even 'meson setup --reconfigure' code).  So, for now, we'll instead give the user a simpler
        # 'reconfigure' utility project that just runs 'meson setup --reconfigure [builddir]_[buildtype] [srcdir]' on
        # each of the ninja build dirs.
        #
        # FIXME:  That will keep the building and compiling correctly configured but obviously won't update the
        # solution and vcxprojs, which may allow solution src files and intellisense options to go out-of-date;  the
        # user would still have to manually 'meson setup --genvslite [vsxxxx] [builddir] [srcdir]' to fully regenerate
        # a complete and correct solution.
        if self.gen_lite:
            project_name = 'RECONFIGURE'
            ofname = os.path.join(self.environment.get_build_dir(), 'RECONFIGURE.vcxproj')
            conftype = 'Makefile'
            # I find the REGEN project doesn't work; it fails to invoke the appropriate -
            #    python meson.py --internal regencheck builddir\meson-private
            # command, despite the fact that manually running such a command in a shell runs just fine.
            # Running/building the regen project produces the error -
            #    ...Microsoft.CppBuild.targets(460,5): error MSB8020: The build tools for ClangCL (Platform Toolset = 'ClangCL') cannot be found. To build using the ClangCL build tools, please install ...
            # Not sure why but a simple makefile-style project that executes the full '...regencheck...' command actually works (and seems a little simpler).
            # Although I've limited this change to only happen under '--genvslite', perhaps ...
            # FIXME : Should all utility projects use the simpler and less problematic makefile-style project?
        else:
            project_name = 'REGEN'
            ofname = os.path.join(self.environment.get_build_dir(), 'REGEN.vcxproj')
            conftype = 'Utility'

        guid = self.environment.coredata.regen_guid
        (root, type_config) = self.create_basic_project(project_name,
                                                        temp_dir='regen-temp',
                                                        guid=guid,
                                                        conftype=conftype
                                                        )

        if self.gen_lite:
            (nmake_base_meson_command, exe_search_paths) = Vs2010Backend.get_nmake_base_meson_command_and_exe_search_paths()
            all_configs_prop_group = ET.SubElement(root, 'PropertyGroup')

            # Multi-line command to reconfigure all buildtype-suffixed build dirs
            multi_config_buildtype_list = coredata.get_genvs_default_buildtype_list()
            (_, build_dir_tail) = os.path.split(self.src_to_build)
            proj_to_multiconfigured_builds_parent_dir = '..' # We know this RECONFIGURE.vcxproj will always be in the '[buildir]_vs' dir.
            proj_to_src_dir = self.build_to_src
            reconfigure_all_cmd = ''
            for buildtype in multi_config_buildtype_list:
                meson_build_dir_for_buildtype = build_dir_tail[:-2] + buildtype # Get the buildtype suffixed 'builddir_[debug/release/etc]' from 'builddir_vs', for example.
                proj_to_build_dir_for_buildtype = str(os.path.join(proj_to_multiconfigured_builds_parent_dir, meson_build_dir_for_buildtype))
                reconfigure_all_cmd += f'{nmake_base_meson_command} setup --reconfigure "{proj_to_build_dir_for_buildtype}" "{proj_to_src_dir}"\n'
            ET.SubElement(all_configs_prop_group, 'NMakeBuildCommandLine').text = reconfigure_all_cmd
            ET.SubElement(all_configs_prop_group, 'NMakeReBuildCommandLine').text = reconfigure_all_cmd
            ET.SubElement(all_configs_prop_group, 'NMakeCleanCommandLine').text = ''

            #Need to set the 'ExecutablePath' element for the above NMake... commands to be able to execute
            ET.SubElement(all_configs_prop_group, 'ExecutablePath').text = exe_search_paths
        else:
            action = ET.SubElement(root, 'ItemDefinitionGroup')
            midl = ET.SubElement(action, 'Midl')
            ET.SubElement(midl, "AdditionalIncludeDirectories").text = '%(AdditionalIncludeDirectories)'
            ET.SubElement(midl, "OutputDirectory").text = '$(IntDir)'
            ET.SubElement(midl, 'HeaderFileName').text = '%(Filename).h'
            ET.SubElement(midl, 'TypeLibraryName').text = '%(Filename).tlb'
            ET.SubElement(midl, 'InterfaceIdentifierFilename').text = '%(Filename)_i.c'
            ET.SubElement(midl, 'ProxyFileName').text = '%(Filename)_p.c'
            regen_command = self.environment.get_build_command() + ['--internal', 'regencheck']
            cmd_templ = '''call %s > NUL
"%s" "%s"'''
            regen_command = cmd_templ % \
                (self.get_vcvars_command(), '" "'.join(regen_command), self.environment.get_scratch_dir())
            self.add_custom_build(root, 'regen', regen_command, deps=self.get_regen_filelist(),
                                  outputs=[Vs2010Backend.get_regen_stampfile(self.environment.get_build_dir())],
                                  msg='Checking whether solution needs to be regenerated.')

        ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.targets')
        ET.SubElement(root, 'ImportGroup', Label='ExtensionTargets')
        self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)

    def gen_testproj(self):
        project_name = 'RUN_TESTS'
        ofname = os.path.join(self.environment.get_build_dir(), f'{project_name}.vcxproj')
        guid = self.environment.coredata.test_guid
        if self.gen_lite:
            (root, type_config) = self.create_basic_project(project_name,
                                                            temp_dir='install-temp',
                                                            guid=guid,
                                                            conftype='Makefile'
                                                            )
            (nmake_base_meson_command, exe_search_paths) = Vs2010Backend.get_nmake_base_meson_command_and_exe_search_paths()
            multi_config_buildtype_list = coredata.get_genvs_default_buildtype_list()
            (_, build_dir_tail) = os.path.split(self.src_to_build)
            proj_to_multiconfigured_builds_parent_dir = '..' # We know this .vcxproj will always be in the '[buildir]_vs' dir.
            # Add appropriate 'test' commands for the 'build' action of this project, for all buildtypes
            for buildtype in multi_config_buildtype_list:
                meson_build_dir_for_buildtype = build_dir_tail[:-2] + buildtype # Get the buildtype suffixed 'builddir_[debug/release/etc]' from 'builddir_vs', for example.
                proj_to_build_dir_for_buildtype = str(os.path.join(proj_to_multiconfigured_builds_parent_dir, meson_build_dir_for_buildtype))
                test_cmd = f'{nmake_base_meson_command} test -C "{proj_to_build_dir_for_buildtype}" --no-rebuild'
                if not self.environment.coredata.get_option(OptionKey('stdsplit')):
                    test_cmd += ' --no-stdsplit'
                if self.environment.coredata.get_option(OptionKey('errorlogs')):
                    test_cmd += ' --print-errorlogs'
                condition = f'\'$(Configuration)|$(Platform)\'==\'{buildtype}|{self.platform}\''
                prop_group = ET.SubElement(root, 'PropertyGroup', Condition=condition)
                ET.SubElement(prop_group, 'NMakeBuildCommandLine').text = test_cmd
                #Need to set the 'ExecutablePath' element for the NMake... commands to be able to execute
                ET.SubElement(prop_group, 'ExecutablePath').text = exe_search_paths
        else:
            (root, type_config) = self.create_basic_project(project_name,
                                                            temp_dir='test-temp',
                                                            guid=guid)

            action = ET.SubElement(root, 'ItemDefinitionGroup')
            midl = ET.SubElement(action, 'Midl')
            ET.SubElement(midl, "AdditionalIncludeDirectories").text = '%(AdditionalIncludeDirectories)'
            ET.SubElement(midl, "OutputDirectory").text = '$(IntDir)'
            ET.SubElement(midl, 'HeaderFileName').text = '%(Filename).h'
            ET.SubElement(midl, 'TypeLibraryName').text = '%(Filename).tlb'
            ET.SubElement(midl, 'InterfaceIdentifierFilename').text = '%(Filename)_i.c'
            ET.SubElement(midl, 'ProxyFileName').text = '%(Filename)_p.c'
            # FIXME: No benchmarks?
            test_command = self.environment.get_build_command() + ['test', '--no-rebuild']
            if not self.environment.coredata.get_option(OptionKey('stdsplit')):
                test_command += ['--no-stdsplit']
            if self.environment.coredata.get_option(OptionKey('errorlogs')):
                test_command += ['--print-errorlogs']
            self.serialize_tests()
            self.add_custom_build(root, 'run_tests', '"%s"' % ('" "'.join(test_command)))

        ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.targets')
        self.add_regen_dependency(root)
        self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)

    def gen_installproj(self):
        project_name = 'RUN_INSTALL'
        ofname = os.path.join(self.environment.get_build_dir(), f'{project_name}.vcxproj')
        guid = self.environment.coredata.install_guid
        if self.gen_lite:
            (root, type_config) = self.create_basic_project(project_name,
                                                            temp_dir='install-temp',
                                                            guid=guid,
                                                            conftype='Makefile'
                                                            )
            (nmake_base_meson_command, exe_search_paths) = Vs2010Backend.get_nmake_base_meson_command_and_exe_search_paths()
            multi_config_buildtype_list = coredata.get_genvs_default_buildtype_list()
            (_, build_dir_tail) = os.path.split(self.src_to_build)
            proj_to_multiconfigured_builds_parent_dir = '..' # We know this .vcxproj will always be in the '[buildir]_vs' dir.
            # Add appropriate 'install' commands for the 'build' action of this project, for all buildtypes
            for buildtype in multi_config_buildtype_list:
                meson_build_dir_for_buildtype = build_dir_tail[:-2] + buildtype # Get the buildtype suffixed 'builddir_[debug/release/etc]' from 'builddir_vs', for example.
                proj_to_build_dir_for_buildtype = str(os.path.join(proj_to_multiconfigured_builds_parent_dir, meson_build_dir_for_buildtype))
                install_cmd = f'{nmake_base_meson_command} install -C "{proj_to_build_dir_for_buildtype}" --no-rebuild'
                condition = f'\'$(Configuration)|$(Platform)\'==\'{buildtype}|{self.platform}\''
                prop_group = ET.SubElement(root, 'PropertyGroup', Condition=condition)
                ET.SubElement(prop_group, 'NMakeBuildCommandLine').text = install_cmd
                #Need to set the 'ExecutablePath' element for the NMake... commands to be able to execute
                ET.SubElement(prop_group, 'ExecutablePath').text = exe_search_paths
        else:
            self.create_install_data_files()

            (root, type_config) = self.create_basic_project(project_name,
                                                            temp_dir='install-temp',
                                                            guid=guid)

            action = ET.SubElement(root, 'ItemDefinitionGroup')
            midl = ET.SubElement(action, 'Midl')
            ET.SubElement(midl, "AdditionalIncludeDirectories").text = '%(AdditionalIncludeDirectories)'
            ET.SubElement(midl, "OutputDirectory").text = '$(IntDir)'
            ET.SubElement(midl, 'HeaderFileName').text = '%(Filename).h'
            ET.SubElement(midl, 'TypeLibraryName').text = '%(Filename).tlb'
            ET.SubElement(midl, 'InterfaceIdentifierFilename').text = '%(Filename)_i.c'
            ET.SubElement(midl, 'ProxyFileName').text = '%(Filename)_p.c'
            install_command = self.environment.get_build_command() + ['install', '--no-rebuild']
            self.add_custom_build(root, 'run_install', '"%s"' % ('" "'.join(install_command)))

        ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.targets')
        self.add_regen_dependency(root)
        self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)

    def add_custom_build(self, node: ET.Element, rulename: str, command: str, deps: T.Optional[T.List[str]] = None,
                         outputs: T.Optional[T.List[str]] = None, msg: T.Optional[str] = None, verify_files: bool = True) -> None:
        igroup = ET.SubElement(node, 'ItemGroup')
        rulefile = os.path.join(self.environment.get_scratch_dir(), rulename + '.rule')
        if not os.path.exists(rulefile):
            with open(rulefile, 'w', encoding='utf-8') as f:
                f.write("# Meson regen file.")
        custombuild = ET.SubElement(igroup, 'CustomBuild', Include=rulefile)
        if msg:
            message = ET.SubElement(custombuild, 'Message')
            message.text = msg
        if not verify_files:
            ET.SubElement(custombuild, 'VerifyInputsAndOutputsExist').text = 'false'

        # If a command ever were to change the current directory or set local
        # variables this would need to be more complicated, as msbuild by
        # default executes all CustomBuilds in a project using the same
        # shell. Right now such tasks are all done inside the meson_exe
        # wrapper. The trailing newline appears to be necessary to allow
        # parallel custom builds to work.
        ET.SubElement(custombuild, 'Command').text = f"{command}\n"

        if not outputs:
            # Use a nonexistent file to always consider the target out-of-date.
            outputs = [self.nonexistent_file(os.path.join(self.environment.get_scratch_dir(),
                                                          'outofdate.file'))]
        ET.SubElement(custombuild, 'Outputs').text = ';'.join(outputs)
        if deps:
            ET.SubElement(custombuild, 'AdditionalInputs').text = ';'.join(deps)

    @staticmethod
    def nonexistent_file(prefix: str) -> str:
        i = 0
        file = prefix
        while os.path.exists(file):
            file = '%s%d' % (prefix, i)
        return file

    def generate_debug_information(self, link: ET.Element) -> None:
        # valid values for vs2015 is 'false', 'true', 'DebugFastLink'
        ET.SubElement(link, 'GenerateDebugInformation').text = 'true'

    def add_regen_dependency(self, root: ET.Element) -> None:
        # For now, with 'genvslite' solutions, REGEN is replaced by the lighter-weight RECONFIGURE utility that is
        # no longer a forced build dependency.  See comment in 'gen_regenproj'
        if not self.gen_lite:
            regen_vcxproj = os.path.join(self.environment.get_build_dir(), 'REGEN.vcxproj')
            self.add_project_reference(root, regen_vcxproj, self.environment.coredata.regen_guid)

    def generate_lang_standard_info(self, file_args: T.Dict[str, CompilerArgs], clconf: ET.Element) -> None:
        pass

    # Returns if a target generates a manifest or not.
    def get_gen_manifest(self, target):
        if not isinstance(target, build.BuildTarget):
            return True

        compiler = self._get_cl_compiler(target)
        link_args = compiler.compiler_args()
        if not isinstance(target, build.StaticLibrary):
            link_args += self.build.get_project_link_args(compiler, target.subproject, target.for_machine)
            link_args += self.build.get_global_link_args(compiler, target.for_machine)
            link_args += self.environment.coredata.get_external_link_args(
                target.for_machine, compiler.get_language())
            link_args += target.link_args

        for arg in reversed(link_args):
            arg = arg.upper()
            if arg == '/MANIFEST:NO':
                return False
            if arg == '/MANIFEST' or arg.startswith('/MANIFEST:'):
                break
        return True
