diff --git a/src/_manifest.lua b/src/_manifest.lua
index 2f1113b6..b0311bfe 100644
--- a/src/_manifest.lua
+++ b/src/_manifest.lua
@@ -41,7 +41,7 @@
"base/project.lua",
"base/config.lua",
"base/fileconfig.lua",
- "base/rules.lua",
+ "base/rule.lua",
-- project script processing
"base/oven.lua",
diff --git a/src/_premake_init.lua b/src/_premake_init.lua
index 8d149b42..9dbfc99d 100644
--- a/src/_premake_init.lua
+++ b/src/_premake_init.lua
@@ -130,18 +130,35 @@
tokens = true,
}
+
api.register {
name = "cleanExtensions",
scope = "config",
kind = "list:string",
}
+
+ api.register {
+ name = "clr",
+ scope = "config",
+ kind = "string",
+ allowed = {
+ "Off",
+ "On",
+ "Pure",
+ "Safe",
+ "Unsafe",
+ }
+ }
+
+
api.register {
name = "configmap",
scope = "config",
kind = "list:keyed:array:string",
}
+
api.register {
name = "configFile",
scope = "config",
@@ -162,13 +179,6 @@
tokens = true,
}
- api.register {
- name = "customRules",
- scope = "project",
- kind = "list:file",
- tokens = true,
- }
-
api.register {
name = "debugargs",
scope = "config",
@@ -241,6 +251,13 @@
}
+ api.register {
+ name = "editAndContinue",
+ scope = "config",
+ kind = "boolean",
+ }
+
+
-- For backward compatibility, excludes() is now an alias for removefiles()
function excludes(value)
removefiles(value)
@@ -285,14 +302,14 @@
"FloatFast", -- DEPRECATED
"FloatStrict", -- DEPRECATED
"LinkTimeOptimization",
- "Managed",
+ "Managed", -- DEPRECATED
"Maps",
"MFC",
"MultiProcessorCompile",
"NativeWChar", -- DEPRECATED
"No64BitChecks",
"NoCopyLocal",
- "NoEditAndContinue",
+ "NoEditAndContinue", -- DEPRECATED
"NoExceptions",
"NoFramePointer",
"NoImplicitLink",
@@ -312,10 +329,12 @@
"OptimizeSpeed", -- DEPRECATED
"ReleaseRuntime",
"SEH",
+ "ShadowedVariables",
"StaticRuntime",
"Symbols",
+ "UndefinedIdentifiers",
"Unicode",
- "Unsafe",
+ "Unsafe", -- DEPRECATED
"WinMain",
"WPF",
},
@@ -624,6 +643,12 @@
tokens = true,
}
+ api.register {
+ name = "rules",
+ scope = "project",
+ kind = "list:string",
+ }
+
api.register {
name = "startproject",
scope = "solution",
@@ -631,6 +656,18 @@
tokens = true,
}
+ api.register {
+ name = "strictaliasing",
+ scope = "config",
+ kind = "string",
+ allowed = {
+ "Off",
+ "Level1",
+ "Level2",
+ "Level3",
+ }
+ }
+
api.register {
name = "system",
scope = "config",
@@ -764,7 +801,7 @@
-- 09 Apr 2013
- api.deprecateField("buildrule", DOC_URL .. "Custom_Build_Commands",
+ api.deprecateField("buildrule", nil,
function(value)
if value.description then
buildmessage(value.description)
@@ -773,16 +810,18 @@
buildoutputs(value.outputs)
end)
+
-- 17 Jun 2013
- api.deprecateValue("flags", "Component", DOC_URL .. "buildaction",
+ api.deprecateValue("flags", "Component", nil,
function(value)
buildaction "Component"
end)
+
-- 26 Sep 2013
- api.deprecateValue("flags", { "EnableSSE", "EnableSSE2" }, DOC_URL .. "vectorextensions",
+ api.deprecateValue("flags", { "EnableSSE", "EnableSSE2" }, nil,
function(value)
vectorextensions(value:sub(7))
end,
@@ -790,7 +829,8 @@
vectorextension "Default"
end)
- api.deprecateValue("flags", { "FloatFast", "FloatStrict" }, DOC_URL .. "floatingpoint",
+
+ api.deprecateValue("flags", { "FloatFast", "FloatStrict" }, nil,
function(value)
floatingpoint(value:sub(6))
end,
@@ -798,7 +838,8 @@
floatingpoint "Default"
end)
- api.deprecateValue("flags", { "NativeWChar", "NoNativeWChar" }, DOC_URL .. "nativewchar",
+
+ api.deprecateValue("flags", { "NativeWChar", "NoNativeWChar" }, nil,
function(value)
local map = { NativeWChar = "On", NoNativeWChar = "Off" }
nativewchar(map[value] or "Default")
@@ -807,7 +848,8 @@
nativewchar "Default"
end)
- api.deprecateValue("flags", { "Optimize", "OptimizeSize", "OptimizeSpeed" }, DOC_URL .. "optimize",
+
+ api.deprecateValue("flags", { "Optimize", "OptimizeSize", "OptimizeSpeed" }, nil,
function(value)
local map = { Optimize = "On", OptimizeSize = "Size", OptimizeSpeed = "Speed" }
optimize (map[value] or "Off")
@@ -816,7 +858,8 @@
optimize "Off"
end)
- api.deprecateValue("flags", { "Optimise", "OptimiseSize", "OptimiseSpeed" }, DOC_URL .. "optimize",
+
+ api.deprecateValue("flags", { "Optimise", "OptimiseSize", "OptimiseSpeed" }, nil,
function(value)
local map = { Optimise = "On", OptimiseSize = "Size", OptimiseSpeed = "Speed" }
optimize (map[value] or "Off")
@@ -825,7 +868,8 @@
optimize "Off"
end)
- api.deprecateValue("flags", { "ExtraWarnings", "NoWarnings" }, DOC_URL .. "warnings",
+
+ api.deprecateValue("flags", { "ExtraWarnings", "NoWarnings" }, nil,
function(value)
local map = { ExtraWarnings = "Extra", NoWarnings = "Off" }
warnings (map[value] or "Default")
@@ -835,6 +879,36 @@
end)
+ -- 10 Nov 2014
+
+ api.deprecateValue("flags", "Managed", nil,
+ function(value)
+ clr "On"
+ end,
+ function(value)
+ clr "Off"
+ end)
+
+
+ api.deprecateValue("flags", "NoEditAndContinue", nil,
+ function(value)
+ editAndContinue "Off"
+ end,
+ function(value)
+ editAndContinue "On"
+ end)
+
+
+ api.deprecateValue("flags", "Unsafe", nil,
+ function(value)
+ clr "Unsafe"
+ end,
+ function(value)
+ clr "On"
+ end)
+
+
+
-----------------------------------------------------------------------------
--
-- Install Premake's default set of command line arguments.
@@ -934,6 +1008,9 @@
--
-----------------------------------------------------------------------------
+ clr "Off"
+ editAndContinue "On"
+
-- Setting a default language makes some validation easier later
language "C++"
diff --git a/src/actions/make/make_cpp.lua b/src/actions/make/make_cpp.lua
index 7ad01e5c..ee42991c 100644
--- a/src/actions/make/make_cpp.lua
+++ b/src/actions/make/make_cpp.lua
@@ -401,7 +401,7 @@
function make.ldFlags(cfg, toolset)
- local flags = table.join(toolset.getLibraryDirectories(cfg), toolset.getldflags(cfg))
+ local flags = table.join(toolset.getLibraryDirectories(cfg), toolset.getldflags(cfg), cfg.linkoptions)
_p(' ALL_LDFLAGS += $(LDFLAGS)%s', make.list(flags))
end
diff --git a/src/actions/vstudio/vs2005_csproj.lua b/src/actions/vstudio/vs2005_csproj.lua
index dcfd66fc..4706f37d 100644
--- a/src/actions/vstudio/vs2005_csproj.lua
+++ b/src/actions/vstudio/vs2005_csproj.lua
@@ -222,7 +222,7 @@
_p(2,'prompt')
_p(2,'4')
- if cfg.flags.Unsafe then
+ if cfg.clr == "Unsafe" then
_p(2,'true')
end
diff --git a/src/actions/vstudio/vs200x_vcproj.lua b/src/actions/vstudio/vs200x_vcproj.lua
index fd056e63..6eede15d 100644
--- a/src/actions/vstudio/vs200x_vcproj.lua
+++ b/src/actions/vstudio/vs200x_vcproj.lua
@@ -749,9 +749,9 @@
return 1
else
-- Edit-and-continue doesn't work for some configurations
- if cfg.flags.NoEditAndContinue or
+ if not cfg.editAndContinue or
config.isOptimizedBuild(cfg) or
- cfg.flags.Managed or
+ cfg.clr ~= p.OFF or
cfg.system == "x64"
then
return 3
@@ -856,7 +856,7 @@
function m.additionalLinkerOptions(cfg, toolset)
local flags
if toolset then
- flags = toolset.getldflags(cfg)
+ flags = table.join(toolset.getldflags(cfg), cfg.linkoptions)
else
flags = cfg.linkoptions
end
@@ -922,7 +922,7 @@
local cfg, filecfg = config.normalize(cfg)
if not filecfg
and not config.isOptimizedBuild(cfg)
- and not cfg.flags.Managed
+ and cfg.clr == p.OFF
and not cfg.flags.NoRuntimeChecks
then
p.w('BasicRuntimeChecks="3"')
@@ -1062,7 +1062,7 @@
function m.detect64BitPortabilityProblems(cfg)
local prjcfg, filecfg = config.normalize(cfg)
- if _ACTION < "vs2008" and not cfg.flags.Managed and cfg.warnings ~= "Off" and not filecfg then
+ if _ACTION < "vs2008" and cfg.clr == p.OFF and cfg.warnings ~= p.OFF and not filecfg then
p.w('Detect64BitPortabilityProblems="%s"', tostring(not cfg.flags.No64BitChecks))
end
end
@@ -1164,7 +1164,7 @@
local windows, managed, makefile
for cfg in project.eachconfig(prj) do
if cfg.system == p.WINDOWS then windows = true end
- if cfg.flags.Managed then managed = true end
+ if cfg.clr ~= p.OFF then managed = true end
if vstudio.isMakefile(cfg) then makefile = true end
end
@@ -1261,7 +1261,7 @@
function m.managedExtensions(cfg)
- if cfg.flags.Managed then
+ if cfg.clr ~= p.OFF then
p.w('ManagedExtensions="1"')
end
end
@@ -1272,7 +1272,7 @@
if config.isDebugBuild(cfg) and
cfg.debugformat ~= "c7" and
not cfg.flags.NoMinimalRebuild and
- not cfg.flags.Managed and
+ cfg.clr == p.OFF and
not cfg.flags.MultiProcessorCompile
then
p.w('MinimalRebuild="true"')
@@ -1500,7 +1500,7 @@
function m.runtimeTypeInfo(cfg)
- if cfg.flags.NoRTTI and not cfg.flags.Managed then
+ if cfg.flags.NoRTTI and cfg.clr == p.OFF then
p.w('RuntimeTypeInfo="false"')
end
end
@@ -1607,7 +1607,7 @@
function m.warnAsError(cfg)
- if cfg.flags.FatalCompileWarnings and cfg.warnings ~= "Off" then
+ if cfg.flags.FatalCompileWarnings and cfg.warnings ~= p.OFF then
p.w('WarnAsError="true"')
end
end
@@ -1618,7 +1618,7 @@
local prjcfg, filecfg = config.normalize(cfg)
local level
- if cfg.warnings == "Off" then
+ if cfg.warnings == p.OFF then
level = "0"
elseif cfg.warnings == "Extra" then
level = "4"
diff --git a/src/actions/vstudio/vs2010_vcxproj.lua b/src/actions/vstudio/vs2010_vcxproj.lua
index 393eea0c..0164a981 100644
--- a/src/actions/vstudio/vs2010_vcxproj.lua
+++ b/src/actions/vstudio/vs2010_vcxproj.lua
@@ -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,23 +491,19 @@
-- Write out project-level custom rule variables.
---
- function m.customRuleVars(cfg)
- local vars = p.api.getCustomVars()
- table.foreachi(cfg.project._customRules, function(rule)
+ function m.ruleVars(cfg)
+ for i = 1, #cfg.rules do
+ local rule = p.global.getRule(cfg.rules[i])
+
local contents = p.capture(function ()
p.push()
- for _, var in ipairs(vars) do
- if cfg[var] then
- local key = p.api.getCustomVarKey(var)
- local value = cfg[var]
-
- if type(value) == "table" then
- local fmt = p.api.getCustomListFormat(var)
- value = table.concat(value, fmt[1])
- end
-
- if value and #value > 0 then
- m.element(key, nil, '%s', value)
+ for prop in p.rule.eachProperty(rule) do
+ local fld = p.rule.getPropertyField(rule, prop)
+ local value = cfg[fld.name]
+ if value ~= nil then
+ value = p.rule.getPropertyString(rule, prop, value)
+ if value ~= nil and #value > 0 then
+ m.element(prop.name, nil, '%s', value)
end
end
end
@@ -515,11 +511,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
@@ -559,12 +555,12 @@
---
m.elements.fileGroups = {
- "ClInclude",
- "ClCompile",
- "None",
- "ResourceCompile",
- "CustomBuild",
- "CustomRule"
+ "clInclude",
+ "clCompile",
+ "none",
+ "resourceCompile",
+ "customBuild",
+ "customRule"
}
m.elements.files = function(prj, groups)
@@ -583,7 +579,7 @@
end
- function m.ClCompileFiles(prj, group)
+ function m.clCompileFiles(prj, group)
local files = group.ClCompile or {}
if #files > 0 then
p.push('')
@@ -622,7 +618,7 @@
end
- function m.ClIncludeFiles(prj, groups)
+ function m.clIncludeFiles(prj, groups)
local files = groups.ClInclude or {}
if #files > 0 then
p.push('')
@@ -634,7 +630,7 @@
end
- function m.CustomBuildFiles(prj, groups)
+ function m.customBuildFiles(prj, groups)
local files = groups.CustomBuild or {}
if #files > 0 then
p.push('')
@@ -672,48 +668,42 @@
end
- function m.CustomRuleFiles(prj, groups)
- local vars = p.api.getCustomVars()
-
- -- Look for rules that aren't in the built-in rule list
- for rule, files in pairs(groups) do
- if not table.contains(m.elements.fileGroups, rule) and #files > 0 then
+ function m.customRuleFiles(prj, groups)
+ for i = 1, #prj.rules do
+ local rule = p.global.getRule(prj.rules[i])
+ local files = groups[rule.name]
+ if files and #files > 0 then
p.push('')
- for _, file in ipairs(files) do
- -- Capture any rule variables that have been set
+ for _, file in ipairs(files) do
local contents = p.capture(function()
p.push()
- for _, var in ipairs(vars) do
+ for prop in p.rule.eachProperty(rule) do
+ local fld = p.rule.getPropertyField(rule, prop)
+
for cfg in project.eachconfig(prj) do
- local condition = m.condition(cfg)
local fcfg = fileconfig.getconfig(file, cfg)
- if fcfg and fcfg[var] then
- local key = p.api.getCustomVarKey(var)
- local value = fcfg[var]
-
- if type(value) == "table" then
- local fmt = p.api.getCustomListFormat(var)
- value = table.concat(value, fmt[1])
- end
-
+ if fcfg and fcfg[fld.name] then
+ local value = p.rule.getPropertyString(rule, prop, fcfg[fld.name])
if value and #value > 0 then
- m.element(key, condition, '%s', value)
+ m.element(prop.name, m.condition(cfg), '%s', value)
end
end
end
+
end
p.pop()
end)
if #contents > 0 then
- p.push('<%s Include=\"%s\">', rule, path.translate(file.relpath))
+ p.push('<%s Include=\"%s\">', rule.name, path.translate(file.relpath))
p.outln(contents)
- p.pop('%s>', rule)
+ p.pop('%s>', rule.name)
else
- p.x('<%s Include=\"%s\" />', rule, path.translate(file.relpath))
+ p.x('<%s Include=\"%s\" />', rule.name, path.translate(file.relpath))
end
end
+
p.pop('')
end
end
@@ -721,7 +711,7 @@
- function m.NoneFiles(prj, groups)
+ function m.noneFiles(prj, groups)
local files = groups.None or {}
if #files > 0 then
p.push('')
@@ -733,7 +723,7 @@
end
- function m.ResourceCompileFiles(prj, groups)
+ function m.resourceCompileFiles(prj, groups)
local files = groups.ResourceCompile or {}
if #files > 0 then
p.push('')
@@ -764,17 +754,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, prj.rules)
+ if rule then
+ return rule.name
+ end
+
-- Otherwise use the file extension to deduce a category
if path.iscppfile(file.name) then
return "ClCompile"
@@ -823,7 +817,7 @@
--
m.elements.projectReferences = function(prj, ref)
- if prj.flags.Managed then
+ if prj.clr ~= p.OFF then
return {
m.referenceProject,
m.referencePrivate,
@@ -957,8 +951,14 @@
function m.clrSupport(cfg)
- if cfg.flags.Managed then
- _p(2,'true')
+ local value
+ if cfg.clr == "On" or cfg.clr == "Unsafe" then
+ value = "true"
+ elseif cfg.clr ~= p.OFF then
+ value = cfg.clr
+ end
+ if value then
+ p.w('%s', value)
end
end
@@ -998,9 +998,9 @@
if cfg.debugformat == "c7" then
value = "OldStyle"
elseif cfg.architecture == "x64" or
- cfg.flags.Managed or
+ cfg.clr ~= p.OFF or
config.isOptimizedBuild(cfg) or
- cfg.flags.NoEditAndContinue
+ not cfg.editAndContinue
then
value = "ProgramDatabase"
else
@@ -1045,7 +1045,7 @@
function m.entryPointSymbol(cfg)
if (cfg.kind == premake.CONSOLEAPP or cfg.kind == premake.WINDOWEDAPP) and
not cfg.flags.WinMain and
- not cfg.flags.Managed and
+ cfg.clr == p.OFF and
cfg.system ~= premake.XBOX360
then
_p(3,'mainCRTStartup')
@@ -1155,11 +1155,13 @@
function m.importExtensionTargets(prj)
p.w('')
p.push('')
- table.foreachi(prj.customRules, function(value)
- value = path.translate(project.getrelative(prj, value))
- value = path.appendExtension(value, ".targets")
- p.x('', 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('', path.translate(loc))
+ end
+
p.pop('')
end
@@ -1174,11 +1176,13 @@
function m.importExtensionSettings(prj)
p.w('')
p.push('')
- table.foreachi(prj.customRules, function(value)
- value = path.translate(project.getrelative(prj, value))
- value = path.appendExtension(value, ".props")
- p.x('', 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('', path.translate(loc))
+ end
+
p.pop('')
end
@@ -1212,7 +1216,7 @@
if cfg.system == premake.WINDOWS then
isWin = true
end
- if cfg.flags.Managed then
+ if cfg.clr ~= p.OFF then
isManaged = true
end
if vstudio.isMakefile(cfg) then
@@ -1486,7 +1490,7 @@
function m.runtimeTypeInfo(cfg)
- if cfg.flags.NoRTTI and not cfg.flags.Managed then
+ if cfg.flags.NoRTTI and cfg.clr == p.OFF then
_p(3,'false')
end
end
@@ -1546,7 +1550,7 @@
function m.treatWarningAsError(cfg)
- if cfg.flags.FatalCompileWarnings and cfg.warnings ~= "Off" then
+ if cfg.flags.FatalCompileWarnings and cfg.warnings ~= p.OFF then
p.w('true')
end
end
diff --git a/src/base/api.lua b/src/base/api.lua
index a6a627fd..d7eb0ba1 100755
--- a/src/base/api.lua
+++ b/src/base/api.lua
@@ -46,7 +46,17 @@
end
_G[containerName] = function(name)
- return api._setContainer(class, name)
+ local c = api._setContainer(class, name)
+ if api._isIncludingExternal then
+ c.external = true
+ end
+ return c
+ end
+
+ _G["external" .. containerName:capitalized()] = function(name)
+ local c = _G[containerName](name)
+ c.external = true
+ return c
end
return class
@@ -54,6 +64,20 @@
+---
+-- Register a general-purpose includeExternal() call which works just like
+-- include(), but marks any containers created while evaluating the included
+-- scripts as external.
+---
+
+ function includeExternal(fname)
+ api._isIncludingExternal = true
+ include(fname)
+ api._isIncludingExternal = nil
+ end
+
+
+
---
-- Return the global configuration container. You could just call global()
-- too, but this is much faster.
@@ -238,7 +262,7 @@
-- create a setter function for it
_G[name] = function(value)
- return api.callback(field, value)
+ return api.storeField(field, value)
end
if premake.field.removes(field) then
@@ -460,15 +484,15 @@
-- gets parceled out to the individual set...() functions.
--
- function api.callback(field, value)
- if not value then
+ function api.storeField(field, value)
+ if value == nil then
return
end
if field.deprecated and type(field.deprecated.handler) == "function" then
field.deprecated.handler(value)
- if api._deprecations ~= "off" then
- premake.warnOnce(field.name, "the field %s has been deprecated.\n %s", field.name, field.deprecated.message or "")
+ if field.deprecated.message and api._deprecations ~= "off" then
+ premake.warnOnce(field.name, "the field %s has been deprecated.\n %s", field.name, field.deprecated.message)
if api._deprecations == "error" then error("deprecation errors enabled", 3) end
end
end
@@ -486,6 +510,7 @@
end
+
--
-- The remover: adds values to be removed to the "removes" field on
-- current configuration. Removes are keyed by the associated field,
@@ -496,7 +521,7 @@
function api.remove(field, value)
-- right now, ignore calls with no value; later might want to
-- return the current baked value
- if not value then return end
+ if value == nil then return end
local target = api.target(field)
if not target then
@@ -517,9 +542,9 @@
if field.deprecated[value] then
local handler = field.deprecated[value]
if handler.remove then handler.remove(value) end
- if api._deprecations ~= "off" then
+ if handler.message and api._deprecations ~= "off" then
local key = field.name .. "_" .. value
- premake.warnOnce(key, "the %s value %s has been deprecated.\n %s", field.name, value, handler.message or "")
+ premake.warnOnce(key, "the %s value %s has been deprecated.\n %s", field.name, value, handler.message)
if api._deprecations == "error" then
error { msg="deprecation errors enabled" }
end
@@ -618,9 +643,9 @@
if field.deprecated and field.deprecated[canonical] then
local handler = field.deprecated[canonical]
handler.add(canonical)
- if api._deprecations ~= "off" then
+ if handler.message and api._deprecations ~= "off" then
local key = field.name .. "_" .. value
- premake.warnOnce(key, "the %s value %s has been deprecated.\n %s", field.name, canonical, handler.message or "")
+ premake.warnOnce(key, "the %s value %s has been deprecated.\n %s", field.name, canonical, handler.message)
if api._deprecations == "error" then
return nil, "deprecation errors enabled"
end
@@ -639,18 +664,9 @@
---
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
- local vars = api.getCustomVars()
- for i, var in ipairs(vars) do
- local f = premake.field.get(var)
- api.unregister(f)
- end
-
- -- Remove all custom list variable formats
- api._customVarFormats = {}
end
@@ -687,6 +703,47 @@
+---
+-- Boolean field kind; converts common yes/no strings into true/false values.
+---
+
+ premake.field.kind("boolean", {
+ store = function(field, current, value, processor)
+ local mapping = {
+ ["false"] = false,
+ ["no"] = false,
+ ["off"] = false,
+ ["on"] = true,
+ ["true"] = true,
+ ["yes"] = true,
+ }
+
+ if type(value) == "string" then
+ value = mapping[value:lower()]
+ if value == nil then
+ error { msg="expected boolean; got " .. value }
+ end
+ return value
+ end
+
+ if type(value) == "boolean" then
+ return value
+ end
+
+ if type(value) == "number" then
+ return (value ~= 0)
+ end
+
+ return (value ~= nil)
+ end,
+ compare = function(field, a, b, processor)
+ return (a == b)
+ end
+ })
+
+
+
+
--
-- Directory data kind; performs wildcard directory searches, converts
-- results to absolute paths.
@@ -1044,26 +1101,6 @@
---
--- Activates a reference to an external, non-Premake generated 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 external(name)
- local prj = project(name)
- prj.external = true;
- return prj
- end
-
-
-
--
-- Define a new action.
--
@@ -1086,125 +1123,3 @@
function newoption(opt)
premake.option.add(opt)
end
-
-
------------------------------------------------------------------------------
---
--- The custom*() functions act as wrappers that define new ad-hoc fields
--- on the fly, to support arbitrary custom rule variables. These should be
--- considered experimental and temporary for now as a more complete rule-
--- generating solution will certainly be needed, but I will do my best to
--- deprecate them cleanly when that time comes.
---
------------------------------------------------------------------------------
-
- api._customVarFormats = {}
-
- function api.getCustomVars()
- local vars = {}
- for f in premake.field.each() do
- if f.name:startswith("_custom_") then
- table.insert(vars, f.name)
- end
- end
- return vars
- end
-
-
- function api.getCustomVarKey(var)
- return var:sub(9)
- end
-
-
- function api.getCustomListFormat(var)
- local key = api.getCustomVarKey(var)
- return api._customVarFormats[key] or { " " }
- end
-
-
- function api.setCustomVar(name, kind, value)
- local fieldName = "_custom_" .. name
- local field = premake.field.get(fieldName)
- if not field then
- field = premake.field.new {
- name = fieldName,
- scope = "config",
- kind = kind,
- tokens = true,
- }
- end
- api.callback(field, value)
- end
-
-
- function customVar(value)
- if type(value) ~= "table" or #value ~= 2 then
- error("invalid value for customVar()")
- end
- api.setCustomVar(value[1], "string", value[2])
- end
-
-
- function customList(value)
- if type(value) ~= "table" or #value < 2 then
- error("invalid value for customList()")
- end
-
- local name = value[1]
- table.remove(value, 1)
- api.setCustomVar(name, "list:string", value)
- end
-
-
- function customListFormat(value)
- if type(value) ~= "table" or #value < 2 then
- error("invalid value for customListFormat()")
- end
-
- local name = value[1]
- 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
diff --git a/src/base/config.lua b/src/base/config.lua
index 9583a1ed..d5f55af9 100755
--- a/src/base/config.lua
+++ b/src/base/config.lua
@@ -4,9 +4,12 @@
-- Copyright (c) 2011-2013 Jason Perkins and the Premake project
--
- premake.config = {}
- local project = premake.project
- local config = premake.config
+ local p = premake
+
+ p.config = {}
+
+ local project = p.project
+ local config = p.config
---
@@ -91,8 +94,8 @@
-- Can't link managed and unmanaged projects
- local cfgManaged = project.isdotnet(cfg.project) or (cfg.flags.Managed ~= nil)
- local tgtManaged = project.isdotnet(target.project) or (target.flags.Managed ~= nil)
+ local cfgManaged = project.isdotnet(cfg.project) or (cfg.clr ~= p.OFF)
+ local tgtManaged = project.isdotnet(target.project) or (target.clr ~= p.OFF)
return (cfgManaged == tgtManaged)
end
@@ -111,7 +114,7 @@
-- Unmanaged projects can never link managed assemblies
- if isManaged and not cfg.flags.Managed then
+ if isManaged and cfg.clr == p.OFF then
return false
end
@@ -438,7 +441,7 @@
--
function config.isOptimizedBuild(cfg)
- return cfg.optimize ~= nil and cfg.optimize ~= "Off" and cfg.optimize ~= "Debug"
+ return cfg.optimize ~= nil and cfg.optimize ~= p.OFF and cfg.optimize ~= "Debug"
end
diff --git a/src/base/configset.lua b/src/base/configset.lua
index 33766f52..f50404ff 100644
--- a/src/base/configset.lua
+++ b/src/base/configset.lua
@@ -89,12 +89,12 @@
-- If the filter contains a file path, make it relative to
-- this block's basedir
- if value and abspath and not cset.compiled and block._basedir ~= basedir then
+ if value ~= nil and abspath and not cset.compiled and block._basedir ~= basedir then
basedir = block._basedir
filter.files = path.getrelative(basedir, abspath)
end
- if value and (cset.compiled or criteria.matches(block._criteria, filter)) then
+ if value ~= nil and (cset.compiled or criteria.matches(block._criteria, filter)) then
-- If value is an object, return a copy of it so that any
-- changes later made to it by the caller won't alter the
-- original value (that was a tough bug to find)
diff --git a/src/base/container.lua b/src/base/container.lua
index 4850eccb..55be14cc 100644
--- a/src/base/container.lua
+++ b/src/base/container.lua
@@ -70,8 +70,10 @@
self.class = class
self.name = name
+ self.filename = name
self.script = _SCRIPT
self.basedir = os.getcwd()
+ self.external = false
for childClass in container.eachChildClass(class) do
self[childClass.pluralName] = {}
diff --git a/src/base/detoken.lua b/src/base/detoken.lua
index bd0749aa..1f6f17c6 100644
--- a/src/base/detoken.lua
+++ b/src/base/detoken.lua
@@ -79,6 +79,10 @@
end
function expandvalue(value)
+ if type(value) ~= "string" then
+ return
+ end
+
local count
repeat
value, count = value:gsub("%%{(.-)}", function(token)
diff --git a/src/base/field.lua b/src/base/field.lua
index 5ba28840..2c4303ab 100644
--- a/src/base/field.lua
+++ b/src/base/field.lua
@@ -290,7 +290,7 @@
local kinds = string.explode(f._kind, ":", true)
for i, kind in ipairs(kinds) do
local value = field._kinds[kind][tag]
- if value then
+ if value ~= nil then
return value
end
end
diff --git a/src/base/global.lua b/src/base/global.lua
index 04086653..f142608f 100644
--- a/src/base/global.lua
+++ b/src/base/global.lua
@@ -47,6 +47,48 @@
+---
+-- 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.
+-- @param rules
+-- A list of rule names to be included in the search. If not specified,
+-- all rules will be checked.
+-- @returns
+-- The rule, is one has been registered, or nil.
+---
+
+ function global.getRuleForFile(fname, rules)
+ local ext = path.getextension(fname):lower()
+ for rule in global.eachRule() do
+ if not rules or table.contains(rules, rule.name) then
+ if rule.fileExtension == ext then
+ return rule
+ end
+ end
+ end
+ end
+
+
+
---
-- Retrieve a solution by name or index.
--
@@ -58,7 +100,5 @@
function global.getSolution(key)
local root = p.api.rootContainer()
- if root.solutions then
- return root.solutions[key]
- end
+ return root.solutions[key]
end
diff --git a/src/base/oven.lua b/src/base/oven.lua
index 53da552e..ae5eda40 100644
--- a/src/base/oven.lua
+++ b/src/base/oven.lua
@@ -94,7 +94,6 @@
-- to project configurations.
self.configs = oven.bakeConfigs(self)
-
end
@@ -194,6 +193,14 @@
+ function p.rule.bake(r)
+ table.sort(r.propertyDefinition, function (a, b)
+ return a.name < b.name
+ end)
+ end
+
+
+
--
-- Assigns a unique objects directory to every configuration of every project
-- in the solution, taking any objdir settings into account, to ensure builds
diff --git a/src/base/premake.lua b/src/base/premake.lua
index f31196b0..be71e6a4 100644
--- a/src/base/premake.lua
+++ b/src/base/premake.lua
@@ -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
@@ -189,7 +191,7 @@ function premake.filename(obj, ext)
fname = fname .. ext
end
end
- return fname
+ return path.getabsolute(fname)
end
@@ -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
diff --git a/src/base/project.lua b/src/base/project.lua
index a5dd802f..cb996641 100755
--- a/src/base/project.lua
+++ b/src/base/project.lua
@@ -12,6 +12,15 @@
+---
+-- Alias the old external() call to the new externalProject(), to distinguish
+-- between it and externalRule().
+---
+
+ external = externalProject
+
+
+
---
-- Create a new project container instance.
---
@@ -19,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
diff --git a/src/base/rule.lua b/src/base/rule.lua
new file mode 100644
index 00000000..d17228ad
--- /dev/null
+++ b/src/base/rule.lua
@@ -0,0 +1,161 @@
+---
+-- base/rule.lua
+-- Defines rule sets for generated custom rule files.
+-- Copyright (c) 2014 Jason Perkins and the Premake project
+---
+
+ local p = premake
+ p.rule = p.api.container("rule", p.global)
+
+ local rule = p.rule
+
+
+
+---
+-- Create a new rule container instance.
+---
+
+ function rule.new(name)
+ local self = p.container.new(rule, name)
+
+ -- create a variable setting function. Do a version with lowercased
+ -- first letter(s) to match Premake's naming style for other calls
+
+ _G[name .. "Vars"] = function(vars)
+ rule.setVars(self, vars)
+ end
+
+ local lowerName = name:gsub("^%u+", string.lower)
+ _G[lowerName .. "Vars"] = _G[name .. "Vars"]
+
+ return self
+ end
+
+
+
+---
+-- Enumerate the property definitions for a rule.
+---
+
+ function rule.eachProperty(self)
+ local props = self.propertyDefinition
+ local i = 0
+ return function ()
+ i = i + 1
+ if i <= #props then
+ return props[i]
+ end
+ end
+ end
+
+
+
+---
+-- Find a property definition by its name.
+--
+-- @param name
+-- The property name.
+-- @returns
+-- The property definition if found, nil otherwise.
+---
+
+ function rule.getProperty(self, name)
+ local props = self.propertyDefinition
+ for i = 1, #props do
+ local prop = props[i]
+ if prop.name == name then
+ return prop
+ end
+ end
+ end
+
+
+
+---
+-- Find the field definition for one this rule's properties. This field
+-- can then be used with the api.* functions to manipulate the property's
+-- values in the current configuration scope.
+--
+-- @param prop
+-- The property definition.
+-- @return
+-- The field definition for the property; this will be created if it
+-- does not already exist.
+---
+
+ function rule.getPropertyField(self, prop)
+ if prop._field then
+ return prop._field
+ end
+
+ local kind = prop.kind or "string"
+ if kind == "list" then
+ kind = "list:string"
+ end
+
+ local fld = p.field.new {
+ name = "_rule_" .. self.name .. "_" .. prop.name,
+ scope = "config",
+ kind = kind,
+ tokens = true,
+ }
+
+ prop._field = fld
+ return fld
+ end
+
+
+
+---
+-- Given the value for a particular property, returns a formatted string.
+--
+-- @param prop
+-- The property definition.
+-- @param value
+-- The value of the property to be formatted.
+-- @returns
+-- A string value.
+---
+
+ function rule.getPropertyString(self, prop, value)
+ -- list?
+ if type(value) == "table" then
+ local sep = prop.separator or " "
+ return table.concat(value, sep)
+ end
+
+ -- enum?
+ if prop.values then
+ local i = table.indexof(prop.values, value)
+ return tostring(i)
+ end
+
+ -- primitive
+ value = tostring(value)
+ if #value > 0 then
+ return value
+ else
+ return nil
+ end
+ end
+
+
+
+---
+-- Set one or more rule variables in the current configuration scope.
+--
+-- @param vars
+-- A key-value list of variables to set and their corresponding values.
+---
+
+ function rule.setVars(self, vars)
+ for key, value in pairs(vars) do
+ local prop = rule.getProperty(self, key)
+ if not prop then
+ error (string.format("rule '%s' does not have property '%s'", self.name, key))
+ end
+
+ local fld = rule.getPropertyField(self, prop)
+ p.api.storeField(fld, value)
+ end
+ end
diff --git a/src/base/rules.lua b/src/base/rules.lua
deleted file mode 100644
index 731350d7..00000000
--- a/src/base/rules.lua
+++ /dev/null
@@ -1,20 +0,0 @@
----
--- base/rules.lua
--- Defines rule sets for generated custom rule files.
--- Copyright (c) 2014 Jason Perkins and the Premake project
----
-
- local p = premake
- p.rule = p.api.container("rule", p.global)
-
- local rule = p.rule
-
-
-
----
--- Create a new rule container instance.
----
-
- function rule.new(name)
- return p.container.new(rule, name)
- end
diff --git a/src/base/solution.lua b/src/base/solution.lua
index 13f0357d..e008d968 100644
--- a/src/base/solution.lua
+++ b/src/base/solution.lua
@@ -18,7 +18,6 @@
function solution.new(name)
local sln = p.container.new(solution, name)
- sln.filename = name
return sln
end
diff --git a/src/base/string.lua b/src/base/string.lua
index 2a85ee47..3c28f521 100644
--- a/src/base/string.lua
+++ b/src/base/string.lua
@@ -5,6 +5,16 @@
--
+--
+-- Capitalize the first letter of the string.
+--
+
+ function string.capitalized(self)
+ return self:gsub("^%l", string.upper)
+ end
+
+
+
--
-- Returns true if the string has a match for the plain specified pattern
--
diff --git a/src/base/table.lua b/src/base/table.lua
index 81285309..e01e7a87 100644
--- a/src/base/table.lua
+++ b/src/base/table.lua
@@ -168,15 +168,15 @@
--
function table.indexof(tbl, obj)
- local count = #tbl
- for i = 1, count do
- if tbl[i] == obj then
- return i
+ for k, v in pairs(tbl) do
+ if v == obj then
+ return k
end
end
end
+
---
-- Insert a new value into a table in the position after the specified
-- existing value. If the specified value does not exist in the table,
diff --git a/src/host/lua_auxlib.c b/src/host/lua_auxlib.c
index f2807713..27883a3e 100644
--- a/src/host/lua_auxlib.c
+++ b/src/host/lua_auxlib.c
@@ -49,7 +49,7 @@ LUALIB_API int luaL_loadfile (lua_State* L, const char* filename)
const char* script_dir;
lua_getglobal(L, "_SCRIPT_DIR");
script_dir = lua_tostring(L, -1);
- if (script_dir[0] == '$') {
+ if (script_dir && script_dir[0] == '$') {
/* call path.getabsolute() to handle ".." if present */
lua_pushcfunction(L, path_getabsolute);
lua_pushstring(L, filename);
@@ -75,7 +75,7 @@ LUALIB_API int luaL_loadfile (lua_State* L, const char* filename)
if (z == OKAY) {
lua_pushcclosure(L, chunk_wrapper, 2);
}
- else {
+ else if (z == LUA_YIELD) {
lua_pushstring(L, "cannot open ");
lua_pushstring(L, filename);
lua_pushstring(L, ": No such file or directory");
diff --git a/src/host/premake.c b/src/host/premake.c
index 51f7f32b..ecba9fa7 100644
--- a/src/host/premake.c
+++ b/src/host/premake.c
@@ -332,11 +332,5 @@ int premake_load_embedded_script(lua_State* L, const char* filename)
lua_concat(L, 2);
/* Load the chunk */
- i = luaL_loadbuffer(L, chunk, strlen(chunk), filename);
- if (i != OKAY) {
- lua_pop(L, 1);
- printf("Failed to load embedded script '%s': %s\n", filename, lua_tostring(L, -1));
- }
-
- return i;
+ return luaL_loadbuffer(L, chunk, strlen(chunk), filename);
}
diff --git a/src/tools/clang.lua b/src/tools/clang.lua
index 3ecae3a5..5a8df4ee 100644
--- a/src/tools/clang.lua
+++ b/src/tools/clang.lua
@@ -166,7 +166,6 @@
function clang.getldflags(cfg)
local flags = config.mapFlags(cfg, clang.ldflags)
- flags = table.join(flags, cfg.linkoptions)
return flags
end
diff --git a/src/tools/dotnet.lua b/src/tools/dotnet.lua
index ed59f058..8ad8c61e 100644
--- a/src/tools/dotnet.lua
+++ b/src/tools/dotnet.lua
@@ -200,10 +200,12 @@
--
dotnet.flags = {
+ clr = {
+ Unsafe = "/unsafe",
+ },
flags = {
FatalWarning = "/warnaserror",
Symbols = "/debug",
- Unsafe = "/unsafe"
},
optimize = {
On = "/optimize",
diff --git a/src/tools/gcc.lua b/src/tools/gcc.lua
index 00c63ddd..41eb74e0 100644
--- a/src/tools/gcc.lua
+++ b/src/tools/gcc.lua
@@ -40,7 +40,9 @@
flags = {
FatalCompileWarnings = "-Werror",
NoFramePointer = "-fomit-frame-pointer",
- Symbols = "-g"
+ ShadowedVariables = "-Wshadow",
+ Symbols = "-g",
+ UndefinedIdentifiers = "-Wundef",
},
floatingpoint = {
Fast = "-ffast-math",
@@ -51,6 +53,12 @@
if cfg.system ~= premake.WINDOWS then return "-fPIC" end
end,
},
+ strictaliasing = {
+ Off = "-fno-strict-aliasing",
+ Level1 = { "-fstrict-aliasing", "-Wstrict-aliasing=1" },
+ Level2 = { "-fstrict-aliasing", "-Wstrict-aliasing=2" },
+ Level3 = { "-fstrict-aliasing", "-Wstrict-aliasing=3" },
+ },
optimize = {
Off = "-O0",
On = "-O2",
@@ -177,7 +185,6 @@
function gcc.getldflags(cfg)
local flags = config.mapFlags(cfg, gcc.ldflags)
- flags = table.join(flags, cfg.linkoptions)
return flags
end
diff --git a/src/tools/msc.lua b/src/tools/msc.lua
index 13a64c3a..1d1426d3 100644
--- a/src/tools/msc.lua
+++ b/src/tools/msc.lua
@@ -25,6 +25,12 @@
--
msc.cflags = {
+ clr = {
+ On = "/clr",
+ Unsafe = "/clr",
+ Pure = "/clr:pure",
+ Safe = "/clr:safe",
+ },
flags = {
FatalCompileWarnings = "/WX",
MultiProcessorCompile = "/MP",
@@ -168,7 +174,6 @@
function msc.getldflags(cfg)
local map = iif(cfg.kind ~= premake.STATICLIB, msc.linkerFlags, msc.librarianFlags)
local flags = config.mapFlags(cfg, map)
- flags = table.join(flags, cfg.linkoptions)
table.insert(flags, 1, "/NOLOGO")
return flags
end
diff --git a/tests/_tests.lua b/tests/_tests.lua
index e438fef2..37a30172 100644
--- a/tests/_tests.lua
+++ b/tests/_tests.lua
@@ -37,6 +37,7 @@ return {
"oven/test_objdirs.lua",
-- API tests
+ "api/test_boolean_kind.lua",
"api/test_containers.lua",
"api/test_directory_kind.lua",
"api/test_list_kind.lua",
@@ -114,6 +115,7 @@ return {
"actions/vstudio/vc2010/test_project_refs.lua",
"actions/vstudio/vc2010/test_prop_sheet.lua",
"actions/vstudio/vc2010/test_resource_compile.lua",
+ "actions/vstudio/vc2010/test_rule_vars.lua",
-- Visual Studio 2012
"actions/vs2012/test_csproj_common_props.lua",
diff --git a/tests/actions/make/cs/test_flags.lua b/tests/actions/make/cs/test_flags.lua
index caeadf2f..3c63247f 100644
--- a/tests/actions/make/cs/test_flags.lua
+++ b/tests/actions/make/cs/test_flags.lua
@@ -43,7 +43,7 @@
--
function suite.onUnsafe()
- flags { "Unsafe" }
+ clr "Unsafe"
prepare()
test.capture [[
FLAGS = /unsafe /noconfig
diff --git a/tests/actions/vstudio/cs2005/test_compiler_props.lua b/tests/actions/vstudio/cs2005/test_compiler_props.lua
index eb303592..43929e4d 100644
--- a/tests/actions/vstudio/cs2005/test_compiler_props.lua
+++ b/tests/actions/vstudio/cs2005/test_compiler_props.lua
@@ -44,7 +44,7 @@
--
function suite.allowUnsafeBlocks_onUnsafeFlag()
- flags { "Unsafe" }
+ clr "Unsafe"
prepare()
test.capture [[
diff --git a/tests/actions/vstudio/sln2005/test_projects.lua b/tests/actions/vstudio/sln2005/test_projects.lua
index 3d713712..144cfbc9 100755
--- a/tests/actions/vstudio/sln2005/test_projects.lua
+++ b/tests/actions/vstudio/sln2005/test_projects.lua
@@ -184,7 +184,7 @@ EndProject
--
function suite.translatesEnvironmentVars()
- external "MyProject"
+ externalProject "MyProject"
location "$(SDK_LOCATION)/MyProject"
uuid "30A1B994-C2C6-485F-911B-FB4674366DA8"
kind "SharedLib"
diff --git a/tests/actions/vstudio/vc200x/test_assembly_refs.lua b/tests/actions/vstudio/vc200x/test_assembly_refs.lua
index 69c12267..b8157b1f 100644
--- a/tests/actions/vstudio/vc200x/test_assembly_refs.lua
+++ b/tests/actions/vstudio/vc200x/test_assembly_refs.lua
@@ -16,7 +16,7 @@
function suite.setup()
sln = test.createsolution()
- flags { "Managed" }
+ clr "On"
end
local function prepare(platform)
diff --git a/tests/actions/vstudio/vc200x/test_compiler_block.lua b/tests/actions/vstudio/vc200x/test_compiler_block.lua
index b6c1ed47..9a0c86a3 100644
--- a/tests/actions/vstudio/vc200x/test_compiler_block.lua
+++ b/tests/actions/vstudio/vc200x/test_compiler_block.lua
@@ -364,7 +364,7 @@
-- Verify the correct Detect64BitPortabilityProblems settings are used when _ACTION < "VS2008".
--
- function suite.runtimeLibraryIsDebug_onVS2005()
+ function suite._64BitPortabilityOn_onVS2005()
_ACTION = "vs2005"
prepare()
test.capture [[
@@ -382,6 +382,23 @@
]]
end
+ function suite._64BitPortabilityOff_onVS2005_andCLR()
+ _ACTION = "vs2005"
+ clr "On"
+ prepare()
+ test.capture [[
+
+ ]]
+ end
+
--
-- Verify the correct warnings settings are used when no warnings are enabled.
diff --git a/tests/actions/vstudio/vc200x/test_project.lua b/tests/actions/vstudio/vc200x/test_project.lua
index 830cc094..56608ee8 100644
--- a/tests/actions/vstudio/vc200x/test_project.lua
+++ b/tests/actions/vstudio/vc200x/test_project.lua
@@ -76,7 +76,7 @@
--
function suite.keywordIsCorrect_onManagedC()
- flags { "Managed" }
+ clr "On"
prepare()
test.capture [[
@@ -606,7 +607,8 @@
--
function suite.debugFormat_onManagedCode()
- flags { "Symbols", "Managed" }
+ flags "Symbols"
+ clr "On"
prepare()
test.capture [[
diff --git a/tests/actions/vstudio/vc2010/test_config_props.lua b/tests/actions/vstudio/vc2010/test_config_props.lua
index d9eb5072..d202cbc6 100755
--- a/tests/actions/vstudio/vc2010/test_config_props.lua
+++ b/tests/actions/vstudio/vc2010/test_config_props.lua
@@ -110,12 +110,13 @@
]]
end
+
--
-- Check the support for Managed C++.
--
- function suite.clrSupport_onManaged()
- flags "Managed"
+ function suite.clrSupport_onClrOn()
+ clr "On"
prepare()
test.capture [[
@@ -125,6 +126,50 @@
]]
end
+ function suite.clrSupport_onClrOff()
+ clr "Off"
+ prepare()
+ test.capture [[
+
+ Application
+ false
+ ]]
+ end
+
+ function suite.clrSupport_onClrUnsafe()
+ clr "Unsafe"
+ prepare()
+ test.capture [[
+
+ Application
+ false
+ true
+ ]]
+ end
+
+ function suite.clrSupport_onClrSafe()
+ clr "Safe"
+ prepare()
+ test.capture [[
+
+ Application
+ false
+ Safe
+ ]]
+ end
+
+ function suite.clrSupport_onClrPure()
+ clr "Pure"
+ prepare()
+ test.capture [[
+
+ Application
+ false
+ Pure
+ ]]
+ end
+
+
--
-- Check the support for building with MFC.
--
diff --git a/tests/actions/vstudio/vc2010/test_extension_settings.lua b/tests/actions/vstudio/vc2010/test_extension_settings.lua
index 78de7363..5f4dbadc 100644
--- a/tests/actions/vstudio/vc2010/test_extension_settings.lua
+++ b/tests/actions/vstudio/vc2010/test_extension_settings.lua
@@ -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 [[
@@ -63,13 +64,13 @@
--
function suite.usesProjectRelativePaths()
- customRules "path/to/MyRules"
+ rules "MyRules"
location "build"
prepare()
test.capture [[
-
+
]]
end
diff --git a/tests/actions/vstudio/vc2010/test_extension_targets.lua b/tests/actions/vstudio/vc2010/test_extension_targets.lua
index 4b957075..77ed8d19 100644
--- a/tests/actions/vstudio/vc2010/test_extension_targets.lua
+++ b/tests/actions/vstudio/vc2010/test_extension_targets.lua
@@ -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 [[
@@ -63,13 +64,13 @@
--
function suite.usesProjectRelativePaths()
- customRules "path/to/MyRules"
+ rules { "MyRules" }
location "build"
prepare()
test.capture [[
-
+
]]
end
diff --git a/tests/actions/vstudio/vc2010/test_files.lua b/tests/actions/vstudio/vc2010/test_files.lua
index ab95b583..9f6c2d36 100755
--- a/tests/actions/vstudio/vc2010/test_files.lua
+++ b/tests/actions/vstudio/vc2010/test_files.lua
@@ -16,6 +16,15 @@
function suite.setup()
_ACTION = "vs2010"
+
+ rule "Animation"
+ fileExtension ".dae"
+ propertyDefinition {
+ name = "AdditionalOptions",
+ kind = "list",
+ separator = ";"
+ }
+
sln = test.createsolution()
end
@@ -522,12 +531,11 @@
-- Check handling of files using custom rule definitions.
--
- function suite.correctlyCategorized_onCustomRule()
+ function suite.isCategorizedByRule()
+ rules "Animation"
files { "hello.dae" }
- filter "files:**.dae"
- customRule "Animation"
prepare()
- test.capture [[
+ test.capture [[
@@ -535,107 +543,20 @@
end
- function suite.customRule_onLiteralVars()
+ function suite.listsPerConfigRuleVars()
+ rules "Animation"
files { "hello.dae" }
- filter "files:**.dae"
- customRule "Animation"
- customVar { "GenerateDebugInfo", "True" }
+ filter { "files:hello.*", "configurations:Debug" }
+ animationVars { AdditionalOptions = { "File1", "File2" }}
+ filter { "files:hello.*", "configurations:Release" }
+ animationVars { AdditionalOptions = { "File3" }}
prepare()
test.capture [[
- True
- True
+ File1;File2
+ File3
]]
end
-
-
- function suite.customRule_onLiteralPath()
- targetdir "../bin/%{cfg.buildcfg}"
- files { "hello.dae" }
- filter "files:**.dae"
- customRule "Animation"
- customVar { "OutputDirectory", "%{cfg.targetdir}/anim" }
- prepare()
- test.capture [[
-
-
- ../bin/Debug/anim
- ../bin/Release/anim
-
-
- ]]
- end
-
-
- function suite.customRule_onPerConfigLiteralVars()
- files { "hello.dae" }
- filter { "files:**.dae" }
- customRule "Animation"
- filter { "files:**.dae", "configurations:Debug" }
- customVar { "GenerateDebugInfo", "True" }
- prepare()
- test.capture [[
-
-
- True
-
-
- ]]
- end
-
-
- function suite.customRule_onListVars()
- files { "hello.dae" }
- filter "files:**.dae"
- customRule "Animation"
- customList { "ExtraDependencies", "File1", "File2" }
- prepare()
- test.capture [[
-
-
- File1 File2
- File1 File2
-
-
- ]]
- end
-
-
- function suite.customRule_onPerConfigListVars()
- files { "hello.dae" }
- filter { "files:**.dae" }
- customRule "Animation"
- customList { "ExtraDependencies", "File1", "File2" }
- filter { "files:**.dae", "configurations:Release" }
- customList { "ExtraDependencies", "File3" }
- prepare()
- test.capture [[
-
-
- File1 File2
- File1 File2 File3
-
-
- ]]
- end
-
-
- function suite.customRule_onListVarsWithCustomFormat()
- files { "hello.dae" }
- filter "files:**.dae"
- customRule "Animation"
- customListFormat { "ExtraDependencies", ";" }
- customList { "ExtraDependencies", "File1", "File2" }
- prepare()
- test.capture [[
-
-
- File1;File2
- File1;File2
-
-
- ]]
- end
\ No newline at end of file
diff --git a/tests/actions/vstudio/vc2010/test_filters.lua b/tests/actions/vstudio/vc2010/test_filters.lua
index c0b0fd36..d699e695 100644
--- a/tests/actions/vstudio/vc2010/test_filters.lua
+++ b/tests/actions/vstudio/vc2010/test_filters.lua
@@ -171,9 +171,12 @@
--
function suite.filter_onCustomRule()
+ rules "Animation"
files { "hello.dae" }
- filter "files:**.dae"
- customRule "Animation"
+
+ rule "Animation"
+ fileExtension ".dae"
+
prepare()
test.capture [[
diff --git a/tests/actions/vstudio/vc2010/test_globals.lua b/tests/actions/vstudio/vc2010/test_globals.lua
index 20e7728e..0d0f08a4 100755
--- a/tests/actions/vstudio/vc2010/test_globals.lua
+++ b/tests/actions/vstudio/vc2010/test_globals.lua
@@ -46,7 +46,7 @@
--
function suite.keywordIsCorrect_onManagedC()
- flags { "Managed" }
+ clr "On"
prepare()
test.capture [[
@@ -64,7 +64,7 @@
--
function suite.frameworkVersionIsCorrect_onManagedC()
- flags { "Managed" }
+ clr "On"
framework "4.5"
prepare()
test.capture [[
diff --git a/tests/actions/vstudio/vc2010/test_project_refs.lua b/tests/actions/vstudio/vc2010/test_project_refs.lua
index 39e195e7..236ca463 100644
--- a/tests/actions/vstudio/vc2010/test_project_refs.lua
+++ b/tests/actions/vstudio/vc2010/test_project_refs.lua
@@ -82,7 +82,7 @@
function suite.referencesAreRelative_onDifferentProjectLocation()
links { "MyProject" }
- flags { "Managed" }
+ clr "On"
prepare()
test.capture [[
diff --git a/tests/actions/vstudio/vc2010/test_rule_vars.lua b/tests/actions/vstudio/vc2010/test_rule_vars.lua
new file mode 100644
index 00000000..21735223
--- /dev/null
+++ b/tests/actions/vstudio/vc2010/test_rule_vars.lua
@@ -0,0 +1,108 @@
+--
+-- tests/actions/vstudio/vc2010/test_rule_vars.lua
+-- Validate generation of custom rule variables at the project level.
+-- Copyright (c) 2014 Jason Perkins and the Premake project
+--
+
+ local suite = test.declare("vstudio_vs2010_rule_vars")
+
+ local vc2010 = premake.vstudio.vc2010
+
+
+
+--
+-- Setup
+--
+
+ local sln, prj
+
+ function suite.setup()
+ rule "MyRule"
+ sln, prj = test.createsolution()
+ rules { "MyRule" }
+ end
+
+ local function createVar(def)
+ rule "MyRule"
+ propertyDefinition(def)
+ project "MyProject"
+ end
+
+ local function prepare()
+ local cfg = test.getconfig(prj, "Debug")
+ vc2010.ruleVars(cfg)
+ end
+
+
+--
+-- If the configuration has a rule, but does not set any variables,
+-- nothing should be written.
+--
+
+ function suite.noOutput_onNoVars()
+ prepare()
+ test.isemptycapture()
+ end
+
+
+--
+-- Test setting the various property kinds.
+--
+
+ function suite.onStringVar()
+ createVar { name="MyVar", kind="string" }
+ myRuleVars { MyVar = "hello" }
+ prepare()
+ test.capture [[
+
+ hello
+
+ ]]
+ end
+
+
+ function suite.onBooleanVar()
+ createVar { name="MyVar", kind="boolean" }
+ myRuleVars { MyVar = false }
+ prepare()
+ test.capture [[
+
+ false
+
+ ]]
+ end
+
+
+ function suite.onListVar()
+ createVar { name="MyVar", kind="list" }
+ myRuleVars { MyVar = { "a", "b", "c" } }
+ prepare()
+ test.capture [[
+
+ a b c
+
+ ]]
+ end
+
+
+ function suite.onEnumVar()
+ createVar {
+ name = "MyVar",
+ values = {
+ [0] = "Win32",
+ [1] = "Win64",
+ },
+ switch = {
+ [0] = "-m32",
+ [1] = "-m64",
+ },
+ value = 0,
+ }
+ myRuleVars { MyVar = "Win32" }
+ prepare()
+ test.capture [[
+
+ 0
+
+ ]]
+ end
diff --git a/tests/api/test_boolean_kind.lua b/tests/api/test_boolean_kind.lua
new file mode 100644
index 00000000..4d99105e
--- /dev/null
+++ b/tests/api/test_boolean_kind.lua
@@ -0,0 +1,79 @@
+--
+-- tests/api/test_boolean_kind.lua
+-- Tests the boolean API value type.
+-- Copyright (c) 2014 Jason Perkins and the Premake project
+--
+
+ local suite = test.declare("api_boolean_kind")
+ local api = premake.api
+
+
+--
+-- Setup and teardown
+--
+
+ function suite.setup()
+ api.register {
+ name = "testapi",
+ kind = "boolean",
+ scope = "project",
+ }
+ test.createsolution()
+ end
+
+ function suite.teardown()
+ testapi = nil
+ end
+
+
+
+--
+-- Check setting of true values.
+--
+
+ function suite.setsTrue_onYes()
+ testapi "yes"
+ test.istrue(api.scope.project.testapi)
+ end
+
+ function suite.setsTrue_onBooleanTrue()
+ testapi (true)
+ test.istrue(api.scope.project.testapi)
+ end
+
+ function suite.setsTrue_onNonZero()
+ testapi (1)
+ test.istrue(api.scope.project.testapi)
+ end
+
+
+--
+-- Check setting of false values.
+--
+
+ function suite.setsFalse_onNo()
+ testapi "no"
+ test.isfalse(api.scope.project.testapi)
+ end
+
+ function suite.setsFalse_onBooleanFalse()
+ testapi (false)
+ test.isfalse(api.scope.project.testapi)
+ end
+
+ function suite.setsFalse_onZero()
+ testapi (0)
+ test.isfalse(api.scope.project.testapi)
+ end
+
+
+--
+-- Raise an error on an invalid string value.
+--
+
+ function suite.raisesError_onDisallowedValue()
+ ok, err = pcall(function ()
+ testapi "maybe"
+ end)
+ test.isfalse(ok)
+ end
diff --git a/tests/base/test_configset.lua b/tests/base/test_configset.lua
index 0983de75..223ee2c1 100644
--- a/tests/base/test_configset.lua
+++ b/tests/base/test_configset.lua
@@ -175,16 +175,16 @@
function suite.remove_onExactValueMatch()
local f = field.get("flags")
- configset.store(cset, f, { "Symbols", "Unsafe", "NoRTTI" })
- configset.remove(cset, f, { "Unsafe" })
+ configset.store(cset, f, { "Symbols", "WinMain", "NoRTTI" })
+ configset.remove(cset, f, { "WinMain" })
test.isequal({ "Symbols", "NoRTTI" }, configset.fetch(cset, f, {}))
end
function suite.remove_onMultipleValues()
local f = field.get("flags")
- configset.store(cset, f, { "Symbols", "NoExceptions", "Unsafe", "NoRTTI" })
+ configset.store(cset, f, { "Symbols", "NoExceptions", "WinMain", "NoRTTI" })
configset.remove(cset, f, { "NoExceptions", "NoRTTI" })
- test.isequal({ "Symbols", "Unsafe" }, configset.fetch(cset, f, {}))
+ test.isequal({ "Symbols", "WinMain" }, configset.fetch(cset, f, {}))
end
diff --git a/tests/base/test_validation.lua b/tests/base/test_validation.lua
index 9b076eb4..c0668096 100644
--- a/tests/base/test_validation.lua
+++ b/tests/base/test_validation.lua
@@ -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
+
diff --git a/tests/config/test_links.lua b/tests/config/test_links.lua
index 659b0fd4..dc894d68 100755
--- a/tests/config/test_links.lua
+++ b/tests/config/test_links.lua
@@ -111,7 +111,7 @@
function suite.skipsAssemblies_onManagedCpp()
system "windows"
- flags { "Managed" }
+ clr "On"
links { "user32", "System.dll" }
local r = prepare("all", "fullpath")
test.isequal({ "user32.lib" }, r)
@@ -125,7 +125,7 @@
function suite.skipsUnmanagedLibs_onManagedLinkage()
system "windows"
- flags { "Managed" }
+ clr "On"
links { "user32", "System.dll" }
local r = prepare("all", "fullpath", "managed")
test.isequal({ "System.dll" }, r)
@@ -161,20 +161,20 @@
end
function suite.canLink_ManagedCppAndManagedCpp()
- flags { "Managed" }
+ clr "On"
links { "MyProject2" }
project "MyProject2"
kind "StaticLib"
language "C++"
- flags { "Managed" }
+ clr "On"
local r = prepare("all", "fullpath")
test.isequal({ "MyProject2.lib" }, r)
end
function suite.canLink_ManagedCppAndCs()
- flags { "Managed" }
+ clr "On"
links { "MyProject2" }
project "MyProject2"
diff --git a/tests/tools/test_gcc.lua b/tests/tools/test_gcc.lua
index ec2e78af..57c0d06d 100644
--- a/tests/tools/test_gcc.lua
+++ b/tests/tools/test_gcc.lua
@@ -402,3 +402,32 @@
test.isequal({ '-I"$(IntDir)/includes"' }, gcc.getincludedirs(cfg, cfg.includedirs))
end
+
+
+--
+-- Check handling of strict aliasing flags.
+--
+
+ function suite.cflags_onNoStrictAliasing()
+ strictaliasing "Off"
+ prepare()
+ test.contains("-fno-strict-aliasing", gcc.getcflags(cfg))
+ end
+
+ function suite.cflags_onLevel1Aliasing()
+ strictaliasing "Level1"
+ prepare()
+ test.contains({ "-fstrict-aliasing", "-Wstrict-aliasing=1" }, gcc.getcflags(cfg))
+ end
+
+ function suite.cflags_onLevel2Aliasing()
+ strictaliasing "Level2"
+ prepare()
+ test.contains({ "-fstrict-aliasing", "-Wstrict-aliasing=2" }, gcc.getcflags(cfg))
+ end
+
+ function suite.cflags_onLevel3Aliasing()
+ strictaliasing "Level3"
+ prepare()
+ test.contains({ "-fstrict-aliasing", "-Wstrict-aliasing=3" }, gcc.getcflags(cfg))
+ end
diff --git a/tests/tools/test_msc.lua b/tests/tools/test_msc.lua
index ffcc2348..7f09c697 100644
--- a/tests/tools/test_msc.lua
+++ b/tests/tools/test_msc.lua
@@ -235,3 +235,33 @@
prepare()
test.contains("/DLL", msc.getldflags(cfg))
end
+
+
+
+--
+-- Check handling of CLR settings.
+--
+
+ function suite.cflags_onClrOn()
+ clr "On"
+ prepare()
+ test.contains("/clr", msc.getcflags(cfg))
+ end
+
+ function suite.cflags_onClrUnsafe()
+ clr "Unsafe"
+ prepare()
+ test.contains("/clr", msc.getcflags(cfg))
+ end
+
+ function suite.cflags_onClrSafe()
+ clr "Safe"
+ prepare()
+ test.contains("/clr:safe", msc.getcflags(cfg))
+ end
+
+ function suite.cflags_onClrPure()
+ clr "Pure"
+ prepare()
+ test.contains("/clr:pure", msc.getcflags(cfg))
+ end