-- -- vs2010_vcxproj.lua -- Generate a Visual Studio 201x C/C++ project. -- Copyright (c) 2009-2014 Jason Perkins and the Premake project -- premake.vstudio.vc2010 = {} local p = premake local vc2010 = p.vstudio.vc2010 local vstudio = p.vstudio local project = p.project local config = p.config local fileconfig = p.fileconfig local tree = p.tree --- -- Add namespace for element definition lists for premake.callarray() --- vc2010.elements = {} -- -- Generate a Visual Studio 201x C++ project, with support for the new platforms API. -- function vc2010.generate(prj) io.utf8() vc2010.xmlDeclaration() vc2010.project("Build") vc2010.projectConfigurations(prj) vc2010.globals(prj) _p(1,'') for cfg in project.eachconfig(prj) do vc2010.configurationProperties(cfg) end _p(1,'') _p(1,'') _p(1,'') for cfg in project.eachconfig(prj) do vc2010.propertySheets(cfg) end _p(1,'') for cfg in project.eachconfig(prj) do vc2010.outputProperties(cfg) vc2010.nmakeProperties(cfg) end for cfg in project.eachconfig(prj) do vc2010.itemDefinitionGroup(cfg) end vc2010.assemblyReferences(prj) vc2010.files(prj) vc2010.projectReferences(prj) vc2010.import(prj) p.out('') end -- -- Output the XML declaration and opening tag. -- function vc2010.project(target) local defaultTargets = "" if target then defaultTargets = string.format(' DefaultTargets="%s"', target) end _p('', defaultTargets) end -- -- Write out the list of project configurations, which pairs build -- configurations with architectures. -- function vc2010.projectConfigurations(prj) -- build a list of all architectures used in this project local platforms = {} for cfg in project.eachconfig(prj) do local arch = vstudio.archFromConfig(cfg, true) if not table.contains(platforms, arch) then table.insert(platforms, arch) end end local configs = {} _p(1,'') for cfg in project.eachconfig(prj) do for _, arch in ipairs(platforms) do local prjcfg = vstudio.projectConfig(cfg, arch) if not configs[prjcfg] then configs[prjcfg] = prjcfg _x(2,'', vstudio.projectConfig(cfg, arch)) _x(3,'%s', vstudio.projectPlatform(cfg)) _p(3,'%s', arch) _p(2,'') end end end _p(1,'') end -- -- Write out the TargetFrameworkVersion property. -- function vc2010.targetFramework(prj) local framework = prj.framework or "4.0" _p(2,'v%s', framework) end -- -- Write out the Globals property group. -- function vc2010.globals(prj) vc2010.propertyGroup(nil, "Globals") vc2010.projectGuid(prj) -- try to determine what kind of targets we're building here local isWin, isManaged, isMakefile for cfg in project.eachconfig(prj) do if cfg.system == premake.WINDOWS then isWin = true end if cfg.flags.Managed then isManaged = true end if vstudio.isMakefile(cfg) then isMakefile = true end end if isWin then if isMakefile then _p(2,'MakeFileProj') else if isManaged then vc2010.targetFramework(prj) _p(2,'ManagedCProj') else _p(2,'Win32Proj') end _p(2,'%s', prj.name) end end vc2010.projectName(prj) _p(1,'') end -- -- Write out the configuration property group: what kind of binary it -- produces, and some global settings. -- vc2010.elements.configurationProperties = { "configurationType", "useDebugLibraries", "useOfMfc", "clrSupport", "characterSet", "wholeProgramOptimization", "nmakeOutDirs", } function vc2010.configurationProperties(cfg) vc2010.propertyGroup(cfg, "Configuration") premake.callarray(vc2010, vc2010.elements.configurationProperties, cfg) _p(1,'') end -- -- Write out the default property sheets for a configuration. -- function vc2010.propertySheets(cfg) _p(1,'', vc2010.condition(cfg)) _p(2,'') _p(1,'') end -- -- Write the output property group, which includes the output and intermediate -- directories, manifest, etc. -- vc2010.elements.outputProperties = { "propertyGroup", "linkIncremental", "ignoreImportLibrary", "outDir", "outputFile", "intDir", "targetName", "targetExt", "imageXexOutput", "generateManifest", } function vc2010.outputProperties(cfg) if not vstudio.isMakefile(cfg) then premake.callarray(vc2010, vc2010.elements.outputProperties, cfg) _p(1,'') end end -- -- Write the NMake property group for Makefile projects, which includes the custom -- build commands, output file location, etc. -- function vc2010.nmakeProperties(cfg) if vstudio.isMakefile(cfg) then vc2010.propertyGroup(cfg) vc2010.nmakeOutput(cfg) vc2010.nmakeCommandLine(cfg, cfg.buildcommands, "Build") vc2010.nmakeCommandLine(cfg, cfg.rebuildcommands, "ReBuild") vc2010.nmakeCommandLine(cfg, cfg.cleancommands, "Clean") _p(1,'') end end -- -- Write a configuration's item definition group, which contains all -- of the per-configuration compile and link settings. -- vc2010.elements.itemDefinitionGroup = { "clCompile", "resourceCompile", "link", "manifest", "buildEvents", "imageXex", "deploy", } function vc2010.itemDefinitionGroup(cfg) if not vstudio.isMakefile(cfg) then _p(1,'', vc2010.condition(cfg)) premake.callarray(vc2010, vc2010.elements.itemDefinitionGroup, cfg) _p(1,'') else if cfg == project.getfirstconfig(cfg.project) then _p(1,'') _p(1,'') end end end -- -- Write the the compiler settings block. -- vc2010.elements.clCompile = { "precompiledHeader", "warningLevel", "treatWarningAsError", "basicRuntimeChecks", "clCompilePreprocessorDefinitions", "clCompileAdditionalIncludeDirectories", "clCompileAdditionalUsingDirectories", "forceIncludes", "debugInformationFormat", "programDataBaseFileName", "optimization", "functionLevelLinking", "intrinsicFunctions", "minimalRebuild", "omitFramePointers", "stringPooling", "runtimeLibrary", "omitDefaultLib", "exceptionHandling", "runtimeTypeInfo", "bufferSecurityCheck", "treatWChar_tAsBuiltInType", "floatingPointModel", "enableEnhancedInstructionSet", "multiProcessorCompilation", "additionalCompileOptions", "compileAs", } function vc2010.clCompile(cfg) _p(2,'') premake.callarray(vc2010, vc2010.elements.clCompile, cfg) _p(2,'') end -- -- Write out the resource compiler block. -- vc2010.elements.resourceCompile = { "resourcePreprocessorDefinitions", "resourceAdditionalIncludeDirectories", "culture", } function vc2010.resourceCompile(cfg) if cfg.system ~= premake.XBOX360 then _p(2,'') premake.callarray(vc2010, vc2010.elements.resourceCompile, cfg) _p(2,'') end end -- -- Write out the linker tool block. -- vc2010.elements.link = { "subSystem", "generateDebugInformation", "optimizeReferences", "linkDynamic", } vc2010.elements.linkDynamic = { "additionalDependencies", "additionalLibraryDirectories", "importLibrary", "entryPointSymbol", "moduleDefinitionFile", "treatLinkerWarningAsErrors", "additionalLinkOptions", } vc2010.elements.linkStatic = { "treatLinkerWarningAsErrors", "additionalLinkOptions", } function vc2010.link(cfg) _p(2,'') local explicit = vstudio.needsExplicitLink(cfg) premake.callarray(vc2010, vc2010.elements.link, cfg, explicit) _p(2,'') if cfg.kind == premake.STATICLIB then vc2010.linkStatic(cfg, explicit) end vc2010.linkLibraryDependencies(cfg, explicit) end function vc2010.linkDynamic(cfg, explicit) if cfg.kind ~= premake.STATICLIB then premake.callarray(vc2010, vc2010.elements.linkDynamic, cfg, explicit) end end function vc2010.linkStatic(cfg, explicit) local contents = p.capture(function () premake.callarray(vc2010, vc2010.elements.linkStatic, cfg, explicit) end) if #contents > 0 then _p(2,'') _p("%s", contents) _p(2,'') end end -- -- Write the manifest section. -- function vc2010.manifest(cfg) -- no additional manifests in static lib if cfg.kind == premake.STATICLIB then return end -- get the manifests files local manifests = {} for _, fname in ipairs(cfg.files) do if path.getextension(fname) == ".manifest" then table.insert(manifests, project.getrelative(cfg.project, fname)) end end -- when a project is not using manifest files, visual studio doesn't write the section. if #manifests == 0 then return end _p(2,'') vc2010.element(3, "AdditionalManifestFiles", nil, "%s %%(AdditionalManifestFiles)", table.concat(manifests, " ")) _p(2,'') end --- -- Write out the pre- and post-build event settings. --- function vc2010.buildEvents(cfg) local write = function (event) local name = event .. "Event" local field = event:lower() local steps = cfg[field .. "commands"] local msg = cfg[field .. "message"] if #steps > 0 then _p(2,'<%s>', name) _x(3,'%s', table.implode(steps, "", "", "\r\n")) if msg then _x(3,'%s', msg) end _p(2,'', name) end end write("PreBuild") write("PreLink") write("PostBuild") end -- -- Reference any managed assemblies listed in the links() -- function vc2010.assemblyReferences(prj) -- Visual Studio doesn't support per-config references; use -- whatever is contained in the first configuration local cfg = project.getfirstconfig(prj) local refs = config.getlinks(cfg, "system", "fullpath", "managed") if #refs > 0 then _p(1,'') table.foreachi(refs, function(value) -- If the link contains a '/' then it is a relative path to -- a local assembly. Otherwise treat it as a system assembly. if value:find('/', 1, true) then _x(2,'', path.getbasename(value)) _x(3,'%s', path.translate(value)) _p(2,'') else _x(2,'', path.getbasename(value)) end end) _p(1,'') end end -- -- Write out the list of source code files, and any associated configuration. -- function vc2010.files(prj) vc2010.simplefilesgroup(prj, "ClInclude") vc2010.compilerfilesgroup(prj) vc2010.simplefilesgroup(prj, "None") vc2010.simplefilesgroup(prj, "ResourceCompile") vc2010.customBuildFilesGroup(prj) end function vc2010.simplefilesgroup(prj, group) local files = vc2010.getfilegroup(prj, group) if #files > 0 then _p(1,'') for _, file in ipairs(files) do -- Capture the contents of the element, if any, so -- I know which form to use. local contents = p.capture(function () if group == "ResourceCompile" then for cfg in project.eachconfig(prj) do local condition = vc2010.condition(cfg) local filecfg = fileconfig.getconfig(file, cfg) if cfg.system == premake.WINDOWS then vc2010.excludedFromBuild(cfg, filecfg) end end end end) if #contents > 0 then _x(2,'<%s Include=\"%s\">', group, path.translate(file.relpath)) _p("%s", contents) _p(2,'', group) else _x(2,'<%s Include=\"%s\" />', group, path.translate(file.relpath)) end end _p(1,'') end end function vc2010.compilerfilesgroup(prj) local files = vc2010.getfilegroup(prj, "ClCompile") if #files > 0 then _p(1,'') for _, file in ipairs(files) do -- Capture the contents of the element, if any, so -- I know which form to use. local contents = p.capture(function () for cfg in project.eachconfig(prj) do local condition = vc2010.condition(cfg) local filecfg = fileconfig.getconfig(file, cfg) vc2010.excludedFromBuild(cfg, filecfg) if filecfg then vc2010.objectFileName(filecfg) vc2010.clCompilePreprocessorDefinitions(filecfg, condition) vc2010.optimization(filecfg, condition) vc2010.forceIncludes(filecfg, condition) vc2010.precompiledHeader(cfg, filecfg, condition) vc2010.additionalCompileOptions(filecfg, condition) end end end) if #contents > 0 then _x(2,'', path.translate(file.relpath)) _p("%s", contents) _p(2,'') else _x(2,'', path.translate(file.relpath)) end end _p(1,'') end end function vc2010.customBuildFilesGroup(prj) local files = vc2010.getfilegroup(prj, "CustomBuild") if #files > 0 then _p(1,'') for _, file in ipairs(files) do _x(2,'', path.translate(file.relpath)) _p(3,'Document') for cfg in project.eachconfig(prj) do local condition = vc2010.condition(cfg) local filecfg = fileconfig.getconfig(file, cfg) if fileconfig.hasCustomBuildRule(filecfg) then vc2010.excludedFromBuild(cfg, filecfg) local commands = table.concat(filecfg.buildcommands,'\r\n') _p(3,'%s', condition, premake.esc(commands)) local outputs = project.getrelative(prj, filecfg.buildoutputs) vc2010.element(3, "Outputs", condition, '%s', table.concat(outputs, " ")) if filecfg.buildmessage then vc2010.element(3, "Message", condition, '%s', premake.esc(filecfg.buildmessage)) end end end _p(2,'') end _p(1,'') end end function vc2010.getfilegroup(prj, group) -- check for a cached copy before creating local groups = prj.vc2010_file_groups if not groups then groups = { ClCompile = {}, ClInclude = {}, None = {}, ResourceCompile = {}, CustomBuild = {}, } prj.vc2010_file_groups = groups local tr = project.getsourcetree(prj) tree.traverse(tr, { onleaf = function(node) -- if any configuration of this file uses a custom build rule, -- then they all must be marked as custom build local hasbuildrule = false for cfg in project.eachconfig(prj) do local filecfg = fileconfig.getconfig(node, cfg) if fileconfig.hasCustomBuildRule(filecfg) then hasbuildrule = true break end end if hasbuildrule then table.insert(groups.CustomBuild, node) elseif path.iscppfile(node.name) then table.insert(groups.ClCompile, node) elseif path.iscppheader(node.name) then table.insert(groups.ClInclude, node) elseif path.isresourcefile(node.name) then table.insert(groups.ResourceCompile, node) else table.insert(groups.None, node) end end }) end return groups[group] end -- -- Generate the list of project dependencies. -- function vc2010.projectReferences(prj) local deps = project.getdependencies(prj) if #deps > 0 then _p(1,'') for _, dep in ipairs(deps) do local relpath = project.getrelative(prj, vstudio.projectfile(dep)) _x(2,'', path.translate(relpath)) _p(3,'{%s}', dep.uuid) _p(2,'') end _p(1,'') end end --------------------------------------------------------------------------- -- -- Handlers for individual project elements -- --------------------------------------------------------------------------- function vc2010.additionalDependencies(cfg, explicit) local links -- check to see if this project uses an external toolset. If so, let the -- toolset define the format of the links local toolset = premake.vstudio.vc200x.toolset(cfg) if toolset then links = toolset.getlinks(cfg, not explicit) else local scope = iif(explicit, "all", "system") links = config.getlinks(cfg, scope, "fullpath") end if #links > 0 then links = path.translate(table.concat(links, ";")) _x(3,'%s;%%(AdditionalDependencies)', links) end end function vc2010.additionalIncludeDirectories(cfg, includedirs) if #includedirs > 0 then local dirs = project.getrelative(cfg.project, includedirs) dirs = path.translate(table.concat(dirs, ";")) _x(3,'%s;%%(AdditionalIncludeDirectories)', dirs) end end function vc2010.additionalLibraryDirectories(cfg) if #cfg.libdirs > 0 then local dirs = project.getrelative(cfg.project, cfg.libdirs) dirs = path.translate(table.concat(dirs, ";")) _x(3,'%s;%%(AdditionalLibraryDirectories)', dirs) end end function vc2010.additionalUsingDirectories(cfg) if #cfg.usingdirs > 0 then local dirs = project.getrelative(cfg.project, cfg.usingdirs) dirs = path.translate(table.concat(dirs, ";")) _x(3,'%s;%%(AdditionalUsingDirectories)', dirs) end end function vc2010.additionalCompileOptions(cfg, condition) if #cfg.buildoptions > 0 then local opts = table.concat(cfg.buildoptions, " ") vc2010.element(3, "AdditionalOptions", condition, '%s %%(AdditionalOptions)', opts) end end function vc2010.additionalLinkOptions(cfg) if #cfg.linkoptions > 0 then local opts = table.concat(cfg.linkoptions, " ") _x(3, '%s %%(AdditionalOptions)', opts) end end function vc2010.basicRuntimeChecks(cfg) if cfg.flags.NoRuntimeChecks then _p(3,'Default') end end function vc2010.characterSet(cfg) if not vstudio.isMakefile(cfg) then _p(2,'%s', iif(cfg.flags.Unicode, "Unicode", "MultiByte")) end end function vc2010.wholeProgramOptimization(cfg) if cfg.flags.LinkTimeOptimization then _p(2,'true') end end function vc2010.clCompileAdditionalIncludeDirectories(cfg) vc2010.additionalIncludeDirectories(cfg, cfg.includedirs) end function vc2010.clCompileAdditionalUsingDirectories(cfg) vc2010.additionalUsingDirectories(cfg, cfg.usingdirs) end function vc2010.clCompilePreprocessorDefinitions(cfg, condition) vc2010.preprocessorDefinitions(cfg, cfg.defines, false, condition) end function vc2010.clrSupport(cfg) if cfg.flags.Managed then _p(2,'true') end end function vc2010.compileAs(cfg) if cfg.project.language == "C" then _p(3,'CompileAsC') end end function vc2010.configurationType(cfg) local types = { SharedLib = "DynamicLibrary", StaticLib = "StaticLibrary", ConsoleApp = "Application", WindowedApp = "Application", Makefile = "Makefile", None = "Makefile", } _p(2,'%s', types[cfg.kind]) end function vc2010.culture(cfg) local value = vstudio.cultureForLocale(cfg.locale) if value then _p(3,'0x%04x', value) end end function vc2010.debugInformationFormat(cfg) local value if cfg.flags.Symbols then if cfg.debugformat == "c7" then value = "OldStyle" elseif cfg.architecture == "x64" or cfg.flags.Managed or config.isOptimizedBuild(cfg) or cfg.flags.NoEditAndContinue then value = "ProgramDatabase" else value = "EditAndContinue" end end if value then _p(3,'%s', value) end end function vc2010.deploy(cfg) if cfg.system == premake.XBOX360 then _p(2,'') _p(3,'CopyToHardDrive') _p(3,'ZeroSeekTimes') _p(3,'$(RemoteRoot)=$(ImagePath);') _p(2,'') end end function vc2010.enableEnhancedInstructionSet(cfg) local map = { SSE = "StreamingSIMDExtensions", SSE2 = "StreamingSIMDExtensions2" } local value = map[cfg.vectorextensions] if value then _p(3,'%s', value) end end function vc2010.entryPointSymbol(cfg) if (cfg.kind == premake.CONSOLEAPP or cfg.kind == premake.WINDOWEDAPP) and not cfg.flags.WinMain and not cfg.flags.Managed and cfg.system ~= premake.XBOX360 then _p(3,'mainCRTStartup') end end function vc2010.exceptionHandling(cfg) if cfg.flags.NoExceptions then _p(3,'false') elseif cfg.flags.SEH then _p(3,'Async') end end function vc2010.excludedFromBuild(cfg, filecfg) if not filecfg or filecfg.flags.ExcludeFromBuild then _p(3,'true', vc2010.condition(cfg)) end end function vc2010.floatingPointModel(cfg) if cfg.floatingpoint then _p(3,'%s', cfg.floatingpoint) end end function vc2010.forceIncludes(cfg, condition) if #cfg.forceincludes > 0 then local includes = path.translate(project.getrelative(cfg.project, cfg.forceincludes)) vc2010.element(3, "ForcedIncludeFiles", condition, table.concat(includes, ';')) end if #cfg.forceusings > 0 then local usings = path.translate(project.getrelative(cfg.project, cfg.forceusings)) _x(3,'%s', table.concat(usings, ';')) end end function vc2010.functionLevelLinking(cfg) if config.isOptimizedBuild(cfg) then _p(3,'true') end end function vc2010.generateDebugInformation(cfg) _p(3,'%s', tostring(cfg.flags.Symbols ~= nil)) end function vc2010.generateManifest(cfg) if cfg.flags.NoManifest then _p(2,'false') end end function vc2010.ignoreImportLibrary(cfg) if cfg.kind == premake.SHAREDLIB and cfg.flags.NoImportLib then _p(2,'true'); end end function vc2010.imageXex(cfg) if cfg.system == premake.XBOX360 then _p(2,'') _p(3,'') _p(3,'') _p(3,'') _p(3,'') _p(2,'') end end function vc2010.imageXexOutput(cfg) if cfg.system == premake.XBOX360 then _x(2,'$(OutDir)$(TargetName).xex') end end function vc2010.import(prj) _p(1,'') _p(1,'') _p(1,'') end function vc2010.importLibrary(cfg) if cfg.kind == premake.SHAREDLIB then _x(3,'%s', path.translate(cfg.linktarget.relpath)) end end function vc2010.intDir(cfg) local objdir = project.getrelative(cfg.project, cfg.objdir) _x(2,'%s\\', path.translate(objdir)) end function vc2010.intrinsicFunctions(cfg) if config.isOptimizedBuild(cfg) then _p(3,'true') end end function vc2010.linkIncremental(cfg) if cfg.kind ~= premake.STATICLIB then _p(2,'%s', tostring(config.canLinkIncremental(cfg))) end end function vc2010.linkLibraryDependencies(cfg, explicit) -- Left to its own devices, VS will happily link against a project dependency -- that has been excluded from the build. As a workaround, disable dependency -- linking and list all siblings explicitly if explicit then _p(2,'') _p(3,'false') _p(2,'') end end function vc2010.minimalRebuild(cfg) if config.isOptimizedBuild(cfg) or cfg.flags.NoMinimalRebuild or cfg.flags.MultiProcessorCompile or cfg.debugformat == premake.C7 then _p(3,'false') end end function vc2010.moduleDefinitionFile(cfg) local df = config.findfile(cfg, ".def") if df then _p(3,'%s', df) end end function vc2010.multiProcessorCompilation(cfg) if cfg.flags.MultiProcessorCompile then _p(3,'true') end end function vc2010.nmakeCommandLine(cfg, commands, phase) if #commands > 0 then commands = table.concat(premake.esc(commands), p.eol()) _p(2, '%s', phase, commands, phase) end end function vc2010.nmakeOutDirs(cfg) if vstudio.isMakefile(cfg) then vc2010.outDir(cfg) vc2010.intDir(cfg) end end function vc2010.nmakeOutput(cfg) _p(2,'$(OutDir)%s', cfg.buildtarget.name) end function vc2010.objectFileName(filecfg) if filecfg.objname ~= filecfg.basename then _p(3,'$(IntDir)\\%s.obj', vc2010.condition(filecfg.config), filecfg.objname) end end function vc2010.omitFramePointers(cfg) if cfg.flags.NoFramePointer then _p(3,'true') end end function vc2010.optimizeReferences(cfg) if config.isOptimizedBuild(cfg) then _p(3,'true') _p(3,'true') end end function vc2010.optimization(cfg, condition) local map = { Off="Disabled", On="Full", Debug="Disabled", Full="Full", Size="MinSpace", Speed="MaxSpeed" } local value = map[cfg.optimize] if value or not condition then vc2010.element(3, 'Optimization', condition, value or "Disabled") end end function vc2010.outDir(cfg) local outdir = project.getrelative(cfg.project, cfg.buildtarget.directory) _x(2,'%s\\', path.translate(outdir)) end function vc2010.outputFile(cfg) if cfg.system == premake.XBOX360 then _p(2,'$(OutDir)%s', cfg.buildtarget.name) end end function vc2010.precompiledHeader(cfg, filecfg, condition) if filecfg then if cfg.pchsource == filecfg.abspath and not cfg.flags.NoPCH then vc2010.element(3, 'PrecompiledHeader', condition, 'Create') elseif filecfg.flags.NoPCH then vc2010.element(3, 'PrecompiledHeader', condition, 'NotUsing') end else if not cfg.flags.NoPCH and cfg.pchheader then _p(3,'Use') _x(3,'%s', cfg.pchheader) else _p(3,'NotUsing') end end end function vc2010.preprocessorDefinitions(cfg, defines, escapeQuotes, condition) if #defines > 0 then defines = table.concat(defines, ";") if escapeQuotes then defines = defines:gsub('"', '\\"') end defines = premake.esc(defines) .. ";%%(PreprocessorDefinitions)" vc2010.element(3, 'PreprocessorDefinitions', condition, defines) end end function vc2010.programDataBaseFileName(cfg) if cfg.flags.Symbols and cfg.debugformat ~= "c7" then local filename = cfg.buildtarget.basename _p(3,'$(OutDir)%s.pdb', filename) end end function vc2010.projectGuid(prj) _p(2,'{%s}', prj.uuid) end function vc2010.projectName(prj) if prj.name ~= prj.filename then _x(2,'%s', prj.name) end end function vc2010.propertyGroup(cfg, label) local cond if cfg then cond = string.format(' %s', vc2010.condition(cfg)) end if label then label = string.format(' Label="%s"', label) end _p(1,'', cond or "", label or "") end function vc2010.resourceAdditionalIncludeDirectories(cfg) vc2010.additionalIncludeDirectories(cfg, table.join(cfg.includedirs, cfg.resincludedirs)) end function vc2010.resourcePreprocessorDefinitions(cfg) vc2010.preprocessorDefinitions(cfg, table.join(cfg.defines, cfg.resdefines), true) end function vc2010.runtimeLibrary(cfg) local runtimes = { StaticDebug = "MultiThreadedDebug", StaticRelease = "MultiThreaded", } local runtime = runtimes[config.getruntime(cfg)] if runtime then _p(3,'%s', runtime) end end function vc2010.omitDefaultLib(cfg) if cfg.flags.OmitDefaultLibrary then _p(3,'true') end end function vc2010.runtimeTypeInfo(cfg) if cfg.flags.NoRTTI and not cfg.flags.Managed then _p(3,'false') end end function vc2010.bufferSecurityCheck(cfg) if cfg.flags.NoBufferSecurityCheck then _p(3,'false') end end function vc2010.stringPooling(cfg) if config.isOptimizedBuild(cfg) then _p(3,'true') end end function vc2010.subSystem(cfg) if cfg.system ~= premake.XBOX360 then local subsystem = iif(cfg.kind == premake.CONSOLEAPP, "Console", "Windows") _p(3,'%s', subsystem) end end function vc2010.targetExt(cfg) local ext = cfg.buildtarget.extension if ext ~= "" then _x(2,'%s', ext) else _p(2,'') _p(2,'') end end function vc2010.targetName(cfg) _x(2,'%s%s', cfg.buildtarget.prefix, cfg.buildtarget.basename) end function vc2010.treatLinkerWarningAsErrors(cfg) if cfg.flags.FatalLinkWarnings then local el = iif(cfg.kind == premake.STATICLIB, "Lib", "Linker") _p(3,'true', el, el) end end function vc2010.treatWChar_tAsBuiltInType(cfg) local map = { On = "true", Off = "false" } local value = map[cfg.nativewchar] if value then _p(3,'%s', value) end end function vc2010.treatWarningAsError(cfg) if cfg.flags.FatalLinkWarnings and cfg.warnings ~= "Off" then _p(3,'true') end end function vc2010.useDebugLibraries(cfg) local runtime = config.getruntime(cfg) _p(2,'%s', tostring(runtime:endswith("Debug"))) end function vc2010.useOfMfc(cfg) if cfg.flags.MFC then _p(2,'%s', iif(cfg.flags.StaticRuntime, "Static", "Dynamic")) end end function vc2010.warningLevel(cfg) local map = { Off = "TurnOffAllWarnings", Extra = "Level4" } vc2010.element(3, "WarningLevel", nil, "%s", map[cfg.warnings] or "Level3") end function vc2010.xmlDeclaration() _p('') end --------------------------------------------------------------------------- -- -- Support functions -- --------------------------------------------------------------------------- -- -- Format and return a Visual Studio Condition attribute. -- function vc2010.condition(cfg) return string.format('Condition="\'$(Configuration)|$(Platform)\'==\'%s\'"', premake.esc(vstudio.projectConfig(cfg))) end -- -- Output an individual project XML element, with an optional configuration -- condition. -- -- @param depth -- How much to indent the element. -- @param name -- The element name. -- @param condition -- An optional configuration condition, formatted with vc2010.condition(). -- @param value -- The element value, which may contain printf formatting tokens. -- @param ... -- Optional additional arguments to satisfy any tokens in the value. -- function vc2010.element(depth, name, condition, value, ...) if select('#',...) == 0 then value = premake.esc(value) end local format if condition then format = string.format('<%s %s>%s', name, condition, value, name) else format = string.format('<%s>%s', name, value, name) end _x(depth, format, ...) end