Ejemplo n.º 1
0
    def VCLinkerTool(self, target, cfg):
        if is_library(target):
            return None
        n = Node("Tool", Name="VCLinkerTool")
        if is_module_dll(target):
            n["IgnoreImportLibrary"] = True
        n["AdditionalOptions"] = VSList(" ", target.type.get_link_options(cfg))
        libs = target.type.get_ldlibs(cfg)
        if libs:
            n["AdditionalDependencies"] = VSList(" ", ("%s.lib" % x.as_py() for x in libs if x))

        n["AdditionalLibraryDirectories"] = target.type.get_libdirs(cfg)

        targetname = cfg["basename"]
        if targetname != target.name or not target.is_variable_null("extension"):
            n["OutputFile"] = concat("$(OutDir)\\", targetname, target.type.target_file_extension(self, target))

        if cfg.is_debug:
            n["LinkIncremental"] = linkIncrementalYes
        else:
            n["LinkIncremental"] = linkIncrementalNo
        # VS: creates debug info for release too; TODO: make this configurable
        n["GenerateDebugInformation"] = True
        if is_program(target) and cfg["win32-subsystem"] == "console":
            n["SubSystem"] = subSystemConsole
        else:
            n["SubSystem"] = subSystemWindows
        if not cfg.is_debug:
            n["OptimizeReferences"] = optReferences
            n["EnableCOMDATFolding"] = optFolding
        if cfg.vs_platform == "x64":
            n["TargetMachine"] = machineAMD64
        else:
            n["TargetMachine"] = machineX86
        return n
Ejemplo n.º 2
0
 def VCLibrarianTool(self, target, cfg):
     if not is_library(target):
         return None
     n = Node("Tool", Name="VCLibrarianTool")
     targetname = cfg["basename"]
     if targetname != target.name or not target.is_variable_null("extension"):
         n["OutputFile"] = concat("$(OutDir)\\", targetname, target.type.target_file_extension(self, target))
     return n
Ejemplo n.º 3
0
 def _get_filename(self, toolset, target, propname, fileclass):
     """
     Returns expression with filename of the target using given property
     (typically, "basename") for use with given toolset.
     """
     fileclass = fileclass.replace("-", "_")
     tdir = dir(toolset)
     prefix = "%s_prefix" % fileclass
     ext = "%s_extension" % fileclass
     parts = []
     if prefix in tdir:
         parts.append(getattr(toolset, prefix))
     parts.append(target[propname])
     if not target.is_variable_null("extension"):
         parts.append(target["extension"])
     elif ext in tdir:
         parts.append("." + getattr(toolset, ext))
     outdir = target["outputdir"]
     return PathExpr(outdir.components + [concat(*parts)], outdir.anchor, outdir.anchor_file)
Ejemplo n.º 4
0
 def _get_filename(self, toolset, target, propname, fileclass):
     """
     Returns expression with filename of the target using given property
     (typically, "basename") for use with given toolset.
     """
     fileclass = fileclass.replace("-", "_")
     tdir = dir(toolset)
     prefix = "%s_prefix" % fileclass
     ext = "%s_extension" % fileclass
     parts = []
     if prefix in tdir:
         parts.append(getattr(toolset, prefix))
     parts.append(target[propname])
     if not target.is_variable_null("extension"):
         parts.append(target["extension"])
     elif ext in tdir:
         parts.append("." + getattr(toolset, ext))
     outdir = target["outputdir"]
     return PathExpr(outdir.components + [concat(*parts)], outdir.anchor,
                     outdir.anchor_file)
Ejemplo n.º 5
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)
Ejemplo n.º 6
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)
Ejemplo n.º 7
0
    def build_files_list(self, target):
        files = Node("Files")
        # TODO: use groups definition, filter into groups, add Resource Files

        sources = Node("Filter", Name="Source Files")
        sources["Filter"] = "cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
        sources["UniqueIdentifier"] = "{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

        headers = Node("Filter", Name="Header Files")
        headers["Filter"] = "h;hpp;hxx;hm;inl;inc;xsd"
        headers["UniqueIdentifier"] = "{93995380-89BD-4b04-88EB-625FBE52EBFB}"

        resources = Node("Filter", Name="Resource Files")
        resources["Filter"] = "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
        resources["UniqueIdentifier"] = "{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

        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)
        cl_files_map = disambiguate_intermediate_file_names(cl_files)
        rc_files_map = disambiguate_intermediate_file_names(rc_files)

        for sfile in target.sources:
            if sfile["compile-commands"]:
                self._add_custom_build_file(sources, sfile)
            else:
                ext = sfile.filename.get_extension()
                # TODO: share this code with VS2010
                # FIXME: make this more solid
                if ext in ['cpp', 'cxx', 'cc', 'c', 'rc', 'idl']:
                    n_file = Node("File", RelativePath=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)

                    n_file = Node("File", RelativePath=sfile.filename)
                    sources.add(n_file)
                    for cfg in self.configs_and_platforms(target):
                        n_cfg = Node("FileConfiguration", Name="%s" % cfg.vs_name)
                        tool = Node("Tool", Name="VCCustomBuildTool")
                        tool["CommandLine"] = VSList("\r\n", compiler.commands(self, target, sfile.filename, genname))
                        tool["Outputs"] = genname
                        n_cfg.add(tool)
                        n_file.add(n_cfg)
                    n_file = Node("File", RelativePath=genname)

                if ext == 'rc':
                    extras = None
                    if sfile in rc_files_map:
                        objfile = concat("$(IntDir)\\", rc_files_map[sfile], ".res")
                        extras = [("ResourceOutputFileName", objfile)]
                    self._add_per_file_options(sfile, n_file, "VCResourceCompilerTool", extras)
                    resources.add(n_file)
                else:
                    if ext == 'idl':
                        self._add_per_file_options(sfile, n_file, "VCMIDLTool", None)
                    else:
                        extras = None
                        if sfile in cl_files_map:
                            objfile = concat("$(IntDir)\\", cl_files_map[sfile], ".obj")
                            extras = [("ObjectFile", objfile)]
                        self._add_per_file_options(sfile, n_file, "VCCLCompilerTool", extras)
                    sources.add(n_file)

        for sfile in target.headers:
            if sfile["compile-commands"]:
                self._add_custom_build_file(headers, sfile)
            else:
                headers.add("File", RelativePath=sfile.filename)

        files.add(sources)
        files.add(headers)
        files.add(resources)
        return files
Ejemplo n.º 8
0
    def gen_for_target(self, target, project):
        root = Node("VisualStudioProject")
        root["ProjectType"] = "Visual C++"
        root["Version"] = "%.2f" % self.version
        root["Name"] =  target.name
        root["ProjectGUID"] = "{%s}" % project.guid
        root["RootNamespace"] = target.name
        root["Keyword"] = "Win32Proj"
        self._add_extra_options_to_node(target, root)

        n_platforms = Node("Platforms")
        for p in self.get_platforms(target):
            n_platforms.add("Platform", Name=p)
        root.add(n_platforms)

        self._add_ToolFiles(root)

        n_configs = Node("Configurations")
        root.add(n_configs)
        for cfg in self.configs_and_platforms(target):
            n = Node("Configuration", Name="%s" % cfg.vs_name)
            n_configs.add(n)
            platform_str = "$(PlatformName)\\" if cfg.vs_platform != "Win32" else ""
            if target.is_variable_explicitly_set("outputdir"):
                n["OutputDirectory"] = concat(cfg["outputdir"], "\\")
            else:
                n["OutputDirectory"] = "$(SolutionDir)%s$(ConfigurationName)" % platform_str
            if self.needs_custom_intermediate_dir(target):
                n["IntermediateDirectory"] = "%s$(ConfigurationName)\\$(ProjectName)\\" % platform_str
            else:
                n["IntermediateDirectory"] = "%s$(ConfigurationName)" % platform_str
            if is_program(target):
                n["ConfigurationType"] = typeApplication
            elif is_library(target):
                n["ConfigurationType"] = typeStaticLibrary
            elif is_dll(target):
                n["ConfigurationType"] = typeDynamicLibrary
            else:
                assert False, "this code should only be called for supported target types"
            if cfg["win32-unicode"]:
                n["CharacterSet"] = 1
            self._add_extra_options_to_node(cfg, n)

            for tool in self.tool_functions:
                if hasattr(self, tool):
                    f_tool = getattr(self, tool)
                    n_tool = f_tool(target, cfg)
                else:
                    n_tool = Node("Tool", Name=tool)
                if n_tool:
                    self._add_extra_options_to_node(cfg, n_tool)
                    n.add(n_tool)

        root.add(Node("References"))

        root.add(self.build_files_list(target))

        root.add(Node("Globals"))

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

        f = OutputFile(filename, EOL_WINDOWS, charset=VCPROJ_CHARSET,
                       creator=self, create_for=target)
        f.write(self.XmlFormatter(target.project.settings, paths_info).format(root))
        f.commit()