Build/Boilerplate/jsonProcessor.lua

302 lines
8.8 KiB
Lua
Raw Normal View History

local auProject = require("project")
function JsonProcessor(info)
local result, err = json.decode(io.readfile(info.path .. "/Aurora.json"))
if (not result) then
print("parse error", info.path, err)
return
end
if (not info.name) then
info.name = result.name
end
local handleUserJsonInclude = function(path)
includedirs(info.path .. "/" .. path)
end
local handleJSONInclude = function(result)
if (not result.include) then
includedirs (info.path)
return
end
forEach(result.include, handleUserJsonInclude)
end
local tryAddDefine = function(aaa)
if (aaa) then
defines(aaa)
end
end
local handleInclude = function(this)
local result = this.result
if (result.type:lower() == "aurora") then
includedirs (info.path .. "/Include")
elseif (result.type:lower() == "lazy_free") then
handleJSONInclude(result)
elseif (result.type:lower() == "root") then
includedirs (info.path)
handleJSONInclude(result)
elseif (result.type:lower() == "pair") then
includedirs (info.srcInclude)
handleJSONInclude(result)
elseif (result.type:lower() == "generic") then
handleJSONInclude(result)
elseif (result.type:lower() == "empty") then
handleJSONInclude(result)
elseif ((result.type:lower() == "utility") or (result.type:lower() == "null")) then
return
end
tryAddDefine(result.defines)
end
local handlePostBuild = function(obj)
local type = ""
if ( obj.lua) then
type = "lua"
elseif (obj.bin) then
type = "bin"
else
return
end
addBuildAction(obj.when, type, obj[type])
end
local handleDllImportMaybe = function(this)
if (this.info.isShared) then
defines(this.result.dllimport)
end
end
local handleDllExportMaybe = function(this)
if (this.info.isShared) then
defines(this.result.dllexport)
end
end
local handleLink = function(this)
dependson(this.info.name)
if ((type:lower() == "utility") or (type:lower() == "null")) then
return
end
links(this.info.name)
handleDllImportMaybe(this)
end
local handleReference = function(this)
local type = this.result.type
if ((type:lower() == "utility") or (type:lower() == "null")) then
return
end
local cur = getProjectInfo(getCurrentProjectName())
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)
end
handleInclude(this)
end
local handleProcess = function (a)
local result = a.result
local name = a.info.name
local path = a.info.path
local isBlank = false
if (result.type:lower() == "aurora") then
local srcPath = path .. "/Source"
local incPath = path .. "/Include"
auProject(name, a.info.projectType, {srcPath}, {srcPath, incPath}, a.info.out, path)
elseif (result.type:lower() == "lazy_free") then
auProject(name, a.info.projectType, {path .. "/*.*"}, {path .. "/"}, a.info.out, path)
elseif (result.type:lower() == "root") then
auProject(name, a.info.projectType, {path}, {path}, a.info.out, path)
elseif (result.type:lower() == "pair") then
auProject(name, a.info.projectType, {path .. "/" .. result.srcSource}, {path .. "/" .. result.srcInclude}, a.info.out, path)
elseif (result.type:lower() == "generic") then
print("type 'generic' is deprecated, use 'empty' instead")
print("'generic' will soon be replaced by the behaviour of 'aurora'")
auProject(name, a.info.projectType, nil, nil, a.info.out, path)
elseif (result.type:lower() == "empty") then
auProject(name, a.info.projectType, nil, nil, a.info.out, path)
elseif (result.type:lower() == "utility") then
project(name)
kind "utility"
isBlank = true
elseif (result.type:lower() == "null") then
return
else
print "invalid auProject type"
os.exit()
end
handleJSONInclude(result) -- include auProject public headers, do not use handleInclude, that could reinclude a header included in `project`
-- that could potentially fuck with #include_next
local handleFeature = function(feature)
addFeature(feature)
end
local translateDep = function(dep)
if (a.info.translations) then
local override = a.info.translations[dep]
if (override) then
dep = override
end
end
return dep
end
local handleRequire = function(dep)
dep = translateDep(dep)
dependson(dep)
end
local handleDepends = function (dep, soft)
dep = translateDep(dep)
local iface = _G["projectsprocessor"][dep]
if (isWeakCircularReference(dep)) then
print("handling circular reference", dep)
iface:handleReference()
return
end
if (not isProjectLoaded(dep)) then
processSubproject(dep)
end
if (isProjectLoaded(dep)) then
defines(("_auhas_" .. dep):upper() .. "=1")
iface:includeHeaders()
iface:handleLink()
else
defines(("_auhas_" .. dep):upper() .. "=0")
if (not soft) then
print("missing project: ", dep)
os.exit()
end
end
end
local handleAction = function(action)
local _if = action["if"]
local _then = action["then"]
_G["info"] = info
local cwd = os.getcwd()
os.chdir(info.path)
if (_if) then
print("DEBUG: IF?? ", _if)
local eval = loadstring("return " .. _if)
if (not eval) then
return
end
if (_then) then
print("DEBUG: EVAL ", _then)
forEach(_then, loadstring)
end
else
if (action.eval) then
print("DEBUG: EVAL ", action.eval)
forEach(action.eval, loadstring)
end
end
os.chdir(cwd)
_G["info"] = nil
end
local handleExcludes = function(excludes, path)
removefiles(path .. "/" .. excludes)
end
local handleSoftDepends = function(dep)
handleDepends(dep, true)
end
function handleSources(source, path)
files(path .. "/" .. source)
end
forEach(result.require, handleRequire)
if (not isBlank) then
forEach(result.features, handleFeature, info.path)
forEach(result.excludes, handleExcludes, info.path)
forEach(result.sources, handleSources, info.path)
forEach(result.depends, handleDepends, info.path)
forEach(result["soft-depends"], handleSoftDepends)
if (a.info.projectType:lower() == "sharedlib") then
tryAddDefine(result.dllexport)
end
tryAddDefine(result.impdefines)
defines(result.defines)
end
forEach(result.actions, handleAction, info.path)
forEach(result.postBuild, handlePostBuild, info.path)
forEach(result.preBuild, handlePreBuild, info.path)
end
forEach(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.process = handleProcess
interface.includeHeaders = handleInclude
interface.handleLink = handleLink
interface.handleReference = handleReference
return interface
end
return JsonProcessor