# Copyright 2014-2016 The Meson development team

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

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

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

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
import re

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

if T.TYPE_CHECKING:
    from ..interpreter import Interpreter


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):
    """
    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):
    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)

class Vs2010Backend(backends.Backend):
    def __init__(self, build: T.Optional[build.Build], interpreter: T.Optional[Interpreter]):
        super().__init__(build, interpreter)
        self.name = 'vs2010'
        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 = {}

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

    def generate_custom_generator_commands(self, target, parent_node):
        generator_output_files = []
        custom_target_include_dirs = []
        custom_target_output_files = []
        target_private_dir = self.relpath(self.get_target_private_dir(target), self.get_target_dir(target))
        down = self.target_to_build_root(target)
        for genlist in target.get_generated_sources():
            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')
                for i, curfile in enumerate(infilelist):
                    if len(infilelist) == len(outfilelist):
                        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))
                    deps = self.get_custom_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
                    )
                    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)
        return generator_output_files, custom_target_output_files, custom_target_include_dirs

    def generate(self):
        target_machine = self.interpreter.builtin['target_machine'].cpu_family_method(None, None)
        if target_machine in {'64', 'x86_64'}:
            # amd64 or x86_64
            target_system = self.interpreter.builtin['target_machine'].system_method(None, None)
            if detect_microsoft_gdk(target_system):
                self.platform = target_system
            else:
                self.platform = 'x64'
        elif target_machine == 'x86':
            # x86
            self.platform = 'Win32'
        elif target_machine in {'aarch64', 'arm64'}:
            target_cpu = self.interpreter.builtin['target_machine'].cpu_method(None, None)
            if target_cpu == 'arm64ec':
                self.platform = 'arm64ec'
            else:
                self.platform = 'arm64'
        elif 'arm' in target_machine.lower():
            self.platform = 'ARM'
        else:
            raise MesonException('Unsupported Visual Studio platform: ' + target_machine)

        build_machine = self.interpreter.builtin['build_machine'].cpu_family_method(None, None)
        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.interpreter.builtin['build_machine'].cpu_method(None, None)
            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()
        self.gen_testproj('RUN_TESTS', os.path.join(self.environment.get_build_dir(), 'RUN_TESTS.vcxproj'))
        self.gen_installproj('RUN_INSTALL', os.path.join(self.environment.get_build_dir(), 'RUN_INSTALL.vcxproj'))
        self.gen_regenproj('REGEN', os.path.join(self.environment.get_build_dir(), 'REGEN.vcxproj'))
        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, build.Target], recursive=False):
        all_deps: T.Dict[str, build.Target] = {}
        for target in t.values():
            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, parents):
        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, projlist):
        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:
                coredata = self.environment.coredata
                if 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')
            regen_line = prj_templ % (self.environment.coredata.lang_guids['default'],
                                      'REGEN', 'REGEN.vcxproj',
                                      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')
            ofile.write('\t\t%s|%s = %s|%s\n' %
                        (self.buildtype, self.platform, self.buildtype,
                         self.platform))
            ofile.write('\tEndGlobalSection\n')
            ofile.write('\tGlobalSection(ProjectConfigurationPlatforms) = '
                        'postSolution\n')
            ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' %
                        (self.environment.coredata.regen_guid, self.buildtype,
                         self.platform, self.buildtype, self.platform))
            ofile.write('\t\t{%s}.%s|%s.Build.0 = %s|%s\n' %
                        (self.environment.coredata.regen_guid, self.buildtype,
                         self.platform, self.buildtype, self.platform))
            # Create the solution configuration
            for p in 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
                ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' %
                            (p[2], self.buildtype, self.platform,
                             self.buildtype, config_platform))
                if p[0] in default_projlist and \
                   not isinstance(self.build.targets[p[0]], build.RunTarget):
                    # Add to the list of projects to be built
                    ofile.write('\t\t{%s}.%s|%s.Build.0 = %s|%s\n' %
                                (p[2], self.buildtype, self.platform,
                                 self.buildtype, config_platform))
            ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' %
                        (self.environment.coredata.test_guid, self.buildtype,
                         self.platform, self.buildtype, self.platform))
            ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' %
                        (self.environment.coredata.install_guid, self.buildtype,
                         self.platform, self.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):
        startup_project = self.environment.coredata.options[OptionKey('backend_startup_project')].value
        projlist = []
        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]
            self.gen_vcxproj(target, str(projfile_path), proj_uuid)
            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, include, projid, link_outputs=False):
        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, 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):
        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
        prjconf = ET.SubElement(confitems, 'ProjectConfiguration',
                                {'Include': self.buildtype + '|' + target_platform})
        p = ET.SubElement(prjconf, 'Configuration')
        p.text = self.buildtype
        pl = ET.SubElement(prjconf, 'Platform')
        pl.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'
        # 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
        pname = ET.SubElement(globalgroup, 'ProjectName')
        pname.text = target_name
        if self.windows_target_platform_version:
            ET.SubElement(globalgroup, 'WindowsTargetPlatformVersion').text = self.windows_target_platform_version
        ET.SubElement(globalgroup, 'UseMultiToolTask').text = 'true'

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

        # Start configuration
        type_config = ET.SubElement(root, 'PropertyGroup', Label='Configuration')
        ET.SubElement(type_config, 'ConfigurationType').text = conftype
        ET.SubElement(type_config, 'CharacterSet').text = 'MultiByte'
        # Fixme: wasn't here before for gen_vcxproj()
        ET.SubElement(type_config, 'UseOfMfc').text = 'false'
        if self.platform_toolset:
            ET.SubElement(type_config, 'PlatformToolset').text = self.platform_toolset

        # End configuration section (but it can be added to further via type_config)
        ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.props')

        # 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

        return (root, type_config)

    def gen_run_target_vcxproj(self, target, ofname, guid):
        (root, type_config) = self.create_basic_project(target.name,
                                                        temp_dir=target.get_id(),
                                                        guid=guid)
        depend_files = self.get_custom_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, ofname, guid):
        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)
        # 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_custom_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, ofname, guid):
        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)
        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)

    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 has_objects(objects, additional_objects, generated_objects):
        # Ignore generated objects, those are automatically used by MSBuild because they are part of
        # the CustomBuild Outputs.
        return len(objects) + len(additional_objects) > 0

    @staticmethod
    def add_generated_objects(node, generated_objects):
        # Do not add generated objects to project file. Those are automatically used by MSBuild, because
        # they are part of the CustomBuild Outputs.
        return

    @staticmethod
    def escape_preprocessor_define(define):
        # 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):
        # 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, ofname):
        ofname_tmp = ofname + '~'
        tree.write(ofname_tmp, encoding='utf-8', xml_declaration=True)

        # ElementTree can not do prettyprinting 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)

    def gen_vcxproj(self, target, ofname, guid):
        mlog.debug(f'Generating vcxproj {target.name}.')
        subsystem = 'Windows'
        self.handled_target_deps[target.get_id()] = []
        if isinstance(target, build.Executable):
            conftype = 'Application'
            if target.gui_app is not None:
                if not target.gui_app:
                    subsystem = 'Console'
            else:
                # 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):
            return self.gen_custom_target_vcxproj(target, ofname, guid)
        elif isinstance(target, build.RunTarget):
            return self.gen_run_target_vcxproj(target, ofname, guid)
        elif isinstance(target, build.CompileTarget):
            return self.gen_compile_target_vcxproj(target, ofname, guid)
        else:
            raise MesonException(f'Unknown target type for {target.get_basename()}')
        # Prefix to use to access the build root from the vcxproj dir
        down = 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(down, 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))
        (sources, headers, objects, languages) = self.split_sources(target.sources)
        if target.is_unity:
            sources = self.generate_unity_files(target, sources)
        compiler = self._get_cl_compiler(target)
        build_args = compiler.get_buildtype_args(self.buildtype)
        build_args += compiler.get_optimization_args(self.optimization)
        build_args += compiler.get_debug_args(self.debug)
        build_args += compiler.sanitizer_compile_args(self.sanitize)
        buildtype_link_args = compiler.get_buildtype_linker_args(self.buildtype)
        vscrt_type = self.environment.coredata.options[OptionKey('b_vscrt')]
        target_name = target.name
        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)

        # FIXME: Should these 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')
        # CRT type; debug or release
        if vscrt_type.value == 'from_buildtype':
            if self.buildtype == 'debug':
                ET.SubElement(type_config, 'UseDebugLibraries').text = 'true'
                ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreadedDebugDLL'
            else:
                ET.SubElement(type_config, 'UseDebugLibraries').text = 'false'
                ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreadedDLL'
        elif vscrt_type.value == 'static_from_buildtype':
            if self.buildtype == 'debug':
                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 = 'MultiThreaded'
        elif vscrt_type.value == 'mdd':
            ET.SubElement(type_config, 'UseDebugLibraries').text = 'true'
            ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreadedDebugDLL'
        elif vscrt_type.value == 'mt':
            # FIXME, wrong
            ET.SubElement(type_config, 'UseDebugLibraries').text = 'false'
            ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreaded'
        elif vscrt_type.value == '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 = self.environment.coredata.options[OptionKey('eh', machine=target.for_machine, lang='cpp')]
            if eh.value == 'a':
                ET.SubElement(clconf, 'ExceptionHandling').text = 'Async'
            elif eh.value == 's':
                ET.SubElement(clconf, 'ExceptionHandling').text = 'SyncCThrow'
            elif eh.value == 'none':
                ET.SubElement(clconf, 'ExceptionHandling').text = 'false'
            else:  # 'sc' or 'default'
                ET.SubElement(clconf, 'ExceptionHandling').text = 'Sync'
        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
        gen_langs += custom_langs

        # 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 = {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)
                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():
            opts = self.environment.coredata.options[OptionKey('args', machine=target.for_machine, lang=l)]
            file_args[l] += opts.value
        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:
                        args.append('-I' + self.relpath(curdir, target.subdir)) # build dir
                        args.append('-I' + os.path.join(proj_to_src_root, curdir))  # src 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 isinstance(d, dependencies.OpenMPDependency):
                ET.SubElement(clconf, 'OpenMPSupport').text = 'true'
            else:
                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)

        languages += gen_langs
        if '/Gw' in build_args:
            target_args.append('/Gw')
        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 = target.get_option(OptionKey('warning_level'))
        ET.SubElement(clconf, 'WarningLevel').text = 'Level' + str(1 + int(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:
            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)
        pch_sources = {}
        if self.environment.coredata.options.get(OptionKey('b_pch')):
            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(down, 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]

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

        # Linker options
        link = ET.SubElement(compiles, 'Link')
        extra_link_args = compiler.compiler_args()
        # FIXME: Can these buildtype linker args be added as tags in the
        # vcxproj file (similar to buildtype compiler args) instead of in
        # AdditionalOptions?
        extra_link_args += compiler.get_buildtype_linker_args(self.buildtype)
        # 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):
                options = self.environment.coredata.options
                extra_link_args += compiler.get_std_shared_module_link_args(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 isinstance(dep, dependencies.OpenMPDependency):
                    ET.SubElement(clconf, 'OpenMPSuppport').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 isinstance(dep, dependencies.OpenMPDependency):
                            ET.SubElement(clconf, 'OpenMPSuppport').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(self.environment.coredata.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:
                        obj_basename = None
                        if self.environment.is_source(src):
                            obj_basename = self.object_filename_from_source(t, src)
                            target_private_dir = self.relpath(self.get_target_private_dir(t),
                                                              self.get_target_dir(t))
                            rel_obj = os.path.join(target_private_dir, obj_basename)
                            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)))
        additional_objects = []
        for o in self.flatten_object_list(target, down)[0]:
            assert isinstance(o, str)
            additional_objects.append(o)
        for o in custom_objs:
            additional_objects.append(o)

        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):
            # 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 self.environment.coredata.get_option(OptionKey('debug')):
            ET.SubElement(link, 'SetChecksum').text = 'true'

        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

        previous_includes = []
        if len(headers) + len(gen_hdrs) + len(target.extra_files) + len(pch_sources) > 0:
            inc_hdrs = ET.SubElement(root, 'ItemGroup')
            for h in headers:
                relpath = os.path.join(down, 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(down, 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:
            inc_src = ET.SubElement(root, 'ItemGroup')
            for s in sources:
                relpath = os.path.join(down, s.rel_to_builddir(self.build_to_src))
                if path_normalize_add(relpath, previous_sources):
                    inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath)
                    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)
                    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)
                    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 name here too?

        previous_objects = []
        if self.has_objects(objects, additional_objects, gen_objs):
            inc_objs = ET.SubElement(root, 'ItemGroup')
            for s in objects:
                relpath = os.path.join(down, 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:
                if path_normalize_add(s, previous_objects):
                    ET.SubElement(inc_objs, 'Object', Include=s)
            self.add_generated_objects(inc_objs, gen_objs)

        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_regenproj(self, project_name, ofname):
        guid = self.environment.coredata.regen_guid
        (root, type_config) = self.create_basic_project(project_name,
                                                        temp_dir='regen-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'
        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, target_name, ofname):
        guid = self.environment.coredata.test_guid
        (root, type_config) = self.create_basic_project(target_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, target_name, ofname):
        self.create_install_data_files()

        guid = self.environment.coredata.install_guid
        (root, type_config) = self.create_basic_project(target_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, rulename, command, deps=None, outputs=None, msg=None, verify_files=True):
        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):
        i = 0
        file = prefix
        while os.path.exists(file):
            file = '%s%d' % (prefix, i)
        return file

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

    def add_regen_dependency(self, root):
        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, clconf):
        pass
