Merge work-in-progress rules support, configuration container API
This commit is contained in:
commit
352b5ba4ca
@ -20,18 +20,13 @@
|
||||
"base/globals.lua",
|
||||
|
||||
-- configuration data
|
||||
"base/container.lua",
|
||||
"base/field.lua",
|
||||
"base/criteria.lua",
|
||||
"base/detoken.lua",
|
||||
"base/configset.lua",
|
||||
"base/context.lua",
|
||||
|
||||
-- project objects
|
||||
"base/project.lua",
|
||||
"base/solution.lua",
|
||||
"base/config.lua",
|
||||
"base/fileconfig.lua",
|
||||
|
||||
-- runtime switches
|
||||
"base/option.lua",
|
||||
"base/action.lua",
|
||||
@ -39,6 +34,13 @@
|
||||
-- project script setup
|
||||
"base/api.lua",
|
||||
|
||||
-- project objects
|
||||
"base/solution.lua",
|
||||
"base/project.lua",
|
||||
"base/config.lua",
|
||||
"base/fileconfig.lua",
|
||||
"base/rules.lua",
|
||||
|
||||
-- project script processing
|
||||
"base/oven.lua",
|
||||
"base/premake.lua",
|
||||
@ -70,6 +72,9 @@
|
||||
"actions/vstudio/vs2010_vcxproj.lua",
|
||||
"actions/vstudio/vs2010_vcxproj_user.lua",
|
||||
"actions/vstudio/vs2010_vcxproj_filters.lua",
|
||||
"actions/vstudio/vs2010_rules_props.lua",
|
||||
"actions/vstudio/vs2010_rules_targets.lua",
|
||||
"actions/vstudio/vs2010_rules_xml.lua",
|
||||
"actions/vstudio/vs2012.lua",
|
||||
"actions/vstudio/vs2013.lua",
|
||||
|
||||
|
@ -62,20 +62,35 @@
|
||||
},
|
||||
}
|
||||
|
||||
api.register {
|
||||
name = "buildmessage",
|
||||
scope = "config",
|
||||
kind = "string",
|
||||
tokens = true,
|
||||
}
|
||||
|
||||
api.register {
|
||||
name = "buildcommands",
|
||||
scope = "config",
|
||||
scope = { "config", "rule" },
|
||||
kind = "list:string",
|
||||
tokens = true,
|
||||
}
|
||||
|
||||
api.alias("buildcommands", "buildCommands")
|
||||
|
||||
|
||||
api.register {
|
||||
name = "buildDependencies",
|
||||
scope = { "rule" },
|
||||
kind = "list:string",
|
||||
tokens = true,
|
||||
}
|
||||
|
||||
|
||||
api.register {
|
||||
name = "buildmessage",
|
||||
scope = { "config", "rule" },
|
||||
kind = "string",
|
||||
tokens = true
|
||||
}
|
||||
|
||||
api.alias("buildmessage", "buildMessage")
|
||||
|
||||
|
||||
api.register {
|
||||
name = "buildoptions",
|
||||
scope = "config",
|
||||
@ -83,13 +98,17 @@
|
||||
tokens = true,
|
||||
}
|
||||
|
||||
|
||||
api.register {
|
||||
name = "buildoutputs",
|
||||
scope = "config",
|
||||
scope = { "config", "rule" },
|
||||
kind = "list:path",
|
||||
tokens = true,
|
||||
}
|
||||
|
||||
api.alias("buildoutputs", "buildOutputs")
|
||||
|
||||
|
||||
api.register {
|
||||
name = "buildinputs",
|
||||
scope = "config",
|
||||
@ -214,14 +233,30 @@
|
||||
tokens = true,
|
||||
}
|
||||
|
||||
|
||||
api.register {
|
||||
name = "display",
|
||||
scope = "rule",
|
||||
kind = "string",
|
||||
}
|
||||
|
||||
|
||||
-- For backward compatibility, excludes() is now an alias for removefiles()
|
||||
function excludes(value)
|
||||
removefiles(value)
|
||||
end
|
||||
|
||||
|
||||
api.register {
|
||||
name = "fileExtension",
|
||||
scope = "rule",
|
||||
kind = "string",
|
||||
}
|
||||
|
||||
|
||||
api.register {
|
||||
name = "filename",
|
||||
scope = "project",
|
||||
scope = { "project", "rule" },
|
||||
kind = "string",
|
||||
tokens = true,
|
||||
}
|
||||
@ -442,7 +477,7 @@
|
||||
|
||||
api.register {
|
||||
name = "location",
|
||||
scope = "project",
|
||||
scope = { "project", "rule" },
|
||||
kind = "path",
|
||||
tokens = true,
|
||||
}
|
||||
@ -555,6 +590,12 @@
|
||||
tokens = true,
|
||||
}
|
||||
|
||||
api.register {
|
||||
name = "propertyDefinition",
|
||||
scope = "rule",
|
||||
kind = "list:table",
|
||||
}
|
||||
|
||||
api.register {
|
||||
name = "rebuildcommands",
|
||||
scope = "config",
|
||||
|
@ -184,7 +184,7 @@
|
||||
function make.csResponseRules(prj)
|
||||
local toolset = premake.tools.dotnet
|
||||
local ext = make.getmakefilename(prj, true)
|
||||
local makefile = path.getname(premake.project.getfilename(prj, ext))
|
||||
local makefile = path.getname(premake.filename(prj, ext))
|
||||
local response = path.translate(make.cs.getresponsefilename(prj))
|
||||
|
||||
_p('$(RESPONSE): %s', makefile)
|
||||
|
@ -58,7 +58,7 @@
|
||||
function make.cleanrules(sln)
|
||||
_p('clean:')
|
||||
for prj in solution.eachproject(sln) do
|
||||
local prjpath = project.getfilename(prj, make.getmakefilename(prj, true))
|
||||
local prjpath = premake.filename(prj, make.getmakefilename(prj, true))
|
||||
local prjdir = path.getdirectory(path.getrelative(sln.location, prjpath))
|
||||
local prjname = path.getname(prjpath)
|
||||
_x(1,'@${MAKE} --no-print-directory -C %s -f %s clean', prjdir, prjname)
|
||||
@ -174,7 +174,7 @@
|
||||
|
||||
_p(1,'@echo "==== Building %s ($(%s_config)) ===="', prj.name, cfgvar)
|
||||
|
||||
local prjpath = project.getfilename(prj, make.getmakefilename(prj, true))
|
||||
local prjpath = premake.filename(prj, make.getmakefilename(prj, true))
|
||||
local prjdir = path.getdirectory(path.getrelative(sln.location, prjpath))
|
||||
local prjname = path.getname(prjpath)
|
||||
|
||||
|
@ -6,9 +6,11 @@
|
||||
|
||||
premake.vstudio = {}
|
||||
local vstudio = premake.vstudio
|
||||
local solution = premake.solution
|
||||
local project = premake.project
|
||||
local config = premake.config
|
||||
|
||||
local p = premake
|
||||
local solution = p.solution
|
||||
local project = p.project
|
||||
local config = p.config
|
||||
|
||||
|
||||
--
|
||||
@ -368,6 +370,16 @@
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Generates a Visual Studio project element for the current action.
|
||||
---
|
||||
|
||||
function vstudio.projectElement()
|
||||
p.push('<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">')
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Returns the full, absolute path to the Visual Studio project file
|
||||
-- corresponding to a particular project object.
|
||||
@ -386,7 +398,7 @@
|
||||
extension = iif(_ACTION > "vs2008", ".vcxproj", ".vcproj")
|
||||
end
|
||||
|
||||
return project.getfilename(prj, extension)
|
||||
return premake.filename(prj, extension)
|
||||
end
|
||||
|
||||
|
||||
@ -563,3 +575,4 @@
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -467,7 +467,7 @@
|
||||
|
||||
function cs2005.xmlDeclaration()
|
||||
if _ACTION > "vs2008" then
|
||||
_p('<?xml version="1.0" encoding="utf-8"?>')
|
||||
p.xmlUtf8()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
--
|
||||
|
||||
function cs2005.generate_user(prj)
|
||||
_p('<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">')
|
||||
p.vstudio.projectElement()
|
||||
_p(1,'<PropertyGroup>')
|
||||
|
||||
-- Per-configuration reference paths aren't supported (are they?) so just
|
||||
|
@ -39,6 +39,22 @@
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Generate the .props, .targets, and .xml files for custom rules.
|
||||
---
|
||||
|
||||
function vs2010.generateRule(rule)
|
||||
p.eol("\r\n")
|
||||
p.indent(" ")
|
||||
p.escaper(vs2010.esc)
|
||||
|
||||
p.generate(rule, ".props", vs2010.rules.props.generate)
|
||||
p.generate(rule, ".targets", vs2010.rules.targets.generate)
|
||||
p.generate(rule, ".xml", vs2010.rules.xml.generate)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- The VS 2010 standard for XML escaping in generated project files.
|
||||
--
|
||||
@ -80,6 +96,7 @@
|
||||
|
||||
onsolution = vstudio.vs2005.generateSolution,
|
||||
onproject = vstudio.vs2010.generateProject,
|
||||
onrule = vstudio.vs2010.generateRule,
|
||||
|
||||
oncleansolution = vstudio.cleanSolution,
|
||||
oncleanproject = vstudio.cleanProject,
|
||||
|
176
src/actions/vstudio/vs2010_rules_props.lua
Normal file
176
src/actions/vstudio/vs2010_rules_props.lua
Normal file
@ -0,0 +1,176 @@
|
||||
---
|
||||
-- vs2010_rules_props.lua
|
||||
-- Generate a Visual Studio 201x custom rules properties file.
|
||||
-- Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
|
||||
premake.vstudio.vs2010.rules = {}
|
||||
premake.vstudio.vs2010.rules.props = {}
|
||||
|
||||
local m = premake.vstudio.vs2010.rules.props
|
||||
m.elements = {}
|
||||
|
||||
local p = premake
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Entry point; generate the root <Project> element.
|
||||
---
|
||||
|
||||
m.elements.project = function(r)
|
||||
return {
|
||||
p.xmlUtf8,
|
||||
p.vstudio.projectElement,
|
||||
m.targetsGroup,
|
||||
m.dependsOnGroup,
|
||||
m.ruleGroup,
|
||||
}
|
||||
end
|
||||
|
||||
function m.generate(r)
|
||||
p.callArray(m.elements.project, r)
|
||||
p.pop()
|
||||
p.out('</Project>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Generate the targets property group element.
|
||||
---
|
||||
|
||||
m.elements.targetsGroup = function(r)
|
||||
return {
|
||||
m.beforeTargets,
|
||||
m.afterTargets,
|
||||
}
|
||||
end
|
||||
|
||||
function m.targetsGroup(r)
|
||||
p.w('<PropertyGroup')
|
||||
p.push(' Condition="\'$(%sBeforeTargets)\' == \'\' and \'$(%sAfterTargets)\' == \'\' and \'$(ConfigurationType)\' != \'Makefile\'">',
|
||||
r.name, r.name)
|
||||
p.callArray(m.elements.targetsGroup, r)
|
||||
p.pop('</PropertyGroup>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Generate the dependencies property group element.
|
||||
---
|
||||
|
||||
m.elements.dependsOnGroup = function(r)
|
||||
return {
|
||||
m.dependsOn,
|
||||
}
|
||||
end
|
||||
|
||||
function m.dependsOnGroup(r)
|
||||
p.push('<PropertyGroup>')
|
||||
p.callArray(m.elements.dependsOnGroup, r)
|
||||
p.pop('</PropertyGroup>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Generate the rule itemm group element.
|
||||
---
|
||||
|
||||
m.elements.ruleGroup = function(r)
|
||||
return {
|
||||
m.propertyDefaults,
|
||||
m.commandLineTemplates,
|
||||
m.outputs,
|
||||
m.executionDescription,
|
||||
m.additionalDependencies,
|
||||
}
|
||||
end
|
||||
|
||||
function m.ruleGroup(r)
|
||||
p.push('<ItemDefinitionGroup>')
|
||||
p.push('<%s>', r.name)
|
||||
p.callArray(m.elements.ruleGroup, r)
|
||||
p.pop('</%s>', r.name)
|
||||
p.pop('</ItemDefinitionGroup>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Output the default values for all of the property definitions.
|
||||
---
|
||||
|
||||
function m.propertyDefaults(r)
|
||||
local defs = r.propertyDefinition
|
||||
for i = 1, #defs do
|
||||
local def = defs[i]
|
||||
local value = def.value
|
||||
if value then
|
||||
if def.kind == "path" then
|
||||
value = path.translate(value)
|
||||
end
|
||||
p.w('<%s>%s</%s>', def.name, value, def.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Implementations of individual elements.
|
||||
---
|
||||
|
||||
function m.additionalDependencies(r)
|
||||
local deps = table.concat(r.buildDependencies, ";")
|
||||
p.x('<AdditionalDependencies>%s</AdditionalDependencies>', deps)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.afterTargets(r)
|
||||
p.w('<%sAfterTargets>CustomBuild</%sAfterTargets>', r.name, r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.beforeTargets(r)
|
||||
p.w('<%sBeforeTargets>Midl</%sBeforeTargets>', r.name, r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.commandLineTemplates(r)
|
||||
if #r.buildcommands then
|
||||
local cmds = table.concat(r.buildcommands, p.eol())
|
||||
p.x('<CommandLineTemplate>%s</CommandLineTemplate>', cmds)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.dependsOn(r)
|
||||
p.w('<%sDependsOn', r.name)
|
||||
p.w(' Condition="\'$(ConfigurationType)\' != \'Makefile\'">_SelectedFiles;$(%sDependsOn)</%sDependsOn>',
|
||||
r.name, r.name, r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.executionDescription(r)
|
||||
if r.buildmessage then
|
||||
p.x('<ExecutionDescription>%s</ExecutionDescription>', r.buildmessage)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.outputs(r)
|
||||
if #r.buildoutputs then
|
||||
local outputs = table.concat(r.buildoutputs, ";")
|
||||
p.x('<Outputs>%s</Outputs>', path.translate(outputs))
|
||||
end
|
||||
end
|
443
src/actions/vstudio/vs2010_rules_targets.lua
Normal file
443
src/actions/vstudio/vs2010_rules_targets.lua
Normal file
@ -0,0 +1,443 @@
|
||||
---
|
||||
-- vs2010_rules_targets.lua
|
||||
-- Generate a Visual Studio 201x custom rules targets file.
|
||||
-- Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
premake.vstudio.vs2010.rules.targets = {}
|
||||
|
||||
local m = premake.vstudio.vs2010.rules.targets
|
||||
m.elements = {}
|
||||
|
||||
local p = premake
|
||||
|
||||
|
||||
---
|
||||
-- Entry point; generate the root <Project> element.
|
||||
---
|
||||
|
||||
m.elements.project = function(r)
|
||||
return {
|
||||
p.xmlUtf8,
|
||||
p.vstudio.projectElement,
|
||||
m.availableItemGroup,
|
||||
m.computeInputsGroup,
|
||||
m.usingTask,
|
||||
m.ruleTarget,
|
||||
m.computeOutputTarget,
|
||||
}
|
||||
end
|
||||
|
||||
function m.generate(r)
|
||||
p.callArray(m.elements.project, r)
|
||||
p.pop()
|
||||
p.out('</Project>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Generate the opening item group element.
|
||||
---
|
||||
|
||||
m.elements.availableItemGroup = function(r)
|
||||
return {
|
||||
m.propertyPageSchema,
|
||||
m.availableItemName,
|
||||
}
|
||||
end
|
||||
|
||||
function m.availableItemGroup(r)
|
||||
p.push('<ItemGroup>')
|
||||
p.callArray(m.elements.availableItemGroup, r)
|
||||
p.pop('</ItemGroup>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Generate the computed input targets group.
|
||||
---
|
||||
|
||||
m.elements.computeInputsGroup = function(r)
|
||||
return {
|
||||
m.computeLinkInputsTargets,
|
||||
m.computeLibInputsTargets,
|
||||
}
|
||||
end
|
||||
|
||||
function m.computeInputsGroup(r)
|
||||
p.push('<PropertyGroup>')
|
||||
p.callArray(m.elements.computeInputsGroup, r)
|
||||
p.pop('</PropertyGroup>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Generate the rule's target element.
|
||||
---
|
||||
|
||||
m.elements.ruleTargetAttributes = function(r)
|
||||
return {
|
||||
m.targetName,
|
||||
m.beforeTargets,
|
||||
m.afterTargets,
|
||||
m.targetCondition,
|
||||
m.targetOutputs,
|
||||
m.targetInputs,
|
||||
m.dependsOnTargets,
|
||||
}
|
||||
end
|
||||
|
||||
m.elements.ruleTarget = function(r)
|
||||
return {
|
||||
m.selectedFiles,
|
||||
m.tlog,
|
||||
m.message,
|
||||
m.tlogWrite,
|
||||
m.tlogRead,
|
||||
m.rule,
|
||||
}
|
||||
end
|
||||
|
||||
function m.ruleTarget(r)
|
||||
local attribs = p.capture(function()
|
||||
p.push()
|
||||
p.callArray(m.elements.ruleTargetAttributes, r)
|
||||
p.pop()
|
||||
end)
|
||||
|
||||
p.push('<Target')
|
||||
p.outln(attribs .. '>')
|
||||
p.callArray(m.elements.ruleTarget, r)
|
||||
p.pop('</Target>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Write out the tlog entries. I've extended this with an input
|
||||
-- dependencies fix as described here:
|
||||
-- http://www.virtualdub.org/blog/pivot/entry.php?id=334
|
||||
---
|
||||
|
||||
m.elements.tlog = function(r)
|
||||
return {
|
||||
m.tlogSource,
|
||||
m.tlogInputs,
|
||||
m.tlogProperties,
|
||||
}
|
||||
end
|
||||
|
||||
function m.tlog(r)
|
||||
p.push('<ItemGroup>')
|
||||
p.push('<%s_tlog', r.name)
|
||||
p.w('Include="%%(%s.Outputs)"', r.name)
|
||||
p.w('Condition="\'%%(%s.Outputs)\' != \'\' and \'%%(%s.ExcludedFromBuild)\' != \'true\'">', r.name, r.name)
|
||||
p.callArray(m.elements.tlog, r)
|
||||
p.pop('</%s_tlog>', r.name)
|
||||
p.pop('</ItemGroup>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Write out the rule element.
|
||||
---
|
||||
|
||||
m.elements.ruleAttributes = function(r)
|
||||
return {
|
||||
m.ruleCondition,
|
||||
m.commandLineTemplate,
|
||||
m.properties,
|
||||
m.additionalOptions,
|
||||
m.inputs,
|
||||
m.standardOutputImportance,
|
||||
}
|
||||
end
|
||||
|
||||
function m.rule(r)
|
||||
local attribs = p.capture(function()
|
||||
p.push()
|
||||
p.callArray(m.elements.ruleAttributes, r)
|
||||
p.pop()
|
||||
end)
|
||||
|
||||
p.w('<%s', r.name)
|
||||
p.outln(attribs .. ' />')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Generate the rule's computed output element.
|
||||
---
|
||||
|
||||
m.elements.computeOutputItems = function(r)
|
||||
return {
|
||||
m.outputs,
|
||||
m.linkLib,
|
||||
}
|
||||
end
|
||||
|
||||
m.elements.computeOutputTarget = function(r)
|
||||
return {
|
||||
m.makeDir,
|
||||
}
|
||||
end
|
||||
|
||||
function m.computeOutputTarget(r)
|
||||
p.push('<Target')
|
||||
p.w('Name="Compute%sOutput"', r.name)
|
||||
p.w('Condition="\'@(%s)\' != \'\'">', r.name)
|
||||
p.push('<ItemGroup>')
|
||||
p.callArray(m.elements.computeOutputItems, r)
|
||||
p.pop('</ItemGroup>')
|
||||
p.callArray(m.elements.computeOutputTarget, r)
|
||||
p.pop('</Target>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Implementations of individual elements.
|
||||
---
|
||||
|
||||
function m.additionalOptions(r)
|
||||
p.w('AdditionalOptions="%%(%s.AdditionalOptions)"', r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.commandLineTemplate(r)
|
||||
p.w('CommandLineTemplate="%%(%s.CommandLineTemplate)"', r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.afterTargets(r)
|
||||
p.w('AfterTargets="$(%sAfterTargets)"', r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.availableItemName(r)
|
||||
p.push('<AvailableItemName Include="%s">', r.name)
|
||||
p.w('<Targets>_%s</Targets>', r.name)
|
||||
p.pop('</AvailableItemName>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.beforeTargets(r)
|
||||
p.w('BeforeTargets="$(%sBeforeTargets)"', r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.computeLibInputsTargets(r)
|
||||
p.push('<ComputeLibInputsTargets>')
|
||||
p.w('$(ComputeLibInputsTargets);')
|
||||
p.w('Compute%sOutput;', r.name)
|
||||
p.pop('</ComputeLibInputsTargets>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.computeLinkInputsTargets(r)
|
||||
p.push('<ComputeLinkInputsTargets>')
|
||||
p.w('$(ComputeLinkInputsTargets);')
|
||||
p.w('Compute%sOutput;', r.name)
|
||||
p.pop('</ComputeLinkInputsTargets>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.dependsOnTargets(r)
|
||||
p.w('DependsOnTargets="$(%sDependsOn);Compute%sOutput"', r.name, r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.inputs(r)
|
||||
p.w('Inputs="%%(%s.Identity)"', r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.linkLib(r)
|
||||
local linkable
|
||||
for i = 1, #r.buildoutputs do
|
||||
if (path.islinkable(r.buildoutputs[i])) then
|
||||
linkable = true
|
||||
end
|
||||
end
|
||||
if linkable then
|
||||
for i, el in pairs { 'Link', 'Lib', 'ImpLib' } do
|
||||
p.push('<%s', el)
|
||||
p.w('Include="%%(%sOutputs.Identity)"', r.name)
|
||||
p.w('Condition="\'%%(Extension)\'==\'.obj\' or \'%%(Extension)\'==\'.res\' or \'%%(Extension)\'==\'.rsc\' or \'%%(Extension)\'==\'.lib\'" />')
|
||||
p.pop()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.makeDir(r)
|
||||
p.w('<MakeDir Directories="@(%sOutputs->\'%%(RootDir)%%(Directory)\')" />', r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.message(r)
|
||||
p.w('<Message')
|
||||
p.w(' Importance="High"')
|
||||
p.w(' Text="%%(%s.ExecutionDescription)" />', r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.outputs(r)
|
||||
p.w('<%sOutputs', r.name)
|
||||
p.w(' Condition="\'@(%s)\' != \'\' and \'%%(%s.ExcludedFromBuild)\' != \'true\'"', r.name, r.name)
|
||||
p.w(' Include="%%(%s.Outputs)" />', r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.properties(r)
|
||||
local defs = r.propertyDefinition
|
||||
for i = 1, #defs do
|
||||
local name = defs[i].name
|
||||
p.w('%s="%%(%s.%s)"', name, r.name, name)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.propertyPageSchema(r)
|
||||
p.w('<PropertyPageSchema')
|
||||
p.w(' Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml" />')
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.ruleCondition(r)
|
||||
p.w('Condition="\'@(%s)\' != \'\' and \'%%(%s.ExcludedFromBuild)\' != \'true\'"', r.name, r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.selectedFiles(r)
|
||||
p.push('<ItemGroup Condition="\'@(SelectedFiles)\' != \'\'">')
|
||||
p.w('<%s Remove="@(%s)" Condition="\'%%(Identity)\' != \'@(SelectedFiles)\'" />', r.name, r.name)
|
||||
p.pop('</ItemGroup>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.standardOutputImportance(r)
|
||||
p.w('StandardOutputImportance="High"')
|
||||
p.w('StandardErrorImportance="High"')
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.targetCondition(r)
|
||||
p.w('Condition="\'@(%s)\' != \'\'"', r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.targetInputs(r)
|
||||
local extra = {}
|
||||
local defs = r.propertyDefinition
|
||||
for i = 1, #defs do
|
||||
local def = defs[i]
|
||||
if def.dependency then
|
||||
table.insert(extra, string.format("%%(%s.%s);", r.name, def.name))
|
||||
end
|
||||
end
|
||||
extra = table.concat(extra)
|
||||
p.w('Inputs="%%(%s.Identity);%%(%s.AdditionalDependencies);%s$(MSBuildProjectFile)"', r.name, r.name, extra)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.targetName(r)
|
||||
p.w('Name="_%s"', r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.targetOutputs(r)
|
||||
p.w('Outputs="%%(%s.Outputs)"', r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.tlogInputs(r)
|
||||
p.w("<Inputs>@(%s, ';')</Inputs>", r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.tlogProperties(r)
|
||||
local defs = r.propertyDefinition
|
||||
for i = 1, #defs do
|
||||
local def = defs[i]
|
||||
if def.dependency then
|
||||
p.w('<%s>%%(%s.%s)</%s>', def.name, r.name, def.name, def.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.tlogRead(r)
|
||||
local extra = {}
|
||||
local defs = r.propertyDefinition
|
||||
for i = 1, #defs do
|
||||
local def = defs[i]
|
||||
if def.dependency then
|
||||
table.insert(extra, string.format("%%(%s_tlog.%s);", r.name, def.name))
|
||||
end
|
||||
end
|
||||
extra = table.concat(extra)
|
||||
|
||||
p.w('<WriteLinesToFile')
|
||||
p.w(' Condition="\'@(%s_tlog)\' != \'\' and \'%%(%s_tlog.ExcludedFromBuild)\' != \'true\'"', r.name, r.name)
|
||||
p.w(' File="$(IntDir)$(ProjectName).read.1.tlog"')
|
||||
p.w(' Lines="^%%(%s_tlog.Inputs);%s$(MSBuildProjectFullPath);%%(%s_tlog.Fullpath)" />', r.name, extra, r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.tlogWrite(r)
|
||||
p.w('<WriteLinesToFile')
|
||||
p.w(' Condition="\'@(%s_tlog)\' != \'\' and \'%%(%s_tlog.ExcludedFromBuild)\' != \'true\'"', r.name, r.name)
|
||||
p.w(' File="$(IntDir)$(ProjectName).write.1.tlog"')
|
||||
p.w(' Lines="^%%(%s_tlog.Source);%%(%s_tlog.Fullpath)" />', r.name, r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.tlogSource(r)
|
||||
p.w("<Source>@(%s, '|')</Source>", r.name)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.usingTask(r)
|
||||
p.push('<UsingTask')
|
||||
p.w('TaskName="%s"', r.name)
|
||||
p.w('TaskFactory="XamlTaskFactory"')
|
||||
p.w('AssemblyName="Microsoft.Build.Tasks.v4.0">')
|
||||
p.w('<Task>$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml</Task>')
|
||||
p.pop('</UsingTask>')
|
||||
end
|
||||
|
||||
|
||||
|
392
src/actions/vstudio/vs2010_rules_xml.lua
Normal file
392
src/actions/vstudio/vs2010_rules_xml.lua
Normal file
@ -0,0 +1,392 @@
|
||||
---
|
||||
-- vs2010_rules_xml.lua
|
||||
-- Generate a Visual Studio 201x custom rules XML file.
|
||||
-- Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
premake.vstudio.vs2010.rules.xml = {}
|
||||
|
||||
local m = premake.vstudio.vs2010.rules.xml
|
||||
m.elements = {}
|
||||
|
||||
local p = premake
|
||||
|
||||
|
||||
---
|
||||
-- Entry point; generate the root <ProjectSchemaDefinitions> element.
|
||||
---
|
||||
|
||||
m.elements.project = function(r)
|
||||
return {
|
||||
p.xmlUtf8,
|
||||
m.projectSchemaDefinitions,
|
||||
m.rule,
|
||||
m.ruleItem,
|
||||
m.fileExtension,
|
||||
m.contentType,
|
||||
}
|
||||
end
|
||||
|
||||
function m.generate(r)
|
||||
p.callArray(m.elements.project, r)
|
||||
p.out('</ProjectSchemaDefinitions>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Generate the main <Rule> element.
|
||||
---
|
||||
|
||||
m.elements.rule = function(r)
|
||||
return {
|
||||
m.dataSource,
|
||||
m.categories,
|
||||
m.inputs,
|
||||
m.properties,
|
||||
m.commandLineTemplate,
|
||||
m.beforeTargets,
|
||||
m.afterTargets,
|
||||
m.outputs,
|
||||
m.executionDescription,
|
||||
m.additionalDependencies,
|
||||
m.additionalOptions,
|
||||
}
|
||||
end
|
||||
|
||||
function m.rule(r)
|
||||
p.push('<Rule')
|
||||
p.w('Name="%s"', r.name)
|
||||
p.w('PageTemplate="tool"')
|
||||
p.w('DisplayName="%s"', r.display or r.name)
|
||||
p.w('Order="200">')
|
||||
p.callArray(m.elements.rule, r)
|
||||
p.pop('</Rule>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Generate the list of categories.
|
||||
---
|
||||
|
||||
function m.categories(r)
|
||||
local categories = {
|
||||
[1] = { name="General" },
|
||||
[2] = { name="Command Line", subtype="CommandLine" },
|
||||
}
|
||||
p.push('<Rule.Categories>')
|
||||
for i = 1, #categories do
|
||||
m.category(categories[i])
|
||||
end
|
||||
p.pop('</Rule.Categories>')
|
||||
end
|
||||
|
||||
|
||||
function m.category(cat)
|
||||
local attribs = p.capture(function()
|
||||
p.push()
|
||||
p.w('Name="%s"', cat.name)
|
||||
if cat.subtype then
|
||||
p.w('Subtype="%s"', cat.subtype)
|
||||
end
|
||||
p.pop()
|
||||
end)
|
||||
|
||||
p.push('<Category')
|
||||
p.outln(attribs .. '>')
|
||||
|
||||
p.push('<Category.DisplayName>')
|
||||
p.w('<sys:String>%s</sys:String>', cat.name)
|
||||
p.pop('</Category.DisplayName>')
|
||||
|
||||
p.pop('</Category>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Generate the list of property definitions.
|
||||
---
|
||||
|
||||
function m.properties(r)
|
||||
local defs = r.propertyDefinition
|
||||
for i = 1, #defs do
|
||||
local def = defs[i]
|
||||
if def.kind == "boolean" then
|
||||
m.boolProperty(def)
|
||||
elseif def.kind == "list" then
|
||||
m.stringListProperty(def)
|
||||
elseif type(def.values) == "table" then
|
||||
m.enumProperty(def)
|
||||
else
|
||||
m.stringProperty(def)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function m.baseProperty(def, suffix)
|
||||
local c = p.capture(function ()
|
||||
p.w('Name="%s"', def.name)
|
||||
p.w('HelpContext="0"')
|
||||
p.w('DisplayName="%s"', def.display or def.name)
|
||||
if def.description then
|
||||
p.w('Description="%s"', def.description)
|
||||
end
|
||||
end)
|
||||
if suffix then
|
||||
c = c .. suffix
|
||||
end
|
||||
p.outln(c)
|
||||
end
|
||||
|
||||
|
||||
function m.boolProperty(def)
|
||||
p.push('<BoolProperty')
|
||||
m.baseProperty(def)
|
||||
p.w('Switch="%s" />', def.switch or "[value]")
|
||||
p.pop()
|
||||
end
|
||||
|
||||
|
||||
function m.enumProperty(def)
|
||||
p.push('<EnumProperty')
|
||||
m.baseProperty(def, '>')
|
||||
|
||||
local values = def.values
|
||||
local switches = def.switch or {}
|
||||
|
||||
local keys = table.keys(def.values)
|
||||
table.sort(keys)
|
||||
|
||||
for _, key in pairs(keys) do
|
||||
p.push('<EnumValue')
|
||||
p.w('Name="%d"', key)
|
||||
if switches[key] then
|
||||
p.w('DisplayName="%s"', values[key])
|
||||
p.w('Switch="%s" />', switches[key])
|
||||
else
|
||||
p.w('DisplayName="%s" />', values[key])
|
||||
end
|
||||
p.pop()
|
||||
end
|
||||
|
||||
p.pop('</EnumProperty>')
|
||||
end
|
||||
|
||||
|
||||
function m.stringProperty(def)
|
||||
p.push('<StringProperty')
|
||||
m.baseProperty(def)
|
||||
p.w('Switch="%s" />', def.switch or "[value]")
|
||||
p.pop()
|
||||
end
|
||||
|
||||
|
||||
function m.stringListProperty(def)
|
||||
p.push('<StringListProperty')
|
||||
m.baseProperty(def)
|
||||
p.w('Separator="%s"', def.separator or " ")
|
||||
p.w('Switch="%s" />', def.switch or "[value]")
|
||||
p.pop()
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Implementations of individual elements.
|
||||
---
|
||||
|
||||
function m.additionalDependencies(r)
|
||||
p.push('<StringListProperty')
|
||||
p.w('Name="AdditionalDependencies"')
|
||||
p.w('DisplayName="Additional Dependencies"')
|
||||
p.w('IncludeInCommandLine="False"')
|
||||
p.w('Visible="false" />')
|
||||
p.pop()
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.additionalOptions(r)
|
||||
p.push('<StringProperty')
|
||||
p.w('Subtype="AdditionalOptions"')
|
||||
p.w('Name="AdditionalOptions"')
|
||||
p.w('Category="Command Line">')
|
||||
p.push('<StringProperty.DisplayName>')
|
||||
p.w('<sys:String>Additional Options</sys:String>')
|
||||
p.pop('</StringProperty.DisplayName>')
|
||||
p.push('<StringProperty.Description>')
|
||||
p.w('<sys:String>Additional Options</sys:String>')
|
||||
p.pop('</StringProperty.Description>')
|
||||
p.pop('</StringProperty>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.afterTargets(r)
|
||||
p.push('<DynamicEnumProperty')
|
||||
p.w('Name="%sAfterTargets"', r.name)
|
||||
p.w('Category="General"')
|
||||
p.w('EnumProvider="Targets"')
|
||||
p.w('IncludeInCommandLine="False">')
|
||||
|
||||
p.push('<DynamicEnumProperty.DisplayName>')
|
||||
p.w('<sys:String>Execute After</sys:String>')
|
||||
p.pop('</DynamicEnumProperty.DisplayName>')
|
||||
|
||||
p.push('<DynamicEnumProperty.Description>')
|
||||
p.w('<sys:String>Specifies the targets for the build customization to run after.</sys:String>')
|
||||
p.pop('</DynamicEnumProperty.Description>')
|
||||
|
||||
p.push('<DynamicEnumProperty.ProviderSettings>')
|
||||
p.push('<NameValuePair')
|
||||
p.w('Name="Exclude"')
|
||||
p.w('Value="^%sAfterTargets|^Compute" />', r.name)
|
||||
p.pop()
|
||||
p.pop('</DynamicEnumProperty.ProviderSettings>')
|
||||
|
||||
p.push('<DynamicEnumProperty.DataSource>')
|
||||
p.push('<DataSource')
|
||||
p.w('Persistence="ProjectFile"')
|
||||
p.w('ItemType=""')
|
||||
p.w('HasConfigurationCondition="true" />')
|
||||
p.pop()
|
||||
p.pop('</DynamicEnumProperty.DataSource>')
|
||||
|
||||
p.pop('</DynamicEnumProperty>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.beforeTargets(r)
|
||||
p.push('<DynamicEnumProperty')
|
||||
p.w('Name="%sBeforeTargets"', r.name)
|
||||
p.w('Category="General"')
|
||||
p.w('EnumProvider="Targets"')
|
||||
p.w('IncludeInCommandLine="False">')
|
||||
|
||||
p.push('<DynamicEnumProperty.DisplayName>')
|
||||
p.w('<sys:String>Execute Before</sys:String>')
|
||||
p.pop('</DynamicEnumProperty.DisplayName>')
|
||||
|
||||
p.push('<DynamicEnumProperty.Description>')
|
||||
p.w('<sys:String>Specifies the targets for the build customization to run before.</sys:String>')
|
||||
p.pop('</DynamicEnumProperty.Description>')
|
||||
|
||||
p.push('<DynamicEnumProperty.ProviderSettings>')
|
||||
p.push('<NameValuePair')
|
||||
p.w('Name="Exclude"')
|
||||
p.w('Value="^%sBeforeTargets|^Compute" />', r.name)
|
||||
p.pop()
|
||||
p.pop('</DynamicEnumProperty.ProviderSettings>')
|
||||
|
||||
p.push('<DynamicEnumProperty.DataSource>')
|
||||
p.push('<DataSource')
|
||||
p.w('Persistence="ProjectFile"')
|
||||
p.w('HasConfigurationCondition="true" />')
|
||||
p.pop()
|
||||
p.pop('</DynamicEnumProperty.DataSource>')
|
||||
|
||||
p.pop('</DynamicEnumProperty>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.commandLineTemplate(r)
|
||||
p.push('<StringProperty')
|
||||
p.w('Name="CommandLineTemplate"')
|
||||
p.w('DisplayName="Command Line"')
|
||||
p.w('Visible="False"')
|
||||
p.w('IncludeInCommandLine="False" />')
|
||||
p.pop()
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.contentType(r)
|
||||
p.push('<ContentType')
|
||||
p.w('Name="%s"', r.name)
|
||||
p.w('DisplayName="%s"', r.display or r.name)
|
||||
p.w('ItemType="%s" />', r.name)
|
||||
p.pop()
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.dataSource(r)
|
||||
p.push('<Rule.DataSource>')
|
||||
p.push('<DataSource')
|
||||
p.w('Persistence="ProjectFile"')
|
||||
p.w('ItemType="%s" />', r.name)
|
||||
p.pop()
|
||||
p.pop('</Rule.DataSource>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.executionDescription(r)
|
||||
p.push('<StringProperty')
|
||||
p.w('Name="ExecutionDescription"')
|
||||
p.w('DisplayName="Execution Description"')
|
||||
p.w('Visible="False"')
|
||||
p.w('IncludeInCommandLine="False" />')
|
||||
p.pop()
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.fileExtension(r)
|
||||
p.push('<FileExtension')
|
||||
p.w('Name="*%s"', r.fileExtension)
|
||||
p.w('ContentType="%s" />', r.name)
|
||||
p.pop()
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.inputs(r)
|
||||
p.push('<StringListProperty')
|
||||
p.w('Name="Inputs"')
|
||||
p.w('Category="Command Line"')
|
||||
p.w('IsRequired="true"')
|
||||
p.w('Switch=" ">')
|
||||
|
||||
p.push('<StringListProperty.DataSource>')
|
||||
p.push('<DataSource')
|
||||
p.w('Persistence="ProjectFile"')
|
||||
p.w('ItemType="%s"', r.name)
|
||||
p.w('SourceType="Item" />')
|
||||
p.pop()
|
||||
|
||||
p.pop('</StringListProperty.DataSource>')
|
||||
p.pop('</StringListProperty>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.outputs(r)
|
||||
p.push('<StringListProperty')
|
||||
p.w('Name="Outputs"')
|
||||
p.w('DisplayName="Outputs"')
|
||||
p.w('Visible="False"')
|
||||
p.w('IncludeInCommandLine="False" />')
|
||||
p.pop()
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.ruleItem(r)
|
||||
p.push('<ItemType')
|
||||
p.w('Name="%s"', r.name)
|
||||
p.w('DisplayName="%s" />', r.display or r.name)
|
||||
p.pop()
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.projectSchemaDefinitions(r)
|
||||
p.push('<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib">')
|
||||
end
|
||||
|
@ -47,7 +47,7 @@
|
||||
|
||||
function m.generate(prj)
|
||||
io.utf8()
|
||||
m.xmlDeclaration()
|
||||
m.xmlDeclaration()
|
||||
m.project("Build")
|
||||
p.callArray(m.elements.project, prj)
|
||||
p.out('</Project>')
|
||||
@ -1583,8 +1583,9 @@
|
||||
end
|
||||
|
||||
|
||||
|
||||
function m.xmlDeclaration()
|
||||
_p('<?xml version="1.0" encoding="utf-8"?>')
|
||||
p.xmlUtf8()
|
||||
end
|
||||
|
||||
|
||||
|
@ -1,10 +1,14 @@
|
||||
--
|
||||
---
|
||||
-- action.lua
|
||||
-- Work with the list of registered actions.
|
||||
-- Copyright (c) 2002-2009 Jason Perkins and the Premake project
|
||||
--
|
||||
-- Copyright (c) 2002-2014 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
premake.action = {}
|
||||
local action = premake.action
|
||||
|
||||
local p = premake
|
||||
|
||||
|
||||
|
||||
--
|
||||
@ -32,32 +36,32 @@
|
||||
-- new entries here.
|
||||
--
|
||||
|
||||
premake.action.list = {}
|
||||
action._list = {}
|
||||
|
||||
|
||||
--
|
||||
-- Register a new action.
|
||||
--
|
||||
-- @param a
|
||||
-- @param act
|
||||
-- The new action object.
|
||||
--
|
||||
|
||||
function premake.action.add(a)
|
||||
function action.add(act)
|
||||
-- validate the action object, at least a little bit
|
||||
local missing
|
||||
for _, field in ipairs({"description", "trigger"}) do
|
||||
if not a[field] then
|
||||
if not act[field] then
|
||||
missing = field
|
||||
end
|
||||
end
|
||||
|
||||
if missing then
|
||||
local name = a.trigger or ""
|
||||
local name = act.trigger or ""
|
||||
error(string.format('action "%s" needs a %s', name, missing), 3)
|
||||
end
|
||||
|
||||
-- add it to the master list
|
||||
premake.action.list[a.trigger] = a
|
||||
action._list[act.trigger] = act
|
||||
end
|
||||
|
||||
|
||||
@ -70,28 +74,28 @@
|
||||
-- None.
|
||||
--
|
||||
|
||||
function premake.action.call(name)
|
||||
local a = premake.action.list[name]
|
||||
function action.call(name)
|
||||
local act = action._list[name]
|
||||
|
||||
-- TODO: remove this once everyone's had a chance to see
|
||||
-- the deprecation warning
|
||||
if _ACTION:endswith("ng") then
|
||||
_ACTION = _ACTION:sub(1, -3)
|
||||
end
|
||||
|
||||
for sln in premake.solution.each() do
|
||||
if a.onsolution then
|
||||
a.onsolution(sln)
|
||||
for sln in p.solution.each() do
|
||||
if act.onsolution then
|
||||
act.onsolution(sln)
|
||||
end
|
||||
for prj in premake.solution.eachproject(sln) do
|
||||
if a.onproject and not prj.external then
|
||||
a.onproject(prj)
|
||||
for prj in p.solution.eachproject(sln) do
|
||||
if act.onproject and not prj.external then
|
||||
act.onproject(prj)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if a.execute then
|
||||
a.execute()
|
||||
for rule in p.rules.each() do
|
||||
if act.onrule then
|
||||
act.onrule(rule)
|
||||
end
|
||||
end
|
||||
|
||||
if act.execute then
|
||||
act.execute()
|
||||
end
|
||||
end
|
||||
|
||||
@ -103,8 +107,8 @@
|
||||
-- The current action, or nil if _ACTION is nil or does not match any action.
|
||||
--
|
||||
|
||||
function premake.action.current()
|
||||
return premake.action.get(_ACTION)
|
||||
function action.current()
|
||||
return action.get(_ACTION)
|
||||
end
|
||||
|
||||
|
||||
@ -117,13 +121,12 @@
|
||||
-- The requested action, or nil if the action does not exist.
|
||||
--
|
||||
|
||||
function premake.action.get(name)
|
||||
function action.get(name)
|
||||
-- "Next-gen" actions are deprecated
|
||||
if name and name:endswith("ng") then
|
||||
name = name:sub(1, -3)
|
||||
end
|
||||
|
||||
return premake.action.list[name]
|
||||
return action._list[name]
|
||||
end
|
||||
|
||||
|
||||
@ -131,18 +134,18 @@
|
||||
-- Iterator for the list of actions.
|
||||
--
|
||||
|
||||
function premake.action.each()
|
||||
function action.each()
|
||||
-- sort the list by trigger
|
||||
local keys = { }
|
||||
for _, action in pairs(premake.action.list) do
|
||||
table.insert(keys, action.trigger)
|
||||
for _, act in pairs(action._list) do
|
||||
table.insert(keys, act.trigger)
|
||||
end
|
||||
table.sort(keys)
|
||||
|
||||
local i = 0
|
||||
return function()
|
||||
i = i + 1
|
||||
return premake.action.list[keys[i]]
|
||||
return act._list[keys[i]]
|
||||
end
|
||||
end
|
||||
|
||||
@ -154,13 +157,13 @@
|
||||
-- The name of the action to activate.
|
||||
--
|
||||
|
||||
function premake.action.set(name)
|
||||
function action.set(name)
|
||||
_ACTION = name
|
||||
|
||||
-- Some actions imply a particular operating system
|
||||
local action = premake.action.get(name)
|
||||
if action then
|
||||
_OS = action.os or _OS
|
||||
local act = action.get(name)
|
||||
if act then
|
||||
_OS = act.os or _OS
|
||||
end
|
||||
end
|
||||
|
||||
@ -168,7 +171,7 @@
|
||||
--
|
||||
-- Determines if an action supports a particular language or target type.
|
||||
--
|
||||
-- @param action
|
||||
-- @param act
|
||||
-- The action to test.
|
||||
-- @param feature
|
||||
-- The feature to check, either a programming language or a target type.
|
||||
@ -176,17 +179,17 @@
|
||||
-- True if the feature is supported, false otherwise.
|
||||
--
|
||||
|
||||
function premake.action.supports(action, feature)
|
||||
if not action then
|
||||
function action.supports(act, feature)
|
||||
if not act then
|
||||
return false
|
||||
end
|
||||
if action.valid_languages then
|
||||
if table.contains(action.valid_languages, feature) then
|
||||
if act.valid_languages then
|
||||
if table.contains(act.valid_languages, feature) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
if action.valid_kinds then
|
||||
if table.contains(action.valid_kinds, feature) then
|
||||
if act.valid_kinds then
|
||||
if table.contains(act.valid_kinds, feature) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
@ -194,19 +197,20 @@
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Determines if an action supports a particular configuration.
|
||||
-- @return
|
||||
-- True if the configuration is supported, false otherwise.
|
||||
--
|
||||
|
||||
function premake.action.supportsconfig(action, cfg)
|
||||
if not action then
|
||||
function action.supportsconfig(act, cfg)
|
||||
if not act then
|
||||
return false
|
||||
end
|
||||
|
||||
if action.supportsconfig then
|
||||
return action.supportsconfig(cfg)
|
||||
if act.supportsconfig then
|
||||
return act.supportsconfig(cfg)
|
||||
end
|
||||
|
||||
return true
|
||||
|
332
src/base/api.lua
332
src/base/api.lua
@ -6,24 +6,180 @@
|
||||
|
||||
premake.api = {}
|
||||
local api = premake.api
|
||||
local configset = premake.configset
|
||||
|
||||
local p = premake
|
||||
local configset = p.configset
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Set up a place to store the current active objects in each configuration
|
||||
-- scope (e.g. solutions, projects, groups, and configurations). Initialize
|
||||
-- it with a "root" container to contain the other containers, as well as the
|
||||
-- global configuration settings which should apply to all of them.
|
||||
--
|
||||
-- Create a "root" configuration set, to hold the global configuration. Values
|
||||
-- that are added to this set become available for all add-ons, solution, projects,
|
||||
-- and on down the line.
|
||||
-- TODO: this should be hidden, with a perhaps a read-only accessor to fetch
|
||||
-- individual scopes for testing.
|
||||
---
|
||||
|
||||
api.scope = {}
|
||||
api.scope.root = p.containerClass.define("root"):new("root")
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Register a new class of configuration container. A configuration container
|
||||
-- can hold configuration settings, as well as child configuration containers.
|
||||
-- Solutions, projects, and rules are all examples of containers.
|
||||
--
|
||||
-- @param def
|
||||
-- The container definition; see premake.container.define().
|
||||
-- @returns
|
||||
-- The newly defined container class.
|
||||
---
|
||||
|
||||
configset.root = configset.new()
|
||||
function api.container(def)
|
||||
-- for now, everything inherits the root configuration
|
||||
if not def.parent then
|
||||
def.parent = "root"
|
||||
end
|
||||
|
||||
-- register the new class; validation checks may cause a failure
|
||||
local cc, err = p.containerClass.define(def)
|
||||
if not cc then
|
||||
error(err, 2)
|
||||
end
|
||||
|
||||
-- create a global function to create new instances, e.g project()
|
||||
_G[cc.name] = function(name)
|
||||
return api._setScope(cc, name)
|
||||
end
|
||||
|
||||
return cc
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Return the currently active configuration container instance.
|
||||
---
|
||||
|
||||
function api.currentContainer()
|
||||
return api.scope.current or api.scope.root
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Return the root container, which contains the global configuration and
|
||||
-- all of the child containers (solutions, rules).
|
||||
---
|
||||
|
||||
function api.rootContainer()
|
||||
return api.scope.root
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Recursively clear any child scopes for a container class. For example,
|
||||
-- if a solution is being activated, clear the project and group scopes,
|
||||
-- as those are children of solutions. If the root scope is made active,
|
||||
-- all child scopes will be cleared.
|
||||
---
|
||||
|
||||
function api._clearChildScopes(cc)
|
||||
for ch in cc:eachChildClass() do
|
||||
api.scope[ch.name] = nil
|
||||
api._clearChildScopes(ch)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Activate a new configuration container, making it the target for all
|
||||
-- subsequent configuration settings. When you call solution() or project()
|
||||
-- to active a container, that call comes here (see api.container() for the
|
||||
-- details on how that happens).
|
||||
--
|
||||
-- A place to store the current active objects in each configuration scope
|
||||
-- (e.g. solutions, projects, groups, and configurations).
|
||||
--
|
||||
-- @param cc
|
||||
-- The container class being activated, e.g. a project or solution.
|
||||
-- @param name
|
||||
-- The name of the container instance to be activated. If a container
|
||||
-- (e.g. project) with this name does not already exist it will be
|
||||
-- created. If name is not set, the last activated container of this
|
||||
-- class will be made current again.
|
||||
-- @return
|
||||
-- The container instance.
|
||||
---
|
||||
|
||||
function api._setScope(cc, name)
|
||||
-- for backward compatibility, "*" activates the parent container
|
||||
if name == "*" then
|
||||
return api._setScope(cc.parent)
|
||||
end
|
||||
|
||||
-- if name is not set, use whatever was last made current
|
||||
local container
|
||||
if not name then
|
||||
container = api.scope[cc.name]
|
||||
if not container then
|
||||
error("no " .. cc.name .. " in scope", 3)
|
||||
end
|
||||
end
|
||||
|
||||
if not container then
|
||||
-- all containers should be contained within a parent
|
||||
local parent = api.scope[cc.parent.name]
|
||||
if not parent then
|
||||
error("no active " .. cc.parent.name, 3)
|
||||
end
|
||||
|
||||
-- fetch (creating if necessary) the container
|
||||
container = parent:fetchChild(cc, name)
|
||||
if not container then
|
||||
container = parent:createChild(cc, name, parent)
|
||||
else
|
||||
configset.addFilter(container, {}, os.getcwd())
|
||||
end
|
||||
end
|
||||
|
||||
-- clear out any active child container types
|
||||
api._clearChildScopes(cc)
|
||||
|
||||
-- activate the container, as well as its ancestors
|
||||
if not cc.placeholder then
|
||||
api.scope.current = container
|
||||
end
|
||||
while container.parent do
|
||||
api.scope[container.class.name] = container
|
||||
container = container.parent
|
||||
end
|
||||
|
||||
return api.scope.current
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Find the closest active scope for the given container class. If no
|
||||
-- exact instance of this container class is in scope, searches up the
|
||||
-- class hierarchy to find the closest parent that is in scope.
|
||||
--
|
||||
-- @param cc
|
||||
-- The container class to target.
|
||||
-- @return
|
||||
-- The closest available active container instance.
|
||||
---
|
||||
|
||||
function api._target(cc)
|
||||
while not api.scope[cc.name] do
|
||||
cc = cc.parent
|
||||
end
|
||||
return api.scope[cc.name]
|
||||
end
|
||||
|
||||
api.scope = { root = configset.root }
|
||||
|
||||
|
||||
---
|
||||
@ -292,14 +448,47 @@
|
||||
|
||||
|
||||
---
|
||||
-- Find the currently active configuration scope.
|
||||
-- Return the target container instance for a field.
|
||||
--
|
||||
-- @param field
|
||||
-- The field being set or fetched.
|
||||
-- @return
|
||||
-- The currently active configuration set object.
|
||||
-- The currently active container instance if one is available, or nil if
|
||||
-- active container is of the wrong class.
|
||||
---
|
||||
|
||||
function api.gettarget()
|
||||
return api.scope.project or api.scope.solution or api.scope.root
|
||||
function api.target(field)
|
||||
-- if nothing is in scope, use the global root scope
|
||||
|
||||
if not api.scope.current then
|
||||
return api.scope.root
|
||||
end
|
||||
|
||||
-- use the current scope if it falls within the container hierarchy
|
||||
-- of one of this field's target scopes; it is okay to set a value of
|
||||
-- the parent of container (e.g. a project-level value can be set on a
|
||||
-- solution, since it will be inherited).
|
||||
|
||||
local currentClass = api.scope.current.class
|
||||
for i = 1, #field.scopes do
|
||||
-- temporary: map config scope to the desired container class; will
|
||||
-- go away once everything is ported to containers
|
||||
local targetScope = field.scopes[i]
|
||||
if targetScope == "config" then
|
||||
targetScope = "project"
|
||||
end
|
||||
|
||||
local targetClass = p.containerClass.get(targetScope)
|
||||
repeat
|
||||
if currentClass == targetClass then
|
||||
return api.scope.current
|
||||
end
|
||||
targetClass = targetClass.parent
|
||||
until not targetClass
|
||||
end
|
||||
|
||||
-- this field's scope isn't available
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
@ -322,7 +511,12 @@
|
||||
end
|
||||
end
|
||||
|
||||
local target = api.gettarget()
|
||||
local target = api.target(field)
|
||||
if not target then
|
||||
local err = string.format("unable to set %s in %s scope, should be %s", field.name, api.scope.current.class.name, table.concat(field.scopes, ", "))
|
||||
error(err, 3)
|
||||
end
|
||||
|
||||
local status, err = configset.store(target, field, value)
|
||||
if err then
|
||||
error(err, 3)
|
||||
@ -342,7 +536,12 @@
|
||||
-- return the current baked value
|
||||
if not value then return end
|
||||
|
||||
local target = api.gettarget()
|
||||
local target = api.target(field)
|
||||
if not target then
|
||||
local err = string.format("unable to remove %s from %s scope, should be %s", field.name, api.scope.current.class.name, table.concat(field.scopes, ", "))
|
||||
error(err, 3)
|
||||
end
|
||||
|
||||
local hasDeprecatedValues = (type(field.deprecated) == "table")
|
||||
|
||||
-- Build a list of values to be removed. If this field has deprecated
|
||||
@ -478,6 +677,9 @@
|
||||
---
|
||||
|
||||
function api.reset()
|
||||
-- Clear out all top level objects
|
||||
api.scope.root.solutions = {}
|
||||
|
||||
-- Remove all custom variables
|
||||
local vars = api.getCustomVars()
|
||||
for i, var in ipairs(vars) do
|
||||
@ -854,7 +1056,7 @@
|
||||
---
|
||||
|
||||
function configuration(terms)
|
||||
local target = api.gettarget()
|
||||
local target = api.currentContainer()
|
||||
if terms then
|
||||
if terms == "*" then terms = nil end
|
||||
configset.addblock(target, {terms}, os.getcwd())
|
||||
@ -870,7 +1072,7 @@
|
||||
---
|
||||
|
||||
function filter(terms)
|
||||
local target = api.gettarget()
|
||||
local target = api.currentContainer()
|
||||
if terms then
|
||||
if terms == "*" then terms = nil end
|
||||
local ok, err = configset.addFilter(target, {terms}, os.getcwd())
|
||||
@ -882,60 +1084,6 @@
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Begin a new solution group, which will contain any subsequent projects.
|
||||
---
|
||||
|
||||
function group(name)
|
||||
if name == "*" then name = nil end
|
||||
api.scope.group = name
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Set the current configuration scope to a project.
|
||||
--
|
||||
-- @param name
|
||||
-- The name of the project. If a project with this name already
|
||||
-- exists, it is made current, otherwise a new project is created
|
||||
-- with this name. If no name is provided, the most recently defined
|
||||
-- project is made active.
|
||||
-- @return
|
||||
-- The active project object.
|
||||
--
|
||||
|
||||
function project(name)
|
||||
if not name then
|
||||
if api.scope.project then
|
||||
name = api.scope.project.name
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local sln = api.scope.solution
|
||||
if not sln then
|
||||
error("no active solution", 2)
|
||||
end
|
||||
|
||||
local prj
|
||||
if name ~= "*" then
|
||||
prj = sln.projects[name]
|
||||
if not prj then
|
||||
prj = premake.project.new(sln, name)
|
||||
prj.group = api.scope.group or ""
|
||||
premake.solution.addproject(sln, prj)
|
||||
end
|
||||
end
|
||||
|
||||
api.scope.project = prj
|
||||
|
||||
configuration {}
|
||||
|
||||
return prj
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Activates a reference to an external, non-Premake generated project.
|
||||
--
|
||||
@ -955,41 +1103,6 @@
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Set the current configuration scope to a solution.
|
||||
--
|
||||
-- @param name
|
||||
-- The name of the solution. If a solution with this name already
|
||||
-- exists, it is made current, otherwise a new solution is created
|
||||
-- with this name. If no name is provided, the most recently defined
|
||||
-- solution is made active.
|
||||
-- @return
|
||||
-- The active solution object.
|
||||
--
|
||||
|
||||
function solution(name)
|
||||
if not name then
|
||||
if api.scope.solution then
|
||||
name = api.scope.solution.name
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local sln
|
||||
if name ~= "*" then
|
||||
sln = premake.solution.get(name) or premake.solution.new(name)
|
||||
end
|
||||
|
||||
api.scope.solution = sln
|
||||
api.scope.project = nil
|
||||
api.scope.group = nil
|
||||
|
||||
configuration {}
|
||||
|
||||
return sln
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Define a new action.
|
||||
@ -1124,7 +1237,12 @@
|
||||
}
|
||||
end
|
||||
|
||||
local cset = api.gettarget()
|
||||
local cset = api.target(field)
|
||||
if not cset then
|
||||
local err = string.format("unable to set rule in %s scope, should be project", api.scope.current.class.name)
|
||||
error(err, 2)
|
||||
end
|
||||
|
||||
local current = cset.current
|
||||
cset.current = cset.blocks[1]
|
||||
api.callback(field, value)
|
||||
|
245
src/base/container.lua
Normal file
245
src/base/container.lua
Normal file
@ -0,0 +1,245 @@
|
||||
---
|
||||
-- container.lua
|
||||
-- Implementation of configuration containers.
|
||||
-- Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
local p = premake
|
||||
p.containerClass = {}
|
||||
p.container = {}
|
||||
|
||||
local container = p.container
|
||||
|
||||
|
||||
|
||||
-- The master list of registered container classes
|
||||
|
||||
container._classes = {}
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- The metatable allows container functions to be called with the ":" syntax,
|
||||
-- and also allows API field values to be get and set as if they were direct
|
||||
-- properties.
|
||||
--
|
||||
-- TODO: I think I'd like to get away from treating the fields as direct
|
||||
-- properties on the containers (fine on the baked contexts later) and require
|
||||
-- explicit fetch() and store() calls instead.
|
||||
---
|
||||
|
||||
p.containerClass.__index = p.containerClass
|
||||
|
||||
p.container.__index = function(c, key)
|
||||
local f = p.field.get(key)
|
||||
if f then
|
||||
return p.configset.fetch(c, f)
|
||||
else
|
||||
return p.container[key]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
p.container.__newindex = function(c, key, value)
|
||||
local f = p.field.get(key)
|
||||
if f then
|
||||
local status, err = p.configset.store(c, f, value)
|
||||
if err then
|
||||
error(err, 2)
|
||||
end
|
||||
else
|
||||
rawset(c, key, value)
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- A container class holds and operates on the metadata about a particular
|
||||
-- type of container, including its name, parent container, and any child
|
||||
-- containers. The container class is responsible for creating new instances
|
||||
-- of its kind of containers.
|
||||
--
|
||||
-- @param def
|
||||
-- A table containing metadata about the container class being created.
|
||||
-- Supported keys are:
|
||||
--
|
||||
-- name (required)
|
||||
-- The name of the new container class (e.g. "solution").
|
||||
-- parent (optional)
|
||||
-- The name of the parent container class (e.g. "solution").
|
||||
-- init (optional)
|
||||
-- An initializer function to call for new instances of this class.
|
||||
-- Should accept the new instance object as its only argument.
|
||||
--
|
||||
-- Other keys are allowed and will be left intact.
|
||||
--
|
||||
-- @return
|
||||
-- A new container class object if successful, else nil and an
|
||||
-- error message.
|
||||
---
|
||||
|
||||
function p.containerClass.define(def)
|
||||
-- If the class has no special properties, allow it to be set using
|
||||
-- just the class name instead of the whole key-value list.
|
||||
|
||||
if type(def) == "string" then
|
||||
def = { name = def }
|
||||
end
|
||||
|
||||
-- Sanity check my inputs
|
||||
|
||||
if not def.name then
|
||||
return nil, "name is required"
|
||||
end
|
||||
|
||||
if container._classes[def.name] then
|
||||
return nil, "container class name already in use"
|
||||
end
|
||||
|
||||
if def.parent and not container._classes[def.parent] then
|
||||
return nil, "parent class does not exist"
|
||||
end
|
||||
|
||||
-- Looks good, set myself up and add to master list
|
||||
|
||||
def._children = {}
|
||||
def._listKey = def.name:plural()
|
||||
setmetatable(def, p.containerClass)
|
||||
container._classes[def.name] = def
|
||||
|
||||
-- Wire myself to my parent class
|
||||
|
||||
def.parent = container._classes[def.parent]
|
||||
if def.parent then
|
||||
table.insert(def.parent._children, def)
|
||||
end
|
||||
|
||||
return def
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Enumerate the child container class of a given class.
|
||||
---
|
||||
|
||||
function p.containerClass:eachChildClass()
|
||||
local children = self._children
|
||||
local i = 0
|
||||
return function ()
|
||||
i = i + 1
|
||||
if i <= #children then
|
||||
return children[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve a container class by name.
|
||||
--
|
||||
-- @param name
|
||||
-- The class name.
|
||||
-- @return
|
||||
-- The corresponding container class if found, nil otherwise.
|
||||
---
|
||||
|
||||
function p.containerClass.get(name)
|
||||
return container._classes[name]
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Create a new instance of a container class.
|
||||
--
|
||||
-- @param name
|
||||
-- The name for the container instance.
|
||||
-- @return
|
||||
-- A new instance of the container class.
|
||||
---
|
||||
|
||||
function p.containerClass:new(name, parent)
|
||||
local c = p.configset.new(parent)
|
||||
setmetatable(c, p.container)
|
||||
|
||||
c.class = self
|
||||
c.name = name
|
||||
c.script = _SCRIPT
|
||||
c.basedir = os.getcwd()
|
||||
c.filename = name
|
||||
|
||||
if type(self.init) == "function" then
|
||||
self.init(c)
|
||||
end
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Create a new child container of the given class, with the specified name.
|
||||
--
|
||||
-- @param cc
|
||||
-- The class of child container to be fetched.
|
||||
-- @param key
|
||||
-- A string key or array index for the container.
|
||||
-- @param parent
|
||||
-- The parent container instance.
|
||||
-- @return
|
||||
-- The child container instance.
|
||||
---
|
||||
|
||||
function container:createChild(cc, key, parent)
|
||||
self[cc._listKey] = self[cc._listKey] or {}
|
||||
local list = self[cc._listKey]
|
||||
|
||||
local child = cc:new(key, parent)
|
||||
child[parent.class.name] = parent -- i.e. child.solution = sln
|
||||
|
||||
table.insert(list, child)
|
||||
list[key] = child
|
||||
return child
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Return an iterator for the child containers of a particular class.
|
||||
--
|
||||
-- @param cc
|
||||
-- The class of child container to be enumerated.
|
||||
---
|
||||
|
||||
function container:eachChild(cc)
|
||||
local children = self[cc._listKey] or {}
|
||||
local i = 0
|
||||
return function ()
|
||||
i = i + 1
|
||||
if i <= #children then
|
||||
return children[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Fetch the child container with the given container class and instance name.
|
||||
--
|
||||
-- @param cc
|
||||
-- The class of child container to be fetched.
|
||||
-- @param key
|
||||
-- A string key or array index for the container.
|
||||
-- @return
|
||||
-- The child container instance.
|
||||
---
|
||||
|
||||
function container:fetchChild(cc, key)
|
||||
self[cc._listKey] = self[cc._listKey] or {}
|
||||
return self[cc._listKey][key]
|
||||
end
|
@ -81,6 +81,13 @@
|
||||
|
||||
f._kind = kind
|
||||
|
||||
-- Make sure scope is always an array; don't overwrite old value
|
||||
if type(f.scope) == "table" then
|
||||
f.scopes = f.scope
|
||||
else
|
||||
f.scopes = { f.scope }
|
||||
end
|
||||
|
||||
-- All fields must have a valid store() function
|
||||
if not field.accessor(f, "store") then
|
||||
return nil, "invalid field kind '" .. f._kind .. "'"
|
||||
@ -250,6 +257,7 @@
|
||||
end
|
||||
|
||||
|
||||
|
||||
function field.merge(f, current, value)
|
||||
local processor = field.accessor(f, "merge")
|
||||
if processor then
|
||||
|
@ -6,9 +6,10 @@
|
||||
|
||||
premake.fileconfig = {}
|
||||
|
||||
local fileconfig = premake.fileconfig
|
||||
local context = premake.context
|
||||
local project = premake.project
|
||||
local p = premake
|
||||
local fileconfig = p.fileconfig
|
||||
local context = p.context
|
||||
local project = p.project
|
||||
|
||||
|
||||
--
|
||||
@ -171,7 +172,7 @@
|
||||
|
||||
function fileconfig.hasFileSettings(fcfg)
|
||||
for key, field in pairs(premake.fields) do
|
||||
if field.scope == "config" then
|
||||
if field.scopes[1] == "config" then
|
||||
local value = fcfg[field.name]
|
||||
if value then
|
||||
if type(value) == "table" then
|
||||
|
@ -10,29 +10,41 @@
|
||||
--
|
||||
|
||||
premake.oven = {}
|
||||
|
||||
local oven = premake.oven
|
||||
local solution = premake.solution
|
||||
local project = premake.project
|
||||
local config = premake.config
|
||||
local fileconfig = premake.fileconfig
|
||||
local configset = premake.configset
|
||||
local context = premake.context
|
||||
|
||||
local p = premake
|
||||
local solution = p.solution
|
||||
local project = p.project
|
||||
local config = p.config
|
||||
local fileconfig = p.fileconfig
|
||||
local configset = p.configset
|
||||
local context = p.context
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Traverses the entire container hierarchy built up by the project scripts,
|
||||
-- filters, merges, and munges the project settings based on the current
|
||||
-- runtime environment, and returns a new container hierarchy with the end
|
||||
-- result. This result will then get handed off to the current action to
|
||||
-- do whatever it is it needs to do, like generate project files.
|
||||
--
|
||||
-- Iterates through all of the current solutions, bakes down their contents,
|
||||
-- and then replaces the original solution object with the baked result.
|
||||
-- This is the entry point to the whole baking process, which happens after
|
||||
-- the scripts have run, but before the project files are generated.
|
||||
--
|
||||
-- @param root
|
||||
-- The top level or root container to be baked.
|
||||
-- @return
|
||||
-- ???
|
||||
---
|
||||
|
||||
function oven.bake()
|
||||
function oven.bake(root)
|
||||
local result = {}
|
||||
for i, sln in ipairs(solution.list) do
|
||||
|
||||
local root = p.api.rootContainer()
|
||||
root.solutions = root.solutions or {}
|
||||
for i, sln in ipairs(root.solutions) do
|
||||
result[i] = oven.bakeSolution(sln)
|
||||
end
|
||||
solution.list = result
|
||||
|
||||
root.solutions = result
|
||||
end
|
||||
|
||||
|
||||
@ -94,6 +106,7 @@
|
||||
-- store that for future reference
|
||||
|
||||
local projects = {}
|
||||
sln.projects = sln.projects or {}
|
||||
for i, prj in ipairs(sln.projects) do
|
||||
projects[i] = oven.bakeProject(prj, ctx)
|
||||
projects[prj.name] = projects[i]
|
||||
|
@ -169,6 +169,16 @@
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Is this a type of file that can be linked?
|
||||
---
|
||||
|
||||
function path.islinkable(fname)
|
||||
return path.hasextension(fname, { ".o", ".obj", ".a", ".lib", ".so" })
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Returns true if the filename represents an object file.
|
||||
--
|
||||
|
@ -7,6 +7,8 @@
|
||||
local solution = premake.solution
|
||||
local project = premake.project
|
||||
local config = premake.config
|
||||
local field = premake.field
|
||||
|
||||
|
||||
|
||||
-- Store captured output text for later testing
|
||||
@ -135,7 +137,7 @@
|
||||
-- Used by the actions to generate solution and project files.
|
||||
--
|
||||
-- @param obj
|
||||
-- A solution or project object; will be based to the callback function.
|
||||
-- A solution or project object; will be passed to the callback function.
|
||||
-- @param ext
|
||||
-- An optional extension for the generated file, with the leading dot.
|
||||
-- @param callback
|
||||
@ -144,7 +146,7 @@
|
||||
--
|
||||
|
||||
function premake.generate(obj, ext, callback)
|
||||
local fn = premake.project.getfilename(obj, ext)
|
||||
local fn = premake.filename(obj, ext)
|
||||
printf("Generating %s...", path.getrelative(os.getcwd(), fn))
|
||||
|
||||
local f, err = io.open(fn, "wb")
|
||||
@ -160,6 +162,34 @@
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Returns the full path a file generated from any of the project
|
||||
-- objects (project, solution, rule).
|
||||
--
|
||||
-- @param obj
|
||||
-- The project object being generated.
|
||||
-- @param ext
|
||||
-- An optional extension for the generated file, with the leading dot.
|
||||
-- @param callback
|
||||
-- The function responsible for writing the file; will receive the
|
||||
-- project object as its only argument.
|
||||
---
|
||||
|
||||
function premake.filename(obj, ext)
|
||||
local fname = obj.location
|
||||
if ext and not ext:startswith(".") then
|
||||
fname = path.join(fname, ext)
|
||||
else
|
||||
fname = path.join(fname, obj.filename)
|
||||
if ext then
|
||||
fname = fname .. ext
|
||||
end
|
||||
end
|
||||
return fname
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Sets the output indentation parameters.
|
||||
--
|
||||
@ -380,23 +410,28 @@
|
||||
--
|
||||
|
||||
function premake.validateScopes(cfg, expected, ctx)
|
||||
for name, field in pairs(premake.fields) do
|
||||
local okay = false
|
||||
|
||||
-- skip fields that are at or below the expected scope
|
||||
if field.scope == "config" or field.scope == expected then
|
||||
okay = true
|
||||
for f in field.each() do
|
||||
-- Pull out the project level scope (this will get cleaned up when
|
||||
-- the project objects move to the new container API)
|
||||
local scope
|
||||
if f.scopes[1] ~= "rule" then
|
||||
scope = f.scopes[1]
|
||||
end
|
||||
|
||||
-- Skip fields that are at or below the expected scope. Config-
|
||||
-- level fields are the most general (can be applied to projects
|
||||
-- or solutions) and so can never be out of scope.
|
||||
local okay = (not scope or scope == "config" or scope == expected)
|
||||
|
||||
-- this one needs to checked
|
||||
if not okay then
|
||||
okay = premake.field.compare(field, cfg[field.scope][name], cfg[name])
|
||||
okay = field.compare(f, cfg[scope][f.name], cfg[f.name])
|
||||
end
|
||||
|
||||
-- found a problem?
|
||||
if not okay then
|
||||
local key = "validate." .. field.name
|
||||
premake.warnOnce(key, "'%s' on %s '%s' differs from %s '%s'; may be set out of scope", name, expected, cfg.name, field.scope, cfg[field.scope].name)
|
||||
local key = "validate." .. f.name
|
||||
premake.warnOnce(key, "'%s' on %s '%s' differs from %s '%s'; may be set out of scope", f.name, expected, cfg.name, scope, cfg[scope].name)
|
||||
end
|
||||
|
||||
end
|
||||
@ -435,6 +470,18 @@
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Write a opening XML element for a UTF-8 encoded file. Used by
|
||||
-- several different files for different actions, so makes sense
|
||||
-- to have a common call for it.
|
||||
---
|
||||
|
||||
function premake.xmlUtf8()
|
||||
premake.outln('<?xml version="1.0" encoding="utf-8"?>')
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- These are the output shortcuts that I used before switching to the
|
||||
-- indentation-aware calls above. They are still in use all over the
|
||||
|
@ -6,35 +6,29 @@
|
||||
|
||||
premake.project = {}
|
||||
local project = premake.project
|
||||
local configset = premake.configset
|
||||
local context = premake.context
|
||||
local tree = premake.tree
|
||||
|
||||
local p = premake
|
||||
local tree = p.tree
|
||||
|
||||
|
||||
--
|
||||
-- Create a new project object.
|
||||
--
|
||||
-- @param sln
|
||||
-- The solution object to contain the new project.
|
||||
-- @param name
|
||||
-- The new project's name.
|
||||
-- @return
|
||||
-- A new project object, contained by the specified solution.
|
||||
--
|
||||
|
||||
function project.new(sln, name)
|
||||
local prj = configset.new(sln)
|
||||
setmetatable(prj, configset.metatable(prj))
|
||||
---
|
||||
-- Register a new container class to represent projects.
|
||||
---
|
||||
|
||||
prj.name = name
|
||||
prj.solution = sln
|
||||
prj.script = _SCRIPT
|
||||
prj.basedir = os.getcwd()
|
||||
prj.filename = name
|
||||
prj.uuid = os.uuid(name)
|
||||
local _prjClass = p.api.container {
|
||||
name = "project",
|
||||
parent = "solution",
|
||||
init = function(prj)
|
||||
prj.uuid = os.uuid(prj.name)
|
||||
if p.api.scope.group then
|
||||
prj.group = p.api.scope.group.name
|
||||
else
|
||||
prj.group = ""
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
return prj
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
@ -210,32 +204,17 @@
|
||||
|
||||
|
||||
|
||||
--
|
||||
---
|
||||
-- Returns the file name for this project. Also works with solutions.
|
||||
--
|
||||
-- @param prj
|
||||
-- The project object to query.
|
||||
-- @param ext
|
||||
-- An optional file extension to add, with the leading dot. If provided
|
||||
-- without a leading dot, it will treated as a file name.
|
||||
-- @return
|
||||
-- The absolute path to the project's file.
|
||||
--
|
||||
-- Deprecated 11 Aug 2014
|
||||
---
|
||||
|
||||
function project.getfilename(prj, ext)
|
||||
local fn = prj.location
|
||||
if ext and not ext:startswith(".") then
|
||||
fn = path.join(fn, ext)
|
||||
else
|
||||
fn = path.join(fn, prj.filename)
|
||||
if ext then
|
||||
fn = fn .. ext
|
||||
end
|
||||
end
|
||||
return fn
|
||||
return premake.filename(prj, ext)
|
||||
end
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Return the first configuration of a project, which is used in some
|
||||
-- actions to generate project-wide defaults.
|
||||
|
50
src/base/rules.lua
Normal file
50
src/base/rules.lua
Normal file
@ -0,0 +1,50 @@
|
||||
---
|
||||
-- base/rules.lua
|
||||
--
|
||||
-- Defines rule sets for generated custom rule files.
|
||||
--
|
||||
-- Copyright (c) 2014 Jason Perkins and the Premake project
|
||||
---
|
||||
|
||||
premake.rules = {}
|
||||
local rules = premake.rules
|
||||
|
||||
local p = premake
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Register a new container class to hold the rules.
|
||||
---
|
||||
|
||||
local _ruleContainerClass = p.api.container {
|
||||
name = "rule",
|
||||
}
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Iterate over the collection of rules in a session.
|
||||
--
|
||||
-- @returns
|
||||
-- An iterator function.
|
||||
---
|
||||
|
||||
function rules.each()
|
||||
return p.api.rootContainer():eachChild(_ruleContainerClass)
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve a rule set by name or numeric index.
|
||||
--
|
||||
-- @param key
|
||||
-- The rule key, either a string name or integer index.
|
||||
-- @returns
|
||||
-- The rule set with the provided key.
|
||||
---
|
||||
|
||||
function rules.fetch(key)
|
||||
return p.api.rootContainer():fetchChild(_ruleContainerClass, key)
|
||||
end
|
@ -6,41 +6,26 @@
|
||||
|
||||
premake.solution = {}
|
||||
local solution = premake.solution
|
||||
local project = premake.project
|
||||
local configset = premake.configset
|
||||
local context = premake.context
|
||||
local tree = premake.tree
|
||||
|
||||
local p = premake
|
||||
local tree = p.tree
|
||||
|
||||
|
||||
-- The list of defined solutions (which contain projects, etc.)
|
||||
|
||||
solution.list = {}
|
||||
---
|
||||
-- Register a new container class to represent solutions.
|
||||
---
|
||||
|
||||
local _slnClass = p.api.container {
|
||||
name = "solution",
|
||||
}
|
||||
|
||||
--
|
||||
-- Create a new solution and add it to the session.
|
||||
--
|
||||
-- @param name
|
||||
-- The new solution's name.
|
||||
-- @return
|
||||
-- A new solution object.
|
||||
--
|
||||
p.api.container {
|
||||
name = "group",
|
||||
parent = "solution",
|
||||
placeholder = true,
|
||||
}
|
||||
|
||||
function solution.new(name)
|
||||
sln = configset.new(configset.root)
|
||||
setmetatable(sln, configset.metatable(sln))
|
||||
|
||||
sln.name = name
|
||||
sln.projects = {}
|
||||
sln.basedir = os.getcwd()
|
||||
sln.filename = name
|
||||
|
||||
-- Add to master list keyed by both name and index
|
||||
table.insert(premake.solution.list, sln)
|
||||
premake.solution.list[name] = sln
|
||||
|
||||
return sln
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
@ -67,11 +52,13 @@
|
||||
--
|
||||
|
||||
function solution.each()
|
||||
local root = p.api.rootContainer()
|
||||
|
||||
local i = 0
|
||||
return function ()
|
||||
i = i + 1
|
||||
if i <= #premake.solution.list then
|
||||
return premake.solution.list[i]
|
||||
if i <= #root.solutions then
|
||||
return root.solutions[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -153,24 +140,13 @@
|
||||
--
|
||||
|
||||
function solution.get(key)
|
||||
return premake.solution.list[key]
|
||||
local root = p.api.rootContainer()
|
||||
if root.solutions then
|
||||
return root.solutions[key]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Returns the file name for this solution.
|
||||
--
|
||||
-- @param sln
|
||||
-- The solution object to query.
|
||||
-- @param ext
|
||||
-- An optional file extension to add, with the leading dot.
|
||||
-- @return
|
||||
-- The absolute path to the solution's file.
|
||||
--
|
||||
|
||||
|
||||
solution.getfilename = project.getfilename
|
||||
|
||||
|
||||
--
|
||||
-- Retrieve the tree of project groups.
|
||||
@ -237,7 +213,7 @@
|
||||
|
||||
function solution.hascppproject(sln)
|
||||
for prj in solution.eachproject(sln) do
|
||||
if project.iscpp(prj) then
|
||||
if p.project.iscpp(prj) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
@ -258,7 +234,7 @@
|
||||
|
||||
function solution.hasdotnetproject(sln)
|
||||
for prj in solution.eachproject(sln) do
|
||||
if project.isdotnet(prj) then
|
||||
if p.project.isdotnet(prj) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
@ -61,3 +61,17 @@
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Return a plural version of a string.
|
||||
---
|
||||
|
||||
function string:plural()
|
||||
if self:endswith("y") then
|
||||
return self:sub(1, #self - 1) .. "ies"
|
||||
else
|
||||
return self .. "s"
|
||||
end
|
||||
end
|
||||
|
@ -1,13 +1,13 @@
|
||||
--
|
||||
-- tests/project/test_filename.lua
|
||||
-- Verify generation of project (and solution) filenames.
|
||||
-- Copyright (c) 2008-2012 Jason Perkins and the Premake project
|
||||
-- tests/base/test_filename.lua
|
||||
-- Verify generation of project/solution/rule filenames.
|
||||
-- Copyright (c) 2008-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
T.project_filename = {}
|
||||
local suite = T.project_filename
|
||||
local suite = test.declare("project_filename")
|
||||
|
||||
local p = premake
|
||||
|
||||
local project = premake.project
|
||||
|
||||
|
||||
--
|
||||
@ -17,11 +17,11 @@
|
||||
local sln
|
||||
|
||||
function suite.setup()
|
||||
sln, prj = test.createsolution()
|
||||
sln = test.createsolution()
|
||||
end
|
||||
|
||||
local function prepare()
|
||||
prj = premake.solution.getproject(sln, 1)
|
||||
prj = test.getproject(sln, 1)
|
||||
end
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
|
||||
function suite.isAbsolutePath()
|
||||
prepare()
|
||||
test.isequal(os.getcwd(), path.getdirectory(project.getfilename(prj)))
|
||||
test.isequal(os.getcwd(), path.getdirectory(p.filename(prj)))
|
||||
end
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
|
||||
function suite.isProjectName_onNoFilename()
|
||||
prepare()
|
||||
test.isequal("MyProject", path.getname(project.getfilename(prj)))
|
||||
test.isequal("MyProject", path.getname(p.filename(prj)))
|
||||
end
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@
|
||||
function suite.doesUseFilename()
|
||||
filename "Howdy"
|
||||
prepare()
|
||||
test.isequal("Howdy", path.getname(project.getfilename(prj)))
|
||||
test.isequal("Howdy", path.getname(p.filename(prj)))
|
||||
end
|
||||
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
|
||||
function suite.doesUseExtension()
|
||||
prepare()
|
||||
test.isequal(".xc", path.getextension(project.getfilename(prj, ".xc")))
|
||||
test.isequal(".xc", path.getextension(p.filename(prj, ".xc")))
|
||||
end
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@
|
||||
|
||||
function suite.worksWithSolution()
|
||||
prepare()
|
||||
test.isequal("MySolution", path.getname(project.getfilename(sln)))
|
||||
test.isequal("MySolution", path.getname(p.filename(sln)))
|
||||
end
|
||||
|
||||
|
||||
@ -84,7 +84,7 @@
|
||||
solution ("MySolution")
|
||||
filename ("Howdy")
|
||||
prepare()
|
||||
test.isequal("MyProject", path.getname(project.getfilename(prj)))
|
||||
test.isequal("MyProject", path.getname(p.filename(prj)))
|
||||
end
|
||||
|
||||
|
||||
@ -95,6 +95,5 @@
|
||||
|
||||
function suite.canOverrideFilename()
|
||||
prepare()
|
||||
test.isequal("Makefile", path.getname(project.getfilename(prj, "Makefile")))
|
||||
test.isequal("Makefile", path.getname(p.filename(prj, "Makefile")))
|
||||
end
|
||||
|
@ -83,38 +83,16 @@
|
||||
-- Warn if a configuration value is set in the wrong scope.
|
||||
--
|
||||
|
||||
function suite.warns_onSolutionStringField_inProject()
|
||||
solution "MySolution"
|
||||
configurations { "Debug", "Release" }
|
||||
project "MyProject"
|
||||
kind "ConsoleApp"
|
||||
language "C++"
|
||||
startproject "MyProject"
|
||||
premake.validate()
|
||||
test.stderr("'startproject' on project")
|
||||
end
|
||||
|
||||
function suite.warns_onSolutionStringField_inConfig()
|
||||
solution "MySolution"
|
||||
configurations { "Debug", "Release" }
|
||||
project "MyProject"
|
||||
kind "ConsoleApp"
|
||||
language "C++"
|
||||
filter "Debug"
|
||||
startproject "MyProject"
|
||||
premake.validate()
|
||||
test.stderr("'startproject' on config")
|
||||
end
|
||||
|
||||
function suite.warns_onSolutionStringField_onlyWarnOnce()
|
||||
solution "MySolution"
|
||||
configurations { "Debug", "Release" }
|
||||
project "MyProject"
|
||||
kind "ConsoleApp"
|
||||
language "C++"
|
||||
startproject "MyProject"
|
||||
premake.validate()
|
||||
test.notstderr("'startproject' on config")
|
||||
test.stderr("'startproject' on config")
|
||||
end
|
||||
|
||||
function suite.warns_onProjectStringField_inConfig()
|
||||
|
230
tests/premake5.lua
Normal file
230
tests/premake5.lua
Normal file
@ -0,0 +1,230 @@
|
||||
--
|
||||
-- tests/premake5.lua
|
||||
-- Automated test suite for Premake 5.x
|
||||
-- Copyright (c) 2008-2013 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
dofile("testfx.lua")
|
||||
|
||||
newoption {
|
||||
trigger = "test",
|
||||
description = "A suite or test to run"
|
||||
}
|
||||
|
||||
newoption {
|
||||
trigger = "profile",
|
||||
description = "Profile execution times; saves to profile.txt"
|
||||
}
|
||||
|
||||
if _OPTIONS["profile"] then
|
||||
dofile("pepperfish_profiler.lua")
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- The test suites
|
||||
--
|
||||
|
||||
-- Base API tests
|
||||
dofile("test_dofile.lua")
|
||||
dofile("test_string.lua")
|
||||
|
||||
dofile("base/test_configset.lua")
|
||||
dofile("base/test_context.lua")
|
||||
dofile("base/test_criteria.lua")
|
||||
dofile("base/test_detoken.lua")
|
||||
dofile("base/test_filename.lua")
|
||||
dofile("base/test_include.lua")
|
||||
dofile("base/test_option.lua")
|
||||
dofile("base/test_os.lua")
|
||||
dofile("base/test_override.lua")
|
||||
dofile("base/test_path.lua")
|
||||
dofile("base/test_premake_command.lua")
|
||||
dofile("base/test_table.lua")
|
||||
dofile("base/test_tree.lua")
|
||||
dofile("base/test_uuid.lua")
|
||||
|
||||
-- Solution object tests
|
||||
dofile("solution/test_eachconfig.lua")
|
||||
dofile("solution/test_location.lua")
|
||||
dofile("solution/test_objdirs.lua")
|
||||
|
||||
-- Project object tests
|
||||
dofile("project/test_config_maps.lua")
|
||||
dofile("project/test_eachconfig.lua")
|
||||
dofile("project/test_getconfig.lua")
|
||||
dofile("project/test_location.lua")
|
||||
dofile("project/test_vpaths.lua")
|
||||
|
||||
-- Configuration object tests
|
||||
dofile("config/test_linkinfo.lua")
|
||||
dofile("config/test_links.lua")
|
||||
dofile("config/test_targetinfo.lua")
|
||||
|
||||
-- Baking tests
|
||||
dofile("oven/test_filtering.lua")
|
||||
dofile("oven/test_objdirs.lua")
|
||||
|
||||
-- API tests
|
||||
dofile("api/test_containers.lua")
|
||||
dofile("api/test_directory_kind.lua")
|
||||
dofile("api/test_list_kind.lua")
|
||||
dofile("api/test_path_kind.lua")
|
||||
dofile("api/test_register.lua")
|
||||
dofile("api/test_string_kind.lua")
|
||||
dofile("api/test_table_kind.lua")
|
||||
|
||||
-- Control system tests
|
||||
dofile("test_premake.lua")
|
||||
dofile("base/test_validation.lua")
|
||||
|
||||
-- Toolset tests
|
||||
dofile("tools/test_dotnet.lua")
|
||||
dofile("tools/test_gcc.lua")
|
||||
dofile("tools/test_msc.lua")
|
||||
dofile("tools/test_snc.lua")
|
||||
|
||||
-- Visual Studio 2005-2010 C# projects
|
||||
dofile("actions/vstudio/cs2005/test_assembly_refs.lua")
|
||||
dofile("actions/vstudio/cs2005/test_build_events.lua")
|
||||
dofile("actions/vstudio/cs2005/test_compiler_props.lua")
|
||||
dofile("actions/vstudio/cs2005/test_debug_props.lua")
|
||||
dofile("actions/vstudio/cs2005/test_files.lua")
|
||||
dofile("actions/vstudio/cs2005/test_icon.lua")
|
||||
dofile("actions/vstudio/cs2005/test_output_props.lua")
|
||||
dofile("actions/vstudio/cs2005/projectelement.lua")
|
||||
dofile("actions/vstudio/cs2005/test_platform_groups.lua")
|
||||
dofile("actions/vstudio/cs2005/test_project_refs.lua")
|
||||
dofile("actions/vstudio/cs2005/projectsettings.lua")
|
||||
|
||||
-- Visual Studio 2005-2010 solutions
|
||||
dofile("actions/vstudio/sln2005/test_dependencies.lua")
|
||||
dofile("actions/vstudio/sln2005/test_header.lua")
|
||||
dofile("actions/vstudio/sln2005/test_nested_projects.lua")
|
||||
dofile("actions/vstudio/sln2005/test_projects.lua")
|
||||
dofile("actions/vstudio/sln2005/test_platforms.lua")
|
||||
|
||||
-- Visual Studio 2002-2008 C/C++ projects
|
||||
dofile("actions/vstudio/vc200x/test_assembly_refs.lua")
|
||||
dofile("actions/vstudio/vc200x/test_build_steps.lua")
|
||||
dofile("actions/vstudio/vc200x/test_configuration.lua")
|
||||
dofile("actions/vstudio/vc200x/test_compiler_block.lua")
|
||||
dofile("actions/vstudio/vc200x/test_debug_settings.lua")
|
||||
dofile("actions/vstudio/vc200x/test_excluded_configs.lua")
|
||||
dofile("actions/vstudio/vc200x/test_external_compiler.lua")
|
||||
dofile("actions/vstudio/vc200x/test_external_linker.lua")
|
||||
dofile("actions/vstudio/vc200x/test_files.lua")
|
||||
dofile("actions/vstudio/vc200x/test_linker_block.lua")
|
||||
dofile("actions/vstudio/vc200x/test_manifest_block.lua")
|
||||
dofile("actions/vstudio/vc200x/test_nmake_settings.lua")
|
||||
dofile("actions/vstudio/vc200x/test_platforms.lua")
|
||||
dofile("actions/vstudio/vc200x/test_project.lua")
|
||||
dofile("actions/vstudio/vc200x/test_project_refs.lua")
|
||||
dofile("actions/vstudio/vc200x/test_resource_compiler.lua")
|
||||
|
||||
-- Visual Studio 2010 C/C++ projects
|
||||
dofile("actions/vstudio/vc2010/test_assembly_refs.lua")
|
||||
dofile("actions/vstudio/vc2010/test_build_events.lua")
|
||||
dofile("actions/vstudio/vc2010/test_compile_settings.lua")
|
||||
dofile("actions/vstudio/vc2010/test_config_props.lua")
|
||||
dofile("actions/vstudio/vc2010/test_debug_settings.lua")
|
||||
dofile("actions/vstudio/vc2010/test_excluded_configs.lua")
|
||||
dofile("actions/vstudio/vc2010/test_extension_settings.lua")
|
||||
dofile("actions/vstudio/vc2010/test_extension_targets.lua")
|
||||
dofile("actions/vstudio/vc2010/test_globals.lua")
|
||||
dofile("actions/vstudio/vc2010/test_header.lua")
|
||||
dofile("actions/vstudio/vc2010/test_files.lua")
|
||||
dofile("actions/vstudio/vc2010/test_filter_ids.lua")
|
||||
dofile("actions/vstudio/vc2010/test_filters.lua")
|
||||
dofile("actions/vstudio/vc2010/test_item_def_group.lua")
|
||||
dofile("actions/vstudio/vc2010/test_link.lua")
|
||||
dofile("actions/vstudio/vc2010/test_manifest.lua")
|
||||
dofile("actions/vstudio/vc2010/test_nmake_props.lua")
|
||||
dofile("actions/vstudio/vc2010/test_output_props.lua")
|
||||
dofile("actions/vstudio/vc2010/test_project_configs.lua")
|
||||
dofile("actions/vstudio/vc2010/test_project_refs.lua")
|
||||
dofile("actions/vstudio/vc2010/test_prop_sheet.lua")
|
||||
dofile("actions/vstudio/vc2010/test_resource_compile.lua")
|
||||
|
||||
-- Visual Studio 2012
|
||||
dofile("actions/vs2012/test_csproj_common_props.lua")
|
||||
dofile("actions/vs2012/test_csproj_project_element.lua")
|
||||
dofile("actions/vs2012/test_csproj_project_props.lua")
|
||||
dofile("actions/vs2012/test_csproj_targets.lua")
|
||||
dofile("actions/vs2012/test_sln_header.lua")
|
||||
dofile("actions/vs2012/test_vcxproj_clcompile.lua")
|
||||
dofile("actions/vs2012/test_vcxproj_config_props.lua")
|
||||
|
||||
-- Visual Studio 2013
|
||||
dofile("actions/vs2013/test_csproj_project_element.lua")
|
||||
dofile("actions/vs2013/test_globals.lua")
|
||||
dofile("actions/vs2013/test_sln_header.lua")
|
||||
dofile("actions/vs2013/test_vcxproj_config_props.lua")
|
||||
|
||||
-- Makefile tests
|
||||
dofile("actions/make/test_make_escaping.lua")
|
||||
dofile("actions/make/test_make_tovar.lua")
|
||||
|
||||
-- Makefile solutions
|
||||
dofile("actions/make/solution/test_config_maps.lua")
|
||||
dofile("actions/make/solution/test_default_config.lua")
|
||||
dofile("actions/make/solution/test_help_rule.lua")
|
||||
dofile("actions/make/solution/test_project_rule.lua")
|
||||
|
||||
-- Makefile C/C++ projects
|
||||
dofile("actions/make/cpp/test_clang.lua")
|
||||
dofile("actions/make/cpp/test_file_rules.lua")
|
||||
dofile("actions/make/cpp/test_flags.lua")
|
||||
dofile("actions/make/cpp/test_make_pch.lua")
|
||||
dofile("actions/make/cpp/test_make_linking.lua")
|
||||
dofile("actions/make/cpp/test_objects.lua")
|
||||
dofile("actions/make/cpp/test_ps3.lua")
|
||||
dofile("actions/make/cpp/test_target_rules.lua")
|
||||
dofile("actions/make/cpp/test_tools.lua")
|
||||
dofile("actions/make/cpp/test_wiidev.lua")
|
||||
|
||||
-- Makefile C# projects
|
||||
dofile("actions/make/cs/test_embed_files.lua")
|
||||
dofile("actions/make/cs/test_flags.lua")
|
||||
dofile("actions/make/cs/test_links.lua")
|
||||
dofile("actions/make/cs/test_response.lua")
|
||||
dofile("actions/make/cs/test_sources.lua")
|
||||
|
||||
|
||||
newaction {
|
||||
trigger = "test",
|
||||
description = "Run the automated test suite",
|
||||
|
||||
execute = function ()
|
||||
local focus = {}
|
||||
if _OPTIONS["test"] then
|
||||
focus = string.explode(_OPTIONS["test"] or "", ".", true)
|
||||
end
|
||||
|
||||
local profile = _OPTIONS["profile"]
|
||||
if profile == "" then profile = "time" end
|
||||
|
||||
local profiler
|
||||
if profile then
|
||||
profiler = newProfiler()
|
||||
profiler:start()
|
||||
end
|
||||
|
||||
passed, failed = test.runall(focus[1], focus[2])
|
||||
|
||||
if profile then
|
||||
profiler:stop()
|
||||
local outfile = io.open("profile.txt", "w+")
|
||||
profiler:report(outfile)
|
||||
outfile:close()
|
||||
end
|
||||
|
||||
msg = string.format("%d tests passed, %d failed", passed, failed)
|
||||
if (failed > 0) then
|
||||
print(msg)
|
||||
os.exit(5)
|
||||
else
|
||||
print(msg)
|
||||
end
|
||||
end
|
||||
}
|
@ -339,7 +339,6 @@
|
||||
|
||||
stderr_capture = nil
|
||||
|
||||
premake.solution.list = { }
|
||||
premake.clearWarnings()
|
||||
premake.eol("\n")
|
||||
premake.escaper(nil)
|
||||
|
Reference in New Issue
Block a user