Build/Core/JSON/jsonProjectHandlers.lua
2022-03-04 17:05:38 +00:00

469 lines
14 KiB
Lua

local kTargetingCmake = false
local kTargetingWindows = os.host() == "windows"
local kBugHack = kTargetingCmake or kTargetingWindows
local auProjectBlockHandlers = {}
local kGenericTasks = {}
local __pRunTasks = function(processor, object, map, tasks, inc)
end
local function __pushFilter(obj, key, callback, expandArray)
if (not obj) then
return
end
local function runCallbackFe(value, key, callback, expandArray, isArray)
if (expandArray and isArray) then
auForEach(value, function(val)
__pushFilter(val, key, callback, false)
end)
else
callback(value)
end
end
if (type(obj) == "table") then
local value = nil
local isArray = false
if (auIsArray(obj)) then
value = obj
isArray = true
else
if (key) then
value = obj[key]
else
value = obj
end
if (not value) then
return
end
end
if (obj.filter) then
auFilter(auFilterOf(obj.filter))
end
runCallbackFe(value, key, callback, expandArray, isArray)
if (obj.filter) then
auFilter {}
end
else
if (expandArray) then -- fast path. we can skip this, if false. the if and statment doesnt optimize away the auIsArray anymore
runCallbackFe(obj, key, callback, true, auIsArray(obj))
else
callback(obj)
end
end
end
local function __handleIncludeCallback(processor, includeProject, callback)
if (type(processor) == "table") then
auForEachKV(processor, function(processorName, soft)
if (type(processorName) == "number") then
processorName = soft
soft = false
end
if (type(processorName) ~= "string") then
auFatal("what is my processor name?")
end
callback(processorName, not soft)
end)
else
if (type(processor) ~= "string") then
auFatal("what is my processor name? [2]", type(processor))
end
callback(processorName, true)
end
end
local function __translate(processor, key)
return processor:translateDep(key)
end
local function _includeDirectoryEx(path, incFiles)
includedirs(path)
if (not incFiles) then
return
end
files(path .. "/**.h")
files(path .. "/**.hpp")
files(path .. "/**.inl")
end
local function auBlockProjectKeyDefines(processor, value)
-- Required for dependent and current processor // global library configuration
__pushFilter(value, "value", defines)
end
local function auBlockProjectKeyIncludes(processor, value, map, tasks, inc)
_includeDirectoryEx(processor:getMeta().path .. "/" .. value, not inc)
end
local function auBlockProjectKeyFeatures(processor, value)
-- Runs special features / plugins defined in sAbsScripts/features
__pushFilter(value, "value", auAddFeature, true)
end
local function auBlockProjectKeyExcludes(processor, value)
__pushFilter(value, "value", removefiles)
end
local function auBlockProjectKeySources(processor, value)
--files(value) -- NOTE: this was once path .. / .. value
__pushFilter(value, "value", files)
end
local function auBlockProjectKeySourcePaths(processor, value)
local source = value
local path = processor:getMeta().path
files
{
path .. "/" .. source .. "/**.*pp",
path .. "/" .. source .. "/**.inl",
path .. "/" .. source .. "/**.c",
path .. "/" .. source .. "/**.cc",
path .. "/" .. source .. "/**.h",
path .. "/" .. source .. "/**.masm"
}
end
local function auBlockProjectKeyEval(processor, value, map, tasksMask)
if (type(object) == "string") then
auEval(object)
return
end
__pushFilter(value, nil, function(value)
__pRunTasks(processor, value, map, tasksMask, true)
end)
end
local function auBlockProjectKeyDefines(processor, value)
__pushFilter(value, "value", defines)
end
local function auBlockProjectKeyImplDefines(processor, value)
__pushFilter(value, "value", defines)
end
local function auBlockProjectKeyStaticImplDefines(processor, value)
if (not processor:getMeta().isStatic) then
return
end
__pushFilter(value, "value", defines)
end
local function auBlockKeyFeature(processor, value)
__pushFilter(value, "value", auAddFeature, true)
end
local function auBlockProjectKeyImplIncludes(processor, value)
__pushFilter(value, "value", _includeDirectoryEx)
end
local function auBlockProjectKeyClangIgnore(processor, value)
if (targetingCmake) then
filter {"toolset:clang"}
end
disablewarnings(value)
filter {}
end
local function auBlockProjectKeyMSVCIgnore(processor, value)
if (targetingCmake) then
filter {"toolset:msc"}
end
disablewarnings(value)
filter {}
end
local function _auBlockProjectKeyLinks(value, processor)
end
local function auBlockProjectKeyLinks(processor, value)
__pushFilter(value, "value", function(val)
links(__translate(processor, val))
end, true)
end
local function auHeaderProjectKeyIncludeDepends(processor, includeProject)
-- Projects that include
__handleIncludeCallback(processor, includeProject, function(processorName, hard)
auIncludeProject(__translate(processor, processorName), not hard)
end)
end
local function auHeaderProjectKeyLinkDepends(processor, includeProject)
__handleIncludeCallback(processor, includeProject, function(processorName, hard)
auLinkProject(__translate(processor, processorName), not hard)
end)
end
local function auBlockProjectKeyBuildEvent(processor, value)
__pushFilter(value, nil, function(value)
local type = ""
if (value.lua) then
type = "lua"
elseif (value.bin) then
type = "bin"
elseif (value.project) then
type = "project"
elseif (value.cmd) then
type = "cmd"
else
return
end
auAddBuildAction(value.when, type, value[type], value.isCwdProjRoot, value.args)
end, processor)
end
local function handleActionCommon(action, cb, ...)
local _if = action["if"]
local _then = action["then"]
--_G["info"] = info
if (_if) then
local val = auEval("return " .. _if)
if (not val) then
return
end
if (_then) then
cb(_then, ...)
end
else
if (not action.eval) then
action.eval = action["then"]
end
if (action.eval) then
cb(action.eval, ...)
end
end
--_G["info"] = nil
end
local function auBlockProjectKeyBuildAction(processor, value, map, tasks)
__pushFilter(value, nil, function(value)
handleActionCommon(value, function(thenblock)
auBlockProjectKeyEval(processor, thenblock, map, tasks)
end)
end, processor)
end
local function handleDepends(processor, dep, soft)
dep = processor:translateDep(dep)
local macro = ("_auhas_" .. dep):upper():gsub("%-", "_");
if (auGetProjectProcessor(dep)) then
defines(macro .. "=1")
auLinkAndRefProject(dep, soft)
else
--defines(macro .. "=0")
if (not soft) then
auFatal("missing project: ", dep)
end
end
end
local function auBlockProjectKeyDepends(processor, value)
__pushFilter(value, "value", function(obj)
handleDepends(processor, obj, false)
end, processor, true)
end
local function auBlockProjectKeyDllimport(processor, value)
__pushFilter(value, "value", defines, processor)
end
local function auBlockProjectKeyDllexport(processor, value)
__pushFilter(value, "value", defines, processor)
end
local function auBlockProjectKeySoftDepends(processor, value)
__pushFilter(value, "value", function(obj)
handleDepends(processor, obj, true)
end, processor, true)
end
local function auBlockProjectRefKeyInclSoftDepends(processor, value, taskMap, taskArray, inc, resolve)
__pushFilter(value, "value", function(obj)
resolve(processor:translateDep(obj), false)
end, processor, true)
end
local function auBlockProjectRefKeyInclDepends(processor, value, taskMap, taskArray, inc, resolve)
__pushFilter(value, "value", function(obj)
resolve(processor:translateDep(obj), false)
end, processor, true)
end
local function auBlockProjectRefKeyDepends(processor, value, taskMap, taskArray, inc, resolve)
__pushFilter(value, "value", function(obj)
resolve(processor:translateDep(obj), false)
end, processor, true)
end
local function auBlockProjectRefKeySoftDepends(processor, value, taskMap, taskArray, inc, resolve)
__pushFilter(value, "value", function(obj)
resolve(processor:translateDep(obj), true)
end, processor, true)
end
local function auBlockProjectKeyLua(processor, script)
auUserRequire(script)
end
local function auBlockProjectKeyImplNoRootInclude()
-- this is just a stub.
-- set me, the "noRootInclude" key to 'true' if you do not want the processor root to be include in the include dir search path
end
local auProjectHeaderHandlers =
{
linkDepends = auHeaderProjectKeyLinkDepends,
includeDepends = auHeaderProjectKeyIncludeDepends
}
local kAllProjectHeaders =
{
"linkDepends", "includeDepends"
}
auProjectBlockHandlers =
{
links = auBlockProjectKeyLinks,
lua = auBlockProjectKeyLua,
sourcePaths = auBlockProjectKeySourcePaths,
sources = auBlockProjectKeySources,
includes = auBlockProjectKeyIncludes,
include = auBlockProjectKeyIncludes,
excludes = auBlockProjectKeyExcludes,
eval = auBlockProjectKeyEval,
defines = auBlockProjectKeyDefines,
impDefines = auBlockProjectKeyImplDefines,
implDefines = auBlockProjectKeyImplDefines,
implementationDefines = auBlockProjectKeyImplDefines,
staticImpDefines = auBlockProjectKeyStaticImplDefines,
impInclude = auBlockProjectKeyImplIncludes,
implInclude = auBlockProjectKeyImplIncludes,
impIncludes = auBlockProjectKeyImplIncludes,
implIncludes = auBlockProjectKeyImplIncludes,
clangIgnore = auBlockProjectKeyClangIgnore,
msvcIgnore = auBlockProjectKeyMSVCIgnore,
depends = auBlockProjectKeyDepends,
require = auBlockProjectKeyRequire,
noRootInclude = auBlockProjectKeyImplNoRootInclude,
events = auBlockProjectKeyBuildEvent,
actions = auBlockProjectKeyBuildAction,
features = auBlockKeyFeature
}
auProjectBlockHandlers["soft-depends"] = auBlockProjectKeySoftDepends
local auProjectRefHandlers =
{
linkDepends = auHeaderProjectKeyLinkDepends,
eval = auBlockProjectKeyEval,
actions = auBlockProjectKeyBuildAction,
links = auBlockProjectKeyLinks,
defines = auBlockProjectKeyDefines,
include = auBlockProjectKeyIncludes,
includes = auBlockProjectKeyIncludes,
dllimport = auBlockProjectKeyDllimport,
dllexport = auBlockProjectKeyDllimport,
staticImport = auBlockProjectKeyDllimport,
staticImpDefines = auBlockProjectKeyDllimport
}
auProjectRefHandlers["soft-depends"] = auBlockProjectRefKeySoftDepends
auProjectRefHandlers["include-soft-depends"] = auBlockProjectRefKeyInclSoftDepends
auProjectRefHandlers["include-depends"] = auBlockProjectRefKeyInclDepends
auProjectRefHandlers["depends"] = auBlockProjectRefKeyDepends
kGenericTasks = {"sourcePaths", "includes","include", "sources",
"impDefines", "implDefines", "implementationDefines",
"impInclude", "implInclude", "impIncludes", "implIncludes", "clangIgnore",
"msvcIgnore", "excludes", "depends", "require",
"eval", "lua", "events", "actions", "staticImpDefines", "features",
"links", "soft-depends"
}
local kReferenceTasks = {"eval", "includes", "include", "includes"} --, "features"}
-- , "include-depends", "include-soft-depends"
__pRunTasks = function(processor, object, map, tasks, inc, resolve)
auForEachKV(tasks, function(na, key)
local value = object[key]
if (not value) then
return
end
map[key](processor, value, map, tasks, inc, resolve)
end)
end
local function __pRunLinkTasks(processor, object, resolve)
__pRunTasks(processor, object, auProjectRefHandlers, { "links", "depends", "soft-depends", "eval", "linkDepends", "defines", "actions"}, false, resolve)
end
local function __pRunIncludeTasks(processor, object, isIncludeLocalProject)
__pRunTasks(processor, object, auProjectBlockHandlers, kReferenceTasks, isIncludeLocalProject)
if (object.type:lower() == "aurora") then
_includeDirectoryEx(processor:getMeta().path .. "/Include")
elseif (object.type:lower() == "lazy_free") then
object.noRootInclude = false
elseif (object.type:lower() == "root") then
_includeDirectoryEx(processor:getMeta().path)
end
end
local function ___pRunIncludeTasks(processor, object, resolve)
__pRunIncludeTasks(processor, object, false)
if (not object.noRootInclude) then
_includeDirectoryEx(processor:getMeta().path, false)
end
end
local function ___pRunImportTask(processor, object, mask, resolve)
__pRunIncludeTasks(processor, object, false)
__pRunTasks(processor, object, auProjectRefHandlers, mask, false, resolve)
if (not object.noRootInclude) then
_includeDirectoryEx(processor:getMeta().path, false)
end
end
local function __pRunMainTasks(processor, object)
__pRunIncludeTasks(processor, object, true)
__pRunTasks(processor, object, auProjectBlockHandlers, kGenericTasks, true)
if (not object.noRootInclude) then
_includeDirectoryEx(processor:getMeta().path, isIncludeLocalProject)
end
end
return auCopyTables(auProjectHeaderHandlers, auProjectBlockHandlers, {
runProjectBlock = __pRunMainTasks,
runProjectLink = __pRunLinkTasks,
runProjectImport = ___pRunImportTask,
runProjectRef = ___pRunIncludeTasks
})