--
-- 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,'%s>', 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,'%s>', 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%s>', name, condition, value, name)
else
format = string.format('<%s>%s%s>', name, value, name)
end
_x(depth, format, ...)
end