Beispiel #1
0
    def _write_filters_file_for(self, filename, formatter, hdr_files, cl_files,
                                idl_files, rc_files):
        root = Node("Project")
        root[
            "ToolsVersion"] = "4.0"  # even if tools_version is different (VS2013)
        root["xmlns"] = "http://schemas.microsoft.com/developer/msbuild/2003"
        filters = Node("ItemGroup")
        root.add(filters)
        f = Node("Filter", Include="Source Files")
        filters.add(f)
        f.add("UniqueIdentifier", "{4FC737F1-C7A5-4376-A066-2A32D752A2FF}")
        f.add("Extensions", "cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx")
        f = Node("Filter", Include="Header Files")
        filters.add(f)
        f.add("UniqueIdentifier", "{93995380-89BD-4b04-88EB-625FBE52EBFB}")
        f.add("Extensions", "h;hpp;hxx;hm;inl;inc;xsd")
        f = Node("Filter", Include="Resource Files")
        filters.add(f)
        f.add("UniqueIdentifier", "{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}")
        f.add(
            "Extensions",
            "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms"
        )

        if hdr_files:
            group = Node("ItemGroup")
            root.add(group)
            for sfile in hdr_files:
                n = Node("ClInclude", Include=sfile.filename)
                group.add(n)
                n.add("Filter", "Header Files")

        if cl_files or idl_files:
            group = Node("ItemGroup")
            root.add(group)
            for sfile in cl_files:
                n = Node("ClCompile", Include=sfile.filename)
                group.add(n)
                n.add("Filter", "Source Files")
            for sfile in idl_files:
                n = Node("Midl", Include=sfile.filename)
                group.add(n)
                n.add("Filter", "Source Files")

        if rc_files:
            group = Node("ItemGroup")
            root.add(group)
            for sfile in rc_files:
                n = Node("ResourceCompile", Include=sfile.filename)
                group.add(n)
                n.add("Filter", "Resource Files")

        f = OutputFile(filename + ".filters",
                       EOL_WINDOWS,
                       creator=self,
                       create_for=filename)
        f.write(codecs.BOM_UTF8)
        f.write(formatter.format(root))
        f.commit()
Beispiel #2
0
 def __init__(self, toolset, module):
     slnfile = module["%s.solutionfile" % toolset.name].as_native_path_for_output(module)
     self.name = module.name
     # unlike targets, modules' names aren't globally unique, so use the fully qualified name, which is
     self.guid = GUID(NAMESPACE_SLN_GROUP, module.project.top_module.name, module.fully_qualified_name)
     self.projects = OrderedDict()
     self.subsolutions = []
     self.parent_solution = None
     paths_info = bkl.expr.PathAnchorsInfo(
                                 dirsep="\\",
                                 outfile=slnfile,
                                 builddir=None,
                                 model=module)
     self.formatter = VSExprFormatter(module.project.settings, paths_info)
     self.generate_outf = module["%s.generate-solution" % toolset.name]
     if self.generate_outf:
         self.outf = OutputFile(slnfile, EOL_WINDOWS,
                                creator=toolset, create_for=module)
     else:
         self.outf = None
Beispiel #3
0
    def gen_for_target(self, target, project):
        rc_files = []
        cl_files = []
        idl_files = []
        for sfile in target.sources:
            ext = sfile.filename.get_extension()
            # TODO: share this code with VS200x
            # FIXME: make this more solid
            if ext == 'rc':
                rc_files.append(sfile)
            elif ext == 'idl':
                idl_files.append(sfile)
            else:
                cl_files.append(sfile)

        root = Node("Project")
        root["DefaultTargets"] = "Build"
        root["ToolsVersion"] = self.tools_version
        root["xmlns"] = "http://schemas.microsoft.com/developer/msbuild/2003"

        n_configs = Node("ItemGroup", Label="ProjectConfigurations")
        for cfg in self.configs_and_platforms(target):
            n = Node("ProjectConfiguration", Include="%s" % cfg.vs_name)
            n.add("Configuration", cfg.name)
            n.add("Platform", cfg.vs_platform)
            n_configs.add(n)
        root.add(n_configs)

        n_globals = Node("PropertyGroup", Label="Globals")
        n_globals.add("ProjectGuid", "{%s}" % project.guid)
        n_globals.add("Keyword", "Win32Proj")
        n_globals.add("RootNamespace", target.name)
        n_globals.add("ProjectName", target.name)
        self._add_extra_options_to_node(target, n_globals)
        root.add(n_globals)

        root.add("Import",
                 Project="$(VCTargetsPath)\\Microsoft.Cpp.Default.props")

        for cfg in self.configs_and_platforms(target):
            n = Node("PropertyGroup", Label="Configuration")
            n["Condition"] = "'$(Configuration)|$(Platform)'=='%s'" % cfg.vs_name
            if is_program(target):
                n.add("ConfigurationType", "Application")
            elif is_library(target):
                n.add("ConfigurationType", "StaticLibrary")
            elif is_dll(target):
                n.add("ConfigurationType", "DynamicLibrary")
            else:
                assert False, "this code should only be called for supported target types"

            n.add("UseDebugLibraries", cfg.is_debug)
            if cfg["win32-unicode"]:
                n.add("CharacterSet", "Unicode")
            else:
                n.add("CharacterSet", "MultiByte")
            if self.platform_toolset:
                n.add("PlatformToolset", self.platform_toolset)
            self._add_extra_options_to_node(cfg, n)
            root.add(n)

        root.add("Import", Project="$(VCTargetsPath)\\Microsoft.Cpp.props")
        root.add("ImportGroup", Label="ExtensionSettings")

        for cfg in self.configs_and_platforms(target):
            n = Node("ImportGroup", Label="PropertySheets")
            n["Condition"] = "'$(Configuration)|$(Platform)'=='%s'" % cfg.vs_name
            n.add(
                "Import",
                Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props",
                Condition=
                "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')",
                Label="LocalAppDataPlatform")
            root.add(n)

        root.add("PropertyGroup", Label="UserMacros")

        for cfg in self.configs_and_platforms(target):
            n = Node("PropertyGroup")
            if not is_library(target):
                n.add("LinkIncremental", cfg.is_debug)
            targetname = cfg["basename"]
            if targetname != target.name:
                n.add("TargetName", targetname)
            if not target.is_variable_null("extension"):
                n.add("TargetExt", target["extension"])
            if is_module_dll(target):
                n.add("IgnoreImportLibrary", True)
            if target.is_variable_explicitly_set("outputdir"):
                n.add("OutDir", concat(cfg["outputdir"], "\\"))
            if self.needs_custom_intermediate_dir(target):
                if cfg.vs_platform != "Win32":
                    intdir = "$(Platform)\\$(Configuration)\\$(ProjectName)\\"
                else:
                    intdir = "$(Configuration)\\$(ProjectName)\\"
                n.add("IntDir", intdir)
            if n.has_children():
                n["Condition"] = "'$(Configuration)|$(Platform)'=='%s'" % cfg.vs_name
            self._add_extra_options_to_node(cfg, n)
            root.add(n)

        for cfg in self.configs_and_platforms(target):
            n = Node("ItemDefinitionGroup")
            n["Condition"] = "'$(Configuration)|$(Platform)'=='%s'" % cfg.vs_name
            n_cl = Node("ClCompile")
            n_cl.add("WarningLevel", self.get_vs_warning_level(cfg))
            if cfg.is_debug:
                n_cl.add("Optimization", "Disabled")
            else:
                n_cl.add("Optimization", "MaxSpeed")
                n_cl.add("FunctionLevelLinking", True)
                n_cl.add("IntrinsicFunctions", True)
            std_defs = self.get_std_defines(target, cfg)
            std_defs.append("%(PreprocessorDefinitions)")
            n_cl.add("PreprocessorDefinitions",
                     list(cfg["defines"]) + std_defs)
            n_cl.add("MultiProcessorCompilation", True)
            n_cl.add("MinimalRebuild", False)
            n_cl.add("AdditionalIncludeDirectories", cfg["includedirs"])

            crt = "MultiThreaded"
            if cfg.is_debug:
                crt += "Debug"
            if cfg["win32-crt-linkage"] == "dll":
                crt += "DLL"
            n_cl.add("RuntimeLibrary", crt)

            # Currently we don't make any distinction between preprocessor, C
            # and C++ flags as they're basically all the same at MSVS level
            # too and all go into the same place in the IDE and same
            # AdditionalOptions node in the project file.
            all_cflags = VSList(" ", cfg["compiler-options"],
                                cfg["c-compiler-options"],
                                cfg["cxx-compiler-options"])
            if all_cflags:
                all_cflags.append("%(AdditionalOptions)")
                n_cl.add("AdditionalOptions", all_cflags)

            self._add_extra_options_to_node(cfg, n_cl)
            n.add(n_cl)

            if rc_files:
                n_res = Node("ResourceCompile")
                n_res.add("AdditionalIncludeDirectories", cfg["includedirs"])
                std_defs = []
                if cfg["win32-unicode"]:
                    std_defs.append("_UNICODE")
                    std_defs.append("UNICODE")
                # See the comment in VCResourceCompilerTool in vs200x.py for
                # the explanation of why do we do this even though the native
                # projects don't define _DEBUG/NDEBUG for the RC files.
                std_defs.append("_DEBUG" if cfg.is_debug else "NDEBUG")
                std_defs.append("%(PreprocessorDefinitions)")
                n_res.add("PreprocessorDefinitions",
                          list(cfg["defines"]) + std_defs)
                self._add_extra_options_to_node(cfg, n_res)
                n.add(n_res)

            if idl_files:
                n_idl = Node("Midl")
                n_idl.add("AdditionalIncludeDirectories", cfg["includedirs"])
                self._add_extra_options_to_node(cfg, n_idl)
                n.add(n_idl)

            n_link = Node("Link")
            if is_program(target) and target["win32-subsystem"] == "console":
                n_link.add("SubSystem", "Console")
            else:
                n_link.add("SubSystem", "Windows")
            n_link.add("GenerateDebugInformation", True)
            if not cfg.is_debug:
                n_link.add("EnableCOMDATFolding", True)
                n_link.add("OptimizeReferences", True)
            if not is_library(target):
                libdirs = VSList(";", target.type.get_libdirs(cfg))
                if libdirs:
                    libdirs.append("%(AdditionalLibraryDirectories)")
                    n_link.add("AdditionalLibraryDirectories", libdirs)
                ldflags = VSList(" ", target.type.get_link_options(cfg))
                if ldflags:
                    ldflags.append("%(AdditionalOptions)")
                    n_link.add("AdditionalOptions", ldflags)
                libs = target.type.get_ldlibs(cfg)
                if libs:
                    addlibs = VSList(";",
                                     ("%s.lib" % x.as_py() for x in libs if x))
                    addlibs.append("%(AdditionalDependencies)")
                    if is_library(target):
                        n_lib = Node("Lib")
                        self._add_extra_options_to_node(cfg, n_lib)
                        n.add(n_lib)
                        n_lib.add("AdditionalDependencies", addlibs)
                    else:
                        n_link.add("AdditionalDependencies", addlibs)
            self._add_extra_options_to_node(cfg, n_link)
            n.add(n_link)
            pre_build = cfg["pre-build-commands"]
            if pre_build:
                n_script = Node("PreBuildEvent")
                n_script.add("Command", VSList("\n", pre_build))
                n.add(n_script)
            post_build = cfg["post-build-commands"]
            if post_build:
                n_script = Node("PostBuildEvent")
                n_script.add("Command", VSList("\n", post_build))
                n.add(n_script)
            root.add(n)

        # Source files:
        if cl_files:
            items = Node("ItemGroup")
            root.add(items)
            cl_files_map = bkl.compilers.disambiguate_intermediate_file_names(
                cl_files)
            for sfile in cl_files:
                if sfile["compile-commands"]:
                    self._add_custom_build_file(items, sfile)
                else:
                    ext = sfile.filename.get_extension()
                    # TODO: share this code with VS200x
                    # FIXME: make this more solid
                    if ext in ['cpp', 'cxx', 'cc', 'c']:
                        n_cl_compile = Node("ClCompile",
                                            Include=sfile.filename)
                    else:
                        # FIXME: handle both compilation into cpp and c files
                        genfiletype = bkl.compilers.CxxFileType.get()
                        genname = bkl.expr.PathExpr(
                            [
                                bkl.expr.LiteralExpr(
                                    sfile.filename.get_basename())
                            ],
                            bkl.expr.ANCHOR_BUILDDIR,
                            pos=sfile.filename.pos).change_extension("cpp")

                        ft_from = bkl.compilers.get_file_type(ext)
                        compiler = bkl.compilers.get_compiler(
                            self, ft_from, genfiletype)

                        customBuild = Node("CustomBuild",
                                           Include=sfile.filename)
                        customBuild.add(
                            "Command",
                            VSList(
                                "\n",
                                compiler.commands(self, target, sfile.filename,
                                                  genname)))
                        customBuild.add("Outputs", genname)
                        items.add(customBuild)
                        n_cl_compile = Node("ClCompile", Include=genname)
                    # Handle files with custom object name:
                    if sfile in cl_files_map:
                        n_cl_compile.add(
                            "ObjectFileName",
                            concat("$(IntDir)\\", cl_files_map[sfile], ".obj"))
                    self._add_per_file_options(sfile, n_cl_compile)
                    items.add(n_cl_compile)

        # Headers files:
        if target.headers:
            items = Node("ItemGroup")
            root.add(items)
            for sfile in target.headers:
                if sfile["compile-commands"]:
                    self._add_custom_build_file(items, sfile)
                else:
                    items.add("ClInclude", Include=sfile.filename)

        # Resources:
        if rc_files:
            items = Node("ItemGroup")
            root.add(items)
            rc_files_map = bkl.compilers.disambiguate_intermediate_file_names(
                rc_files)
            for sfile in rc_files:
                n_rc_compile = Node("ResourceCompile", Include=sfile.filename)
                # Handle files with custom object name:
                if sfile in rc_files_map:
                    n_rc_compile.add(
                        "ResourceOutputFileName",
                        concat("$(IntDir)\\", rc_files_map[sfile], ".res"))
                self._add_per_file_options(sfile, n_rc_compile)
                items.add(n_rc_compile)

        # IDL files:
        if idl_files:
            items = Node("ItemGroup")
            root.add(items)
            for sfile in idl_files:
                n_midl = Node("Midl", Include=sfile.filename)
                self._add_per_file_options(sfile, n_midl)
                items.add(n_midl)

        # Dependencies:
        target_deps = self._get_references(target)
        if target_deps:
            refs = Node("ItemGroup")
            root.add(refs)
            for dep in target_deps:
                dep_prj = self.get_project_object(dep)
                depnode = Node("ProjectReference", Include=dep_prj.projectfile)
                depnode.add("Project", "{%s}" % dep_prj.guid.lower())
                refs.add(depnode)

        root.add("Import", Project="$(VCTargetsPath)\\Microsoft.Cpp.targets")
        root.add("ImportGroup", Label="ExtensionTargets")

        filename = project.projectfile.as_native_path_for_output(target)
        paths_info = self.get_project_paths_info(target, project)

        formatter = self.XmlFormatter(target.project.settings, paths_info)
        f = OutputFile(filename, EOL_WINDOWS, creator=self, create_for=target)
        f.write(codecs.BOM_UTF8)
        f.write(formatter.format(root))
        f.commit()
        self._write_filters_file_for(filename, formatter, target.headers,
                                     cl_files, idl_files, rc_files)
Beispiel #4
0
    def gen_for_target(self, target, project):
        rc_files = []
        cl_files = []
        idl_files = []
        for sfile in target.sources:
            ext = sfile.filename.get_extension()
            # TODO: share this code with VS200x
            # FIXME: make this more solid
            if ext == 'rc':
                rc_files.append(sfile)
            elif ext == 'idl':
                idl_files.append(sfile)
            else:
                cl_files.append(sfile)

        root = Node("Project")
        root["DefaultTargets"] = "Build"
        root["ToolsVersion"] = self.tools_version
        root["xmlns"] = "http://schemas.microsoft.com/developer/msbuild/2003"

        n_configs = Node("ItemGroup", Label="ProjectConfigurations")
        for cfg in self.configs_and_platforms(target):
            n = Node("ProjectConfiguration", Include="%s" % cfg.vs_name)
            n.add("Configuration", cfg.name)
            n.add("Platform", cfg.vs_platform)
            n_configs.add(n)
        root.add(n_configs)

        n_globals = Node("PropertyGroup", Label="Globals")
        n_globals.add("ProjectGuid", "{%s}" % project.guid)
        n_globals.add("Keyword", "Win32Proj")
        n_globals.add("RootNamespace", target.name)
        n_globals.add("ProjectName", target.name)
        self._add_extra_options_to_node(target, n_globals)
        root.add(n_globals)

        root.add("Import", Project="$(VCTargetsPath)\\Microsoft.Cpp.Default.props")

        for cfg in self.configs_and_platforms(target):
            n = Node("PropertyGroup", Label="Configuration")
            n["Condition"] = "'$(Configuration)|$(Platform)'=='%s'" % cfg.vs_name
            if is_program(target):
                n.add("ConfigurationType", "Application")
            elif is_library(target):
                n.add("ConfigurationType", "StaticLibrary")
            elif is_dll(target):
                n.add("ConfigurationType", "DynamicLibrary")
            else:
                assert False, "this code should only be called for supported target types"

            n.add("UseDebugLibraries", cfg.is_debug)
            if cfg["win32-unicode"]:
                n.add("CharacterSet", "Unicode")
            else:
                n.add("CharacterSet", "MultiByte")
            if self.platform_toolset:
                n.add("PlatformToolset", self.platform_toolset)
            self._add_extra_options_to_node(cfg, n)
            root.add(n)

        root.add("Import", Project="$(VCTargetsPath)\\Microsoft.Cpp.props")
        root.add("ImportGroup", Label="ExtensionSettings")

        for cfg in self.configs_and_platforms(target):
            n = Node("ImportGroup", Label="PropertySheets")
            n["Condition"] = "'$(Configuration)|$(Platform)'=='%s'" % cfg.vs_name
            n.add("Import",
                  Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props",
                  Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')",
                  Label="LocalAppDataPlatform")
            root.add(n)

        root.add("PropertyGroup", Label="UserMacros")

        for cfg in self.configs_and_platforms(target):
            n = Node("PropertyGroup")
            if not is_library(target):
                n.add("LinkIncremental", cfg.is_debug)
            targetname = cfg["basename"]
            if targetname != target.name:
                n.add("TargetName", targetname)
            if not target.is_variable_null("extension"):
                n.add("TargetExt", target["extension"])
            if is_module_dll(target):
                n.add("IgnoreImportLibrary", True)
            if target.is_variable_explicitly_set("outputdir"):
                n.add("OutDir", concat(cfg["outputdir"], "\\"))
            if self.needs_custom_intermediate_dir(target):
                if cfg.vs_platform != "Win32":
                    intdir = "$(Platform)\\$(Configuration)\\$(ProjectName)\\"
                else:
                    intdir = "$(Configuration)\\$(ProjectName)\\"
                n.add("IntDir", intdir)
            if n.has_children():
                n["Condition"] = "'$(Configuration)|$(Platform)'=='%s'" % cfg.vs_name
            self._add_extra_options_to_node(cfg, n)
            root.add(n)

        for cfg in self.configs_and_platforms(target):
            n = Node("ItemDefinitionGroup")
            n["Condition"] = "'$(Configuration)|$(Platform)'=='%s'" % cfg.vs_name
            n_cl = Node("ClCompile")
            n_cl.add("WarningLevel", self.get_vs_warning_level(cfg))
            if cfg.is_debug:
                n_cl.add("Optimization", "Disabled")
            else:
                n_cl.add("Optimization", "MaxSpeed")
                n_cl.add("FunctionLevelLinking", True)
                n_cl.add("IntrinsicFunctions", True)
            std_defs = self.get_std_defines(target, cfg)
            std_defs.append("%(PreprocessorDefinitions)")
            n_cl.add("PreprocessorDefinitions", list(cfg["defines"]) + std_defs)
            n_cl.add("MultiProcessorCompilation", True)
            n_cl.add("MinimalRebuild", False)
            n_cl.add("AdditionalIncludeDirectories", cfg["includedirs"])

            crt = "MultiThreaded"
            if cfg.is_debug:
                crt += "Debug"
            if cfg["win32-crt-linkage"] == "dll":
                crt += "DLL"
            n_cl.add("RuntimeLibrary", crt)

            # Currently we don't make any distinction between preprocessor, C
            # and C++ flags as they're basically all the same at MSVS level
            # too and all go into the same place in the IDE and same
            # AdditionalOptions node in the project file.
            all_cflags = VSList(" ", cfg["compiler-options"],
                                     cfg["c-compiler-options"],
                                     cfg["cxx-compiler-options"])
            if all_cflags:
                all_cflags.append("%(AdditionalOptions)")
                n_cl.add("AdditionalOptions", all_cflags)

            self._add_extra_options_to_node(cfg, n_cl)
            n.add(n_cl)

            if rc_files:
                n_res = Node("ResourceCompile")
                n_res.add("AdditionalIncludeDirectories", cfg["includedirs"])
                std_defs = []
                if cfg["win32-unicode"]:
                    std_defs.append("_UNICODE")
                    std_defs.append("UNICODE")
                # See the comment in VCResourceCompilerTool in vs200x.py for
                # the explanation of why do we do this even though the native
                # projects don't define _DEBUG/NDEBUG for the RC files.
                std_defs.append("_DEBUG" if cfg.is_debug else "NDEBUG")
                std_defs.append("%(PreprocessorDefinitions)")
                n_res.add("PreprocessorDefinitions", list(cfg["defines"]) + std_defs)
                self._add_extra_options_to_node(cfg, n_res)
                n.add(n_res)

            if idl_files:
                n_idl = Node("Midl")
                n_idl.add("AdditionalIncludeDirectories", cfg["includedirs"])
                self._add_extra_options_to_node(cfg, n_idl)
                n.add(n_idl)

            n_link = Node("Link")
            if is_program(target) and target["win32-subsystem"] == "console":
                n_link.add("SubSystem", "Console")
            else:
                n_link.add("SubSystem", "Windows")
            n_link.add("GenerateDebugInformation", True)
            if not cfg.is_debug:
                n_link.add("EnableCOMDATFolding", True)
                n_link.add("OptimizeReferences", True)
            if not is_library(target):
                libdirs = VSList(";", target.type.get_libdirs(cfg))
                if libdirs:
                    libdirs.append("%(AdditionalLibraryDirectories)")
                    n_link.add("AdditionalLibraryDirectories", libdirs)
                ldflags = VSList(" ", target.type.get_link_options(cfg))
                if ldflags:
                    ldflags.append("%(AdditionalOptions)")
                    n_link.add("AdditionalOptions", ldflags)
                libs = target.type.get_ldlibs(cfg)
                if libs:
                    addlibs = VSList(";", ("%s.lib" % x.as_py() for x in libs if x))
                    addlibs.append("%(AdditionalDependencies)")
                    if is_library(target):
                        n_lib = Node("Lib")
                        self._add_extra_options_to_node(cfg, n_lib)
                        n.add(n_lib)
                        n_lib.add("AdditionalDependencies", addlibs)
                    else:
                        n_link.add("AdditionalDependencies", addlibs)
            self._add_extra_options_to_node(cfg, n_link)
            n.add(n_link)
            pre_build = cfg["pre-build-commands"]
            if pre_build:
                n_script = Node("PreBuildEvent")
                n_script.add("Command", VSList("\n", pre_build))
                n.add(n_script)
            post_build = cfg["post-build-commands"]
            if post_build:
                n_script = Node("PostBuildEvent")
                n_script.add("Command", VSList("\n", post_build))
                n.add(n_script)
            root.add(n)

        # Source files:
        if cl_files:
            items = Node("ItemGroup")
            root.add(items)
            cl_files_map = bkl.compilers.disambiguate_intermediate_file_names(cl_files)
            for sfile in cl_files:
                if sfile["compile-commands"]:
                    self._add_custom_build_file(items, sfile)
                else:
                    ext = sfile.filename.get_extension()
                    # TODO: share this code with VS200x
                    # FIXME: make this more solid
                    if ext in ['cpp', 'cxx', 'cc', 'c']:
                        n_cl_compile = Node("ClCompile", Include=sfile.filename)
                    else:
                        # FIXME: handle both compilation into cpp and c files
                        genfiletype = bkl.compilers.CxxFileType.get()
                        genname = bkl.expr.PathExpr([bkl.expr.LiteralExpr(sfile.filename.get_basename())],
                                                    bkl.expr.ANCHOR_BUILDDIR,
                                                    pos=sfile.filename.pos).change_extension("cpp")

                        ft_from = bkl.compilers.get_file_type(ext)
                        compiler = bkl.compilers.get_compiler(self, ft_from, genfiletype)

                        customBuild = Node("CustomBuild", Include=sfile.filename)
                        customBuild.add("Command", VSList("\n", compiler.commands(self, target, sfile.filename, genname)))
                        customBuild.add("Outputs", genname)
                        items.add(customBuild)
                        n_cl_compile = Node("ClCompile", Include=genname)
                    # Handle files with custom object name:
                    if sfile in cl_files_map:
                        n_cl_compile.add("ObjectFileName",
                                         concat("$(IntDir)\\", cl_files_map[sfile], ".obj"))
                    self._add_per_file_options(sfile, n_cl_compile)
                    items.add(n_cl_compile)

        # Headers files:
        if target.headers:
            items = Node("ItemGroup")
            root.add(items)
            for sfile in target.headers:
                if sfile["compile-commands"]:
                    self._add_custom_build_file(items, sfile)
                else:
                    items.add("ClInclude", Include=sfile.filename)

        # Resources:
        if rc_files:
            items = Node("ItemGroup")
            root.add(items)
            rc_files_map = bkl.compilers.disambiguate_intermediate_file_names(rc_files)
            for sfile in rc_files:
                n_rc_compile = Node("ResourceCompile", Include=sfile.filename)
                # Handle files with custom object name:
                if sfile in rc_files_map:
                    n_rc_compile.add("ResourceOutputFileName",
                                     concat("$(IntDir)\\", rc_files_map[sfile], ".res"))
                self._add_per_file_options(sfile, n_rc_compile)
                items.add(n_rc_compile)

        # IDL files:
        if idl_files:
            items = Node("ItemGroup")
            root.add(items)
            for sfile in idl_files:
                n_midl = Node("Midl", Include=sfile.filename)
                self._add_per_file_options(sfile, n_midl)
                items.add(n_midl)

        # Dependencies:
        target_deps = self._get_references(target)
        if target_deps:
            refs = Node("ItemGroup")
            root.add(refs)
            for dep in target_deps:
                dep_prj = self.get_project_object(dep)
                depnode = Node("ProjectReference", Include=dep_prj.projectfile)
                depnode.add("Project", "{%s}" % dep_prj.guid.lower())
                refs.add(depnode)

        root.add("Import", Project="$(VCTargetsPath)\\Microsoft.Cpp.targets")
        root.add("ImportGroup", Label="ExtensionTargets")

        filename = project.projectfile.as_native_path_for_output(target)
        paths_info = self.get_project_paths_info(target, project)

        formatter = self.XmlFormatter(target.project.settings, paths_info)
        f = OutputFile(filename, EOL_WINDOWS,
                       creator=self, create_for=target)
        f.write(codecs.BOM_UTF8)
        f.write(formatter.format(root))
        f.commit()
        self._write_filters_file_for(filename, formatter,
                                     target.headers, cl_files, idl_files, rc_files)