Clean up rule container creation and usage
- Adds externalRule() to match rule() - Adds externalProject() as replacement for external() for consistency with rules - Adds rules() to associate rules (external or generated) with a project - Drops customRules(); use rules() on the project level instead
This commit is contained in:
parent
d73e9af2ed
commit
4af8eb44af
@ -162,13 +162,6 @@
|
||||
tokens = true,
|
||||
}
|
||||
|
||||
api.register {
|
||||
name = "customRules",
|
||||
scope = "project",
|
||||
kind = "list:file",
|
||||
tokens = true,
|
||||
}
|
||||
|
||||
api.register {
|
||||
name = "debugargs",
|
||||
scope = "config",
|
||||
@ -624,6 +617,12 @@
|
||||
tokens = true,
|
||||
}
|
||||
|
||||
api.register {
|
||||
name = "rules",
|
||||
scope = "project",
|
||||
kind = "list:string",
|
||||
}
|
||||
|
||||
api.register {
|
||||
name = "startproject",
|
||||
scope = "solution",
|
||||
|
@ -241,7 +241,7 @@
|
||||
m.elements.itemDefinitionGroup = function(cfg)
|
||||
if cfg.kind == p.UTILITY then
|
||||
return {
|
||||
m.customRuleVars,
|
||||
m.ruleVars,
|
||||
m.buildEvents,
|
||||
}
|
||||
else
|
||||
@ -253,7 +253,7 @@
|
||||
m.buildEvents,
|
||||
m.imageXex,
|
||||
m.deploy,
|
||||
m.customRuleVars,
|
||||
m.ruleVars,
|
||||
}
|
||||
end
|
||||
end
|
||||
@ -491,9 +491,9 @@
|
||||
-- Write out project-level custom rule variables.
|
||||
---
|
||||
|
||||
function m.customRuleVars(cfg)
|
||||
function m.ruleVars(cfg)
|
||||
local vars = p.api.getCustomVars()
|
||||
table.foreachi(cfg.project._customRules, function(rule)
|
||||
for rule in p.global.eachRule() do
|
||||
local contents = p.capture(function ()
|
||||
p.push()
|
||||
for _, var in ipairs(vars) do
|
||||
@ -515,11 +515,11 @@
|
||||
end)
|
||||
|
||||
if #contents > 0 then
|
||||
p.push('<%s>', rule)
|
||||
p.push('<%s>', rule.name)
|
||||
p.outln(contents)
|
||||
p.pop('</%s>', rule)
|
||||
p.pop('</%s>', rule.name)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -764,17 +764,21 @@
|
||||
|
||||
|
||||
function m.categorize(prj, file)
|
||||
-- If any configuration for this file uses a custom build step or a
|
||||
-- custom, externally defined rule, that's the category to use
|
||||
-- If any configuration for this file uses a custom build step,
|
||||
-- that's the category to use
|
||||
for cfg in project.eachconfig(prj) do
|
||||
local fcfg = fileconfig.getconfig(file, cfg)
|
||||
if fileconfig.hasCustomBuildRule(fcfg) then
|
||||
return "CustomBuild"
|
||||
elseif fcfg and fcfg._customRule then
|
||||
return fcfg._customRule
|
||||
end
|
||||
end
|
||||
|
||||
-- If there is a custom rule associated with it, use that
|
||||
local rule = p.global.getRuleForFile(file.name)
|
||||
if rule then
|
||||
return rule.name
|
||||
end
|
||||
|
||||
-- Otherwise use the file extension to deduce a category
|
||||
if path.iscppfile(file.name) then
|
||||
return "ClCompile"
|
||||
@ -1155,11 +1159,13 @@
|
||||
function m.importExtensionTargets(prj)
|
||||
p.w('<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.targets" />')
|
||||
p.push('<ImportGroup Label="ExtensionTargets">')
|
||||
table.foreachi(prj.customRules, function(value)
|
||||
value = path.translate(project.getrelative(prj, value))
|
||||
value = path.appendExtension(value, ".targets")
|
||||
p.x('<Import Project="%s" />', value)
|
||||
end)
|
||||
|
||||
for i = 1, #prj.rules do
|
||||
local rule = p.global.getRule(prj.rules[i])
|
||||
local loc = project.getrelative(prj, premake.filename(rule, ".targets"))
|
||||
p.x('<Import Project="%s" />', path.translate(loc))
|
||||
end
|
||||
|
||||
p.pop('</ImportGroup>')
|
||||
end
|
||||
|
||||
@ -1174,11 +1180,13 @@
|
||||
function m.importExtensionSettings(prj)
|
||||
p.w('<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props" />')
|
||||
p.push('<ImportGroup Label="ExtensionSettings">')
|
||||
table.foreachi(prj.customRules, function(value)
|
||||
value = path.translate(project.getrelative(prj, value))
|
||||
value = path.appendExtension(value, ".props")
|
||||
p.x('<Import Project="%s" />', value)
|
||||
end)
|
||||
|
||||
for i = 1, #prj.rules do
|
||||
local rule = p.global.getRule(prj.rules[i])
|
||||
local loc = project.getrelative(prj, premake.filename(rule, ".props"))
|
||||
p.x('<Import Project="%s" />', path.translate(loc))
|
||||
end
|
||||
|
||||
p.pop('</ImportGroup>')
|
||||
end
|
||||
|
||||
|
@ -645,7 +645,8 @@
|
||||
---
|
||||
|
||||
function api.reset()
|
||||
-- Clear out all top level objects
|
||||
-- Clear out all top level objects, but keep the root config
|
||||
api.scope.global.rules = {}
|
||||
api.scope.global.solutions = {}
|
||||
|
||||
-- Remove all custom variables
|
||||
@ -1192,46 +1193,3 @@
|
||||
table.remove(value, 1)
|
||||
api._customVarFormats[name] = value
|
||||
end
|
||||
|
||||
|
||||
function customRule(value)
|
||||
-- Store the rule name in the current configuration, like a
|
||||
-- normal set-field operation would
|
||||
local fieldName = "_customRule"
|
||||
local field = premake.field.get(fieldName)
|
||||
if not field then
|
||||
field = premake.field.new {
|
||||
name = fieldName,
|
||||
scope = "config",
|
||||
kind = "string",
|
||||
}
|
||||
end
|
||||
api.callback(field, value)
|
||||
|
||||
-- Wild hack: I need a way to get all of the custom rule names that are
|
||||
-- in use within a project. The rule names are currently only associated
|
||||
-- with individual files. Rather than iterating over all the files after
|
||||
-- the fact, keep a master list of rule names in the first configuration
|
||||
-- block of the project. This way it will come out of the baking system
|
||||
-- looking like a normal list:string field.
|
||||
fieldName = "_customRules"
|
||||
field = premake.field.get(fieldName)
|
||||
if not field then
|
||||
field = premake.field.new {
|
||||
name = fieldName,
|
||||
scope = "config",
|
||||
kind = "list:string"
|
||||
}
|
||||
end
|
||||
|
||||
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)
|
||||
cset.current = current
|
||||
end
|
||||
|
@ -70,6 +70,7 @@
|
||||
|
||||
self.class = class
|
||||
self.name = name
|
||||
self.filename = name
|
||||
self.script = _SCRIPT
|
||||
self.basedir = os.getcwd()
|
||||
self.external = false
|
||||
|
@ -47,6 +47,43 @@
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve a rule by name or index.
|
||||
--
|
||||
-- @param key
|
||||
-- The rule key, either a string name or integer index.
|
||||
-- @returns
|
||||
-- The rule with the provided key.
|
||||
---
|
||||
|
||||
function global.getRule(key)
|
||||
local root = p.api.rootContainer()
|
||||
return root.rules[key]
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve the rule to applies to the provided file name, if any such
|
||||
-- rule exists.
|
||||
--
|
||||
-- @param fname
|
||||
-- The name of the file.
|
||||
-- @returns
|
||||
-- The rule, is one has been registered, or nil.
|
||||
---
|
||||
|
||||
function global.getRuleForFile(fname)
|
||||
local ext = path.getextension(fname):lower()
|
||||
for rule in global.eachRule() do
|
||||
if rule.fileExtension == ext then
|
||||
return rule
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- Retrieve a solution by name or index.
|
||||
--
|
||||
@ -58,7 +95,5 @@
|
||||
|
||||
function global.getSolution(key)
|
||||
local root = p.api.rootContainer()
|
||||
if root.solutions then
|
||||
return root.solutions[key]
|
||||
end
|
||||
return root.solutions[key]
|
||||
end
|
||||
|
@ -94,7 +94,6 @@
|
||||
-- to project configurations.
|
||||
|
||||
self.configs = oven.bakeConfigs(self)
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
@ -4,10 +4,12 @@
|
||||
-- Copyright (c) 2002-2014 Jason Perkins and the Premake project
|
||||
--
|
||||
|
||||
local solution = premake.solution
|
||||
local project = premake.project
|
||||
local config = premake.config
|
||||
local field = premake.field
|
||||
local p = premake
|
||||
|
||||
local solution = p.solution
|
||||
local project = p.project
|
||||
local config = p.config
|
||||
local field = p.field
|
||||
|
||||
|
||||
|
||||
@ -180,7 +182,7 @@
|
||||
---
|
||||
|
||||
function premake.filename(obj, ext)
|
||||
local fname = obj.location
|
||||
local fname = obj.location or obj.basedir
|
||||
if ext and not ext:startswith(".") then
|
||||
fname = path.join(fname, ext)
|
||||
else
|
||||
@ -367,6 +369,14 @@ end
|
||||
premake.error("project '%s' does not have a language", prj.name)
|
||||
end
|
||||
|
||||
-- all rules must exist
|
||||
for i = 1, #prj.rules do
|
||||
local rule = prj.rules[i]
|
||||
if not p.global.getRule(rule) then
|
||||
premake.error("project '%s' uses missing rule '%s'", prj.name, rule)
|
||||
end
|
||||
end
|
||||
|
||||
-- check for out of scope fields
|
||||
premake.validateScopes(prj, "project", ctx)
|
||||
end
|
||||
|
@ -28,7 +28,6 @@
|
||||
function project.new(name)
|
||||
local prj = p.container.new(project, name)
|
||||
prj.uuid = os.uuid(name)
|
||||
prj.filename = name
|
||||
|
||||
if p.api.scope.group then
|
||||
prj.group = p.api.scope.group.name
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
function solution.new(name)
|
||||
local sln = p.container.new(solution, name)
|
||||
sln.filename = name
|
||||
return sln
|
||||
end
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
local sln
|
||||
|
||||
function suite.setup()
|
||||
rule "MyRules"
|
||||
rule "MyOtherRules"
|
||||
sln = test.createsolution()
|
||||
end
|
||||
|
||||
@ -45,8 +47,7 @@
|
||||
--
|
||||
|
||||
function suite.addsImport_onEachRulesFile()
|
||||
customRules "MyRules"
|
||||
customRules "MyOtherRules"
|
||||
rules { "MyRules", "MyOtherRules" }
|
||||
prepare()
|
||||
test.capture [[
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
@ -63,13 +64,13 @@
|
||||
--
|
||||
|
||||
function suite.usesProjectRelativePaths()
|
||||
customRules "path/to/MyRules"
|
||||
rules "MyRules"
|
||||
location "build"
|
||||
prepare()
|
||||
test.capture [[
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="..\path\to\MyRules.props" />
|
||||
<Import Project="..\MyRules.props" />
|
||||
</ImportGroup>
|
||||
]]
|
||||
end
|
||||
|
@ -16,6 +16,8 @@
|
||||
local sln
|
||||
|
||||
function suite.setup()
|
||||
rule "MyRules"
|
||||
rule "MyOtherRules"
|
||||
sln = test.createsolution()
|
||||
end
|
||||
|
||||
@ -45,8 +47,7 @@
|
||||
--
|
||||
|
||||
function suite.addsImport_onEachRulesFile()
|
||||
customRules "MyRules"
|
||||
customRules "MyOtherRules"
|
||||
rules { "MyRules", "MyOtherRules" }
|
||||
prepare()
|
||||
test.capture [[
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
@ -63,13 +64,13 @@
|
||||
--
|
||||
|
||||
function suite.usesProjectRelativePaths()
|
||||
customRules "path/to/MyRules"
|
||||
rules { "MyRules" }
|
||||
location "build"
|
||||
prepare()
|
||||
test.capture [[
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\path\to\MyRules.targets" />
|
||||
<Import Project="..\MyRules.targets" />
|
||||
</ImportGroup>
|
||||
]]
|
||||
end
|
||||
|
@ -524,10 +524,12 @@
|
||||
|
||||
function suite.correctlyCategorized_onCustomRule()
|
||||
files { "hello.dae" }
|
||||
filter "files:**.dae"
|
||||
customRule "Animation"
|
||||
|
||||
rule "Animation"
|
||||
fileExtension ".dae"
|
||||
|
||||
prepare()
|
||||
test.capture [[
|
||||
test.capture [[
|
||||
<ItemGroup>
|
||||
<Animation Include="hello.dae" />
|
||||
</ItemGroup>
|
||||
@ -535,11 +537,14 @@
|
||||
end
|
||||
|
||||
|
||||
function suite.customRule_onLiteralVars()
|
||||
function suite.rule_onLiteralVars()
|
||||
files { "hello.dae" }
|
||||
filter "files:**.dae"
|
||||
customRule "Animation"
|
||||
customVar { "GenerateDebugInfo", "True" }
|
||||
|
||||
rule "Animation"
|
||||
fileExtension ".dae"
|
||||
|
||||
prepare()
|
||||
test.capture [[
|
||||
<ItemGroup>
|
||||
@ -552,12 +557,15 @@
|
||||
end
|
||||
|
||||
|
||||
function suite.customRule_onLiteralPath()
|
||||
function suite.rule_onLiteralPath()
|
||||
targetdir "../bin/%{cfg.buildcfg}"
|
||||
files { "hello.dae" }
|
||||
filter "files:**.dae"
|
||||
customRule "Animation"
|
||||
customVar { "OutputDirectory", "%{cfg.targetdir}/anim" }
|
||||
|
||||
rule "Animation"
|
||||
fileExtension ".dae"
|
||||
|
||||
prepare()
|
||||
test.capture [[
|
||||
<ItemGroup>
|
||||
@ -570,12 +578,14 @@
|
||||
end
|
||||
|
||||
|
||||
function suite.customRule_onPerConfigLiteralVars()
|
||||
function suite.rule_onPerConfigLiteralVars()
|
||||
files { "hello.dae" }
|
||||
filter { "files:**.dae" }
|
||||
customRule "Animation"
|
||||
filter { "files:**.dae", "configurations:Debug" }
|
||||
customVar { "GenerateDebugInfo", "True" }
|
||||
|
||||
rule "Animation"
|
||||
fileExtension ".dae"
|
||||
|
||||
prepare()
|
||||
test.capture [[
|
||||
<ItemGroup>
|
||||
@ -587,11 +597,14 @@
|
||||
end
|
||||
|
||||
|
||||
function suite.customRule_onListVars()
|
||||
function suite.rule_onListVars()
|
||||
files { "hello.dae" }
|
||||
filter "files:**.dae"
|
||||
customRule "Animation"
|
||||
customList { "ExtraDependencies", "File1", "File2" }
|
||||
|
||||
rule "Animation"
|
||||
fileExtension ".dae"
|
||||
|
||||
prepare()
|
||||
test.capture [[
|
||||
<ItemGroup>
|
||||
@ -604,13 +617,16 @@
|
||||
end
|
||||
|
||||
|
||||
function suite.customRule_onPerConfigListVars()
|
||||
function suite.rule_onPerConfigListVars()
|
||||
files { "hello.dae" }
|
||||
filter { "files:**.dae" }
|
||||
customRule "Animation"
|
||||
customList { "ExtraDependencies", "File1", "File2" }
|
||||
filter { "files:**.dae", "configurations:Release" }
|
||||
customList { "ExtraDependencies", "File3" }
|
||||
|
||||
rule "Animation"
|
||||
fileExtension ".dae"
|
||||
|
||||
prepare()
|
||||
test.capture [[
|
||||
<ItemGroup>
|
||||
@ -623,12 +639,15 @@
|
||||
end
|
||||
|
||||
|
||||
function suite.customRule_onListVarsWithCustomFormat()
|
||||
function suite.rule_onListVarsWithCustomFormat()
|
||||
files { "hello.dae" }
|
||||
filter "files:**.dae"
|
||||
customRule "Animation"
|
||||
customListFormat { "ExtraDependencies", ";" }
|
||||
customList { "ExtraDependencies", "File1", "File2" }
|
||||
|
||||
rule "Animation"
|
||||
fileExtension ".dae"
|
||||
|
||||
prepare()
|
||||
test.capture [[
|
||||
<ItemGroup>
|
||||
|
@ -172,8 +172,10 @@
|
||||
|
||||
function suite.filter_onCustomRule()
|
||||
files { "hello.dae" }
|
||||
filter "files:**.dae"
|
||||
customRule "Animation"
|
||||
|
||||
rule "Animation"
|
||||
fileExtension ".dae"
|
||||
|
||||
prepare()
|
||||
test.capture [[
|
||||
<ItemGroup>
|
||||
|
@ -130,3 +130,17 @@
|
||||
premake.validate()
|
||||
test.stderr("'configurations' on config")
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- If a rule is specified for inclusion, it must have been defined.
|
||||
--
|
||||
|
||||
function suite.fails_onNoSuchRule()
|
||||
solution "MySolution"
|
||||
configurations { "Debug", "Release" }
|
||||
project "MyProject"
|
||||
rules { "NoSuchRule" }
|
||||
test.isfalse(pcall(premake.validate))
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user