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
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
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)
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)
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)
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
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()