Build/Core/Legacy/jsonProcessor.lua

471 lines
13 KiB
Lua

local auProject = auRequire("Core/project").startProject
local valaGo = auRequire("Core/Vala")
function JsonProcessor(info)
local result, err = json.decode(io.readfile(info.jpath))
if (not result) then
fatal("parse error", info.path, err)
return
end
if (not info.name) then
info.name = result.name
end
result.name = info.name
local translateDep = function(this, dep)
return this:translateDep(dep)
end
-- ported
local includeDirEx = function(path, incFiles)
includedirs(path)
if (not incFiles) then
return
end
files(path .. "/**.h")
files(path .. "/**.hpp")
files(path .. "/**.inl")
end
local handleUserJsonInclude = function(path, prefix, inc)
includeDirEx(prefix .. "/" .. path, inc)
end
local handleJSONInclude = function(result, val, incFiles)
if (not result.include) then
if (val) then
return
end
includeDirEx (info.path, incFiles)
return
end
auForEach(result.include, handleUserJsonInclude, info.path, incFiles)
end
local handleInclude = function(this, incFiles)
local otherREsult = info
local result = this.result
auForEach(result.defines, defines)
if (result.type:lower() == "aurora") then
includeDirEx(info.path .. "/Include")
elseif (result.type:lower() == "lazy_free") then
includeDirEx(info.path)
handleJSONInclude(result, false, incFiles)
elseif (result.type:lower() == "root") then
includeDirEx(info.path)
handleJSONInclude(result, result.noRootInclude, incFiles)
elseif (result.type:lower() == "generic") then
handleJSONInclude(result, false, incFiles)
elseif ((result.type:lower() == "utility") or (result.type:lower() == "blank")) then
return
end
end
local handleBuildEvent = function(obj)
local type = ""
if ( obj.lua) then
type = "lua"
elseif (obj.bin) then
type = "bin"
else
return
end
auAddBuildAction(obj.when, type, obj[type], obj.isCwdProjRoot)
end
local handleDllImportMaybe = function(this)
if (this.info.isShared) then
auForEach(this.result.dllimport, defines)
end
end
local handleDllExportMaybe = function(this)
if (this.info.isShared) then
auForEach(this.result.dllexport, defines)
end
end
local handleDependsShort = function(dep, this, soft)
dep = translateDep(this, dep)
local processor = auGetProjectProcessor(this:translateDep(dep))
if (not processor) then
if (soft) then
print("Not including, ", dep)
return
end
fatal("Missing project", dep)
end
if (auIsProjectIntialized(dep) and not _G["_linkingcur"][dep]) then
processor:handleLink()
end
end
local processJsonBlockForLinks = function(object, this)
auForEach(object.links, links)
auForEach(object.depends, handleDependsShort, this, false)
auForEach(object["soft-depends"], handleDependsShort, this, true)
end
function handleEvalForLinks(object, this)
if (auIsArray(object)) then
auForEach(object, handleEvalForLinks, this)
return
end
if (type(object) == "string") then
return
end
processJsonBlockForLinks(object, this)
end
local handleActionCommon = function(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 (action.eval) then
cb(action.eval, ...)
end
end
_G["info"] = nil
end
local handleActionsForLinks = function(action, this)
handleActionCommon(action, handleEvalForLinks, this)
end
local processSubLinks = function(this)
processJsonBlockForLinks(result, this)
auForEach(result.actions, handleActionsForLinks, this)
end
local handleSourcesRel = function(source, path)
files(path .. "/" .. source)
end
local handleLink = function(this)
dependson(this.info.name)
auForEach(result.linkSources, handleSourcesRel, info.path)
local erase = false;
if (not _G["_linkingcur"]) then
erase = true
_G["_linkingcur"] = {}
end
_G["_linkingcur"][this.info.name] = true
local type = this.result.type
if ((type:lower() == "utility") or (type:lower() == "blank")) then
return
end
if ((not this.result.noLink)) then
links(this.info.name)
end
--if (not this.info.isStatic) then
processSubLinks(this)
--end
if (erase) then
_G["_linkingcur"] = nil
end
end
local publicDepends = function(name, this, soft)
auIncludeProject(this:translateDep(name), soft) -- evil recursion
end
local handleReference = function(this, circular)
local type = this.result.type
if ((type:lower() == "utility") or (type:lower() == "blank")) then
return
end
local cur = nil
if (circular) then
cur = auGetCurrentProjectMeta()
else
cur = this.info
end
if (cur and cur.isShared) then
-- shared libraries are only allowed to import other shared libraries
handleDllImportMaybe(this)
elseif (cur and cur.isStatic) then
-- static libs are allowed to reference dllexports in translation units of the parent shared module
handleDllExportMaybe(this)
auForEach(result.staticImport, defines)
end
if (this.info.isStatic) then
auForEach(result.staticImpDefines, defines)
end
auForEach(result["include-depends"], publicDepends, this, false)
auForEach(result["include-soft-depends"], publicDepends, this, true)
handleInclude(this, false)
defines(("_auhas_" .. this.result.name):upper():gsub("%-", "_") .. "=1")
end
local handleDependsPreemptive = function(dep, this, soft, resolve)
dep = translateDep(this, dep)
if (not auIsProjectIntialized(dep)) then
resolve(dep, soft)
end
end
local pokeDeps = function(this, resolve)
local result = this.result
auForEach(result.depends, handleDependsPreemptive, this, false, resolve)
auForEach(result["soft-depends"], handleDependsPreemptive, this, true, resolve)
end
local handleParse = function(this)
end
local handleProcess = function (a)
local result = a.result
local name = a.info.name
local path = a.info.path
local isUtility = false
info.copy_build_files = {}
local function runCopies(prefix, rootPath, name)
local referenceRoot = auGetRoot() .. "/Build_UserScripts/" .. name .. "/"
local referencePath = referenceRoot .. prefix
local copyRoot = rootPath .. "/" .. prefix
info.copy_build_files[_G.path.getrelative(referencePath, path)] = prefix
if (not os.isfile(copyRoot)) then
os.copyfile(referencePath, copyRoot)
end
end
auForEach(result.unpack, runCopies, info.path, info.name)
local prj_ = {
name = info.name,
projectType = info.projectType or result.projectType,
dest = info.out,
noLink = result.noLink
}
if (result.noLink) then
print("noLink is deprecated. Use projectType: none")
prj_.projectType = "none"
info.projectType = "none"
end
if (result.type:lower() == "aurora") then
local srcPath = path .. "/Source"
local incPath = path .. "/Include" -- /Source is emitted by design. Use it as a prefix in <> includes; eg, #include <Source/MyLib.hpp>
prj_.src = srcPath
prj_.inc = {incPath, path}
auProject(prj_)
elseif (result.type:lower() == "lazy_free") then
prj_.src = path .. "/*.*"
prj_.inc = path .. "/"
auProject(prj_)
elseif (result.type:lower() == "root") then
prj_.src = path
prj_.inc = path
auProject(prj_)
elseif (result.type:lower() == "generic") then
auProject(prj_)
elseif (result.type:lower() == "utility") then
project(name)
kind "utility"
isUtility = true
elseif (result.type:lower() == "blank") then
return
else
print "invalid project type"
os.exit()
end
_G["_linkingcur"] = {}
_G["_linkingcur"][name] = true
handleInclude(a, true)
local handleDepends = function(dep, this, soft)
local processor = auGetProjectProcessor(this:translateDep(dep))
if (not processor) then
if (soft) then
print("Not including, ", dep)
return
end
fatal("Missing project", dep)
end
local macro = ("_auhas_" .. dep):upper():gsub("%-", "_");
if (auIsProjectIntialized(dep)) then
defines(macro .. "=1")
processor:handleReference(isWeakCircularReference(dep))
if (not this.info.isStatic) then
processor:handleLink()
end
else
defines(macro .. "=0")
if (not soft) then
fatal("missing project: ", dep)
end
end
end
info.m4_files = {}
local addM4Defines = function(obj)
if (not obj) then return end
for fk, fv in pairs(obj) do
local fileTbl = info.m4_files[fk] or {}
info.m4_files[fk] = fileTbl
for k, v in pairs(fv) do
fileTbl[k] = v
end
end
end
local processJsonBlock = function(object)
auRequire("Core/JSON/JSON").projectHandlers.runProjectBlock(a, object)
auForEach(object["soft-depends"], handleDepends, a, true)
auForEach(object.unpack, runCopies, info.path, info.name)
addM4Defines(object.m4Defines)
end
function handleEval(object)
if (auIsArray(object)) then
auForEach(object, handleEval)
return
end
if (type(object) == "string") then
auEval(object)
return
end
processJsonBlock(object)
end
local handleAction = function(action)
handleActionCommon(action, handleEval)
end
if (not isUtility) then
processJsonBlock(result)
if (a.info.projectType:lower() == "sharedlib") then
auForEach(result.dllexport, defines)
end
end
if (result.valaSrc) then
local sources = result.valaSrc
local gir = concatArrays(auValaGirs, result.valaGirs)
local vapi = concatArrays(auValaDevVApis, result.valaDevVApis)
local valIncludes = result.valaInclude
local valGirFile = result.valGirFile
local header = result.valaHeader
local name = result.valaName
local extended =
{
sources = sources,
gir = gir,
vapi = vapi,
vapi = vapi,
package = valIncludes,
header = header,
girFile = valGirFile,
name = name
}
valaGo(extended)
end
auForEach(result.events, handleBuildEvent, info.path)
_G["_linkingcur"] = nil
end
auForEach(result.subprojs, function(subproj)
local subinfo = {
namespace = info.namespace,
path = info.path .. "/" .. subproj.path,
projectType = subproj.projectType,
out = info.out,
name = nil,
translations = info.translations
}
addVist(subinfo)
end)
local interface = {}
interface.result = result
interface.info = info
interface.resolveDependencies = pokeDeps
interface.process = handleProcess
interface.handleLink = handleLink
interface.handleReference = handleReference
return interface
end
return JsonProcessor