2021-05-21 19:15:38 +00:00
|
|
|
local auProject = require("project")
|
2021-05-20 12:56:44 +00:00
|
|
|
|
|
|
|
function JsonProcessor(info)
|
2021-05-27 10:02:12 +00:00
|
|
|
local result, err = json.decode(io.readfile(info.jpath))
|
2021-05-20 12:56:44 +00:00
|
|
|
|
|
|
|
if (not result) then
|
2021-06-03 13:00:02 +00:00
|
|
|
fatal("parse error", info.path, err)
|
2021-05-20 12:56:44 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
if (not info.name) then
|
|
|
|
info.name = result.name
|
|
|
|
end
|
|
|
|
|
2021-06-17 23:58:12 +00:00
|
|
|
local translateDep = function(this, dep)
|
|
|
|
|
|
|
|
if (this.info.translations) then
|
|
|
|
local override = this.info.translations[dep]
|
|
|
|
if (override) then
|
|
|
|
dep = override
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return dep
|
|
|
|
end
|
|
|
|
|
2021-06-03 13:00:02 +00:00
|
|
|
local includeDirEx = function(path, incFiles)
|
|
|
|
includedirs(path)
|
2021-05-20 12:56:44 +00:00
|
|
|
|
2021-06-03 13:00:02 +00:00
|
|
|
if (not incFiles) then
|
|
|
|
return
|
2021-05-20 12:56:44 +00:00
|
|
|
end
|
2021-06-03 13:00:02 +00:00
|
|
|
|
|
|
|
files(path .. "/**.h")
|
|
|
|
files(path .. "/**.hpp")
|
|
|
|
files(path .. "/**.inl")
|
|
|
|
end
|
2021-05-20 12:56:44 +00:00
|
|
|
|
2021-06-03 13:00:02 +00:00
|
|
|
local handleUserJsonInclude = function(path, prefix, inc)
|
|
|
|
includeDirEx(prefix .. "/" .. path, inc)
|
2021-05-20 12:56:44 +00:00
|
|
|
end
|
|
|
|
|
2021-06-03 13:00:02 +00:00
|
|
|
local handleJSONInclude = function(result, val, incFiles)
|
|
|
|
if (not result.include) then
|
|
|
|
if (val) then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
includeDirEx (info.path, incFiles)
|
|
|
|
return
|
2021-05-21 19:15:38 +00:00
|
|
|
end
|
2021-06-03 13:00:02 +00:00
|
|
|
|
|
|
|
forEach(result.include, handleUserJsonInclude, info.path, incFiles)
|
2021-05-21 19:15:38 +00:00
|
|
|
end
|
|
|
|
|
2021-06-03 13:00:02 +00:00
|
|
|
local handleInclude = function(this, incFiles)
|
|
|
|
local otherREsult = info
|
2021-05-20 12:56:44 +00:00
|
|
|
local result = this.result
|
2021-05-21 19:15:38 +00:00
|
|
|
|
2021-06-03 13:00:02 +00:00
|
|
|
forEach(result.defines, defines)
|
|
|
|
|
2021-05-20 12:56:44 +00:00
|
|
|
if (result.type:lower() == "aurora") then
|
2021-06-03 13:00:02 +00:00
|
|
|
includeDirEx(info.path .. "/Include")
|
2021-05-21 19:15:38 +00:00
|
|
|
elseif (result.type:lower() == "lazy_free") then
|
2021-06-03 13:00:02 +00:00
|
|
|
includeDirEx(info.path)
|
|
|
|
handleJSONInclude(result, false, incFiles)
|
2021-05-21 19:15:38 +00:00
|
|
|
elseif (result.type:lower() == "root") then
|
2021-06-03 13:00:02 +00:00
|
|
|
includeDirEx(info.path)
|
|
|
|
handleJSONInclude(result, result.noRootInclude, incFiles)
|
2021-05-21 19:15:38 +00:00
|
|
|
elseif (result.type:lower() == "generic") then
|
2021-06-03 13:00:02 +00:00
|
|
|
handleJSONInclude(result, false, incFiles)
|
2021-05-21 19:34:30 +00:00
|
|
|
elseif ((result.type:lower() == "utility") or (result.type:lower() == "blank")) then
|
2021-05-21 19:15:38 +00:00
|
|
|
return
|
2021-05-20 12:56:44 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-05-28 03:36:12 +00:00
|
|
|
local handleBuildEvent = function(obj)
|
2021-05-20 12:56:44 +00:00
|
|
|
local type = ""
|
|
|
|
if ( obj.lua) then
|
|
|
|
type = "lua"
|
|
|
|
elseif (obj.bin) then
|
|
|
|
type = "bin"
|
|
|
|
else
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2021-05-28 03:36:12 +00:00
|
|
|
addBuildAction(obj.when, type, obj[type], obj.isCwdProjRoot)
|
2021-05-20 12:56:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
local handleDllImportMaybe = function(this)
|
|
|
|
if (this.info.isShared) then
|
2021-06-06 12:15:07 +00:00
|
|
|
forEach(this.result.dllimport, defines)
|
2021-05-20 12:56:44 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local handleDllExportMaybe = function(this)
|
|
|
|
if (this.info.isShared) then
|
2021-06-06 12:15:07 +00:00
|
|
|
forEach(this.result.dllexport, defines)
|
2021-05-20 12:56:44 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-06-17 23:58:12 +00:00
|
|
|
local handleDependsShort = function(dep, this, soft)
|
|
|
|
dep = translateDep(this, dep)
|
|
|
|
|
|
|
|
local proj = _G["projectsprocessor"][dep]
|
|
|
|
if (not proj) then
|
|
|
|
if (soft) then
|
|
|
|
print("Not including, ", dep)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
fatal("Missing project", dep)
|
|
|
|
end
|
|
|
|
|
|
|
|
local iface = proj.processor
|
|
|
|
if (isProjectLoaded(dep) and not _G["_linkingcur"][dep]) then
|
|
|
|
iface:handleLink()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local processJsonBlockForLinks = function(object, this)
|
|
|
|
forEach(object.links, links)
|
|
|
|
forEach(object.depends, handleDependsShort, this, false)
|
|
|
|
forEach(object["soft-depends"], handleDependsShort, this, true)
|
|
|
|
end
|
|
|
|
|
|
|
|
function handleEvalForLinks(object, this)
|
|
|
|
if (isArray(object)) then
|
|
|
|
forEach(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
|
|
|
|
|
|
|
|
local loadstring = loadstring or load
|
|
|
|
|
|
|
|
if (_if) then
|
|
|
|
local val = eval("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)
|
|
|
|
forEach(result.actions, handleActionsForLinks, this)
|
|
|
|
end
|
|
|
|
|
2021-07-02 05:27:32 +00:00
|
|
|
local handleSourcesRel = function(source, path)
|
|
|
|
files(path .. "/" .. source)
|
|
|
|
end
|
|
|
|
|
2021-05-20 12:56:44 +00:00
|
|
|
local handleLink = function(this)
|
2021-06-17 23:58:12 +00:00
|
|
|
dependson (this.info.name)
|
|
|
|
|
2021-07-02 05:27:32 +00:00
|
|
|
forEach(result.linkSources, handleSourcesRel, info.path)
|
|
|
|
|
2021-06-17 23:58:12 +00:00
|
|
|
local erase = false;
|
|
|
|
if (not _G["_linkingcur"]) then
|
|
|
|
erase = true
|
|
|
|
_G["_linkingcur"] = {}
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
_G["_linkingcur"][this.info.name] = true
|
|
|
|
|
2021-06-03 13:00:02 +00:00
|
|
|
local type = this.result.type
|
2021-05-21 19:15:38 +00:00
|
|
|
|
2021-05-21 19:34:30 +00:00
|
|
|
if ((type:lower() == "utility") or (type:lower() == "blank")) then
|
2021-05-21 19:15:38 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2021-06-17 23:58:12 +00:00
|
|
|
if ((not this.result.noLink)) then
|
2021-06-03 13:00:02 +00:00
|
|
|
links(this.info.name)
|
|
|
|
end
|
2021-06-17 23:58:12 +00:00
|
|
|
|
|
|
|
--if (not this.info.isStatic) then
|
|
|
|
processSubLinks(this)
|
|
|
|
--end
|
|
|
|
|
|
|
|
if (erase) then
|
|
|
|
_G["_linkingcur"] = nil
|
|
|
|
end
|
2021-05-20 12:56:44 +00:00
|
|
|
end
|
|
|
|
|
2021-06-04 18:39:11 +00:00
|
|
|
local handleReference = function(this, circular)
|
2021-05-21 19:15:38 +00:00
|
|
|
local type = this.result.type
|
|
|
|
|
2021-05-21 19:34:30 +00:00
|
|
|
if ((type:lower() == "utility") or (type:lower() == "blank")) then
|
2021-05-21 19:15:38 +00:00
|
|
|
return
|
|
|
|
end
|
2021-05-20 12:56:44 +00:00
|
|
|
|
2021-06-04 18:39:11 +00:00
|
|
|
local cur = nil
|
|
|
|
if (circular) then
|
|
|
|
cur = getProjectInfo(getCurrentProjectName())
|
|
|
|
else
|
|
|
|
cur = this.info
|
|
|
|
end
|
|
|
|
|
2021-05-20 12:56:44 +00:00
|
|
|
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)
|
2021-06-04 18:39:11 +00:00
|
|
|
|
|
|
|
forEach(result.staticImport, defines)
|
2021-05-20 12:56:44 +00:00
|
|
|
end
|
|
|
|
|
2021-06-06 12:15:07 +00:00
|
|
|
if (this.info.isStatic) then
|
|
|
|
forEach(result.staticImpDefines, defines)
|
|
|
|
end
|
|
|
|
|
2021-06-04 18:39:11 +00:00
|
|
|
handleInclude(this, false)
|
2021-06-03 13:00:02 +00:00
|
|
|
|
|
|
|
defines(("_auhas_" .. this.result.name):upper() .. "=1")
|
|
|
|
end
|
|
|
|
|
2021-06-07 16:50:22 +00:00
|
|
|
local handleDependsPreemptive = function(dep, this, soft, resolve)
|
2021-06-03 13:00:02 +00:00
|
|
|
dep = translateDep(this, dep)
|
|
|
|
|
|
|
|
if (not isProjectLoaded(dep)) then
|
2021-06-07 16:50:22 +00:00
|
|
|
resolve(dep, soft)
|
2021-06-03 13:00:02 +00:00
|
|
|
end
|
2021-05-20 12:56:44 +00:00
|
|
|
end
|
|
|
|
|
2021-06-07 16:50:22 +00:00
|
|
|
local pokeDeps = function(this, resolve)
|
|
|
|
local result = this.result
|
|
|
|
forEach(result.depends, handleDependsPreemptive, this, false, resolve)
|
|
|
|
forEach(result["soft-depends"], handleDependsPreemptive, this, true, resolve)
|
|
|
|
end
|
|
|
|
|
|
|
|
local handleParse = function(this)
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2021-05-20 12:56:44 +00:00
|
|
|
local handleProcess = function (a)
|
|
|
|
local result = a.result
|
|
|
|
local name = a.info.name
|
|
|
|
local path = a.info.path
|
|
|
|
|
2021-05-21 19:34:30 +00:00
|
|
|
local isUtility = false
|
2021-05-21 19:15:38 +00:00
|
|
|
|
2021-05-20 12:56:44 +00:00
|
|
|
if (result.type:lower() == "aurora") then
|
|
|
|
local srcPath = path .. "/Source"
|
|
|
|
local incPath = path .. "/Include"
|
|
|
|
|
2021-05-21 19:15:38 +00:00
|
|
|
auProject(name, a.info.projectType, {srcPath}, {srcPath, incPath}, a.info.out, path)
|
2021-05-20 12:56:44 +00:00
|
|
|
|
|
|
|
elseif (result.type:lower() == "lazy_free") then
|
2021-05-21 19:15:38 +00:00
|
|
|
auProject(name, a.info.projectType, {path .. "/*.*"}, {path .. "/"}, a.info.out, path)
|
2021-05-20 12:56:44 +00:00
|
|
|
|
|
|
|
elseif (result.type:lower() == "root") then
|
2021-06-03 13:00:02 +00:00
|
|
|
auProject(name, a.info.projectType, path, path, a.info.out, path)
|
2021-05-20 12:56:44 +00:00
|
|
|
|
2021-06-03 13:00:02 +00:00
|
|
|
elseif (result.type:lower() == "generic") then
|
2021-05-21 19:15:38 +00:00
|
|
|
auProject(name, a.info.projectType, nil, nil, a.info.out, path)
|
2021-05-20 12:56:44 +00:00
|
|
|
|
2021-05-21 19:15:38 +00:00
|
|
|
elseif (result.type:lower() == "utility") then
|
|
|
|
project(name)
|
|
|
|
kind "utility"
|
2021-05-21 19:34:30 +00:00
|
|
|
isUtility = true
|
2021-05-21 19:15:38 +00:00
|
|
|
|
2021-05-21 19:34:30 +00:00
|
|
|
elseif (result.type:lower() == "blank") then
|
2021-05-21 19:15:38 +00:00
|
|
|
return
|
2021-05-20 12:56:44 +00:00
|
|
|
|
|
|
|
else
|
2021-05-21 19:34:30 +00:00
|
|
|
print "invalid project type"
|
2021-05-20 12:56:44 +00:00
|
|
|
os.exit()
|
|
|
|
end
|
|
|
|
|
2021-06-17 23:58:12 +00:00
|
|
|
|
|
|
|
_G["_linkingcur"] = {}
|
|
|
|
_G["_linkingcur"][name] = true
|
|
|
|
|
2021-06-03 13:00:02 +00:00
|
|
|
handleInclude(a, true)
|
|
|
|
|
|
|
|
--forEach(result.defines, defines)
|
|
|
|
--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
|
2021-05-20 12:56:44 +00:00
|
|
|
|
|
|
|
local handleFeature = function(feature)
|
|
|
|
addFeature(feature)
|
|
|
|
end
|
|
|
|
|
|
|
|
local handleRequire = function(dep)
|
2021-06-03 13:00:02 +00:00
|
|
|
dep = translateDep(a, dep)
|
2021-05-20 12:56:44 +00:00
|
|
|
|
|
|
|
dependson(dep)
|
|
|
|
end
|
|
|
|
|
2021-06-07 16:50:22 +00:00
|
|
|
local handleDepends = function(dep, this, soft)
|
|
|
|
dep = translateDep(this, dep)
|
2021-05-20 12:56:44 +00:00
|
|
|
|
2021-06-03 13:00:02 +00:00
|
|
|
local proj = _G["projectsprocessor"][dep]
|
|
|
|
if (not proj) then
|
|
|
|
if (soft) then
|
|
|
|
print("Not including, ", dep)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
fatal("Missing project", dep)
|
|
|
|
end
|
2021-05-20 12:56:44 +00:00
|
|
|
|
2021-06-07 16:50:22 +00:00
|
|
|
local iface = proj.processor
|
|
|
|
|
2021-05-20 12:56:44 +00:00
|
|
|
if (isProjectLoaded(dep)) then
|
|
|
|
defines(("_auhas_" .. dep):upper() .. "=1")
|
2021-06-22 18:27:45 +00:00
|
|
|
|
|
|
|
iface:handleReference(isWeakCircularReference(dep))
|
|
|
|
|
2021-06-17 23:58:12 +00:00
|
|
|
if (not this.info.isStatic) then
|
|
|
|
iface:handleLink()
|
|
|
|
end
|
2021-05-20 12:56:44 +00:00
|
|
|
else
|
|
|
|
defines(("_auhas_" .. dep):upper() .. "=0")
|
|
|
|
if (not soft) then
|
2021-06-03 13:00:02 +00:00
|
|
|
fatal("missing project: ", dep)
|
2021-05-20 12:56:44 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-06-03 13:00:02 +00:00
|
|
|
local handleExcludes = function(excludes, path)
|
|
|
|
removefiles(excludes)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local handleSources = function(source, path)
|
|
|
|
--files(path .. "/" .. source)
|
|
|
|
files(source)
|
|
|
|
end
|
|
|
|
|
|
|
|
local handleSourcePaths = function(source, path)
|
|
|
|
files
|
|
|
|
{
|
|
|
|
path .. "/" .. source .. "/**.*pp",
|
|
|
|
path .. "/" .. source .. "/**.inl",
|
|
|
|
path .. "/" .. source .. "/**.c",
|
|
|
|
path .. "/" .. source .. "/**.cc",
|
|
|
|
path .. "/" .. source .. "/**.h",
|
|
|
|
path .. "/" .. source .. "/**.masm"
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
local processJsonBlock = function(object)
|
|
|
|
forEach(object.features, handleFeature, info.path)
|
|
|
|
forEach(object.sourcePaths, handleSourcePaths, info.path)
|
|
|
|
forEach(object.excludes, handleExcludes, info.path)
|
|
|
|
forEach(object.sources, handleSources, info.path)
|
|
|
|
forEach(object.depends, handleDepends, a, false)
|
|
|
|
forEach(object["soft-depends"], handleDepends, a, true)
|
|
|
|
forEach(object.impDefines, defines)
|
2021-06-06 12:15:07 +00:00
|
|
|
forEach(object.links, links)
|
2021-06-04 18:39:11 +00:00
|
|
|
if (usingMSVC) then
|
|
|
|
forEach(object.msvcIgnore, disablewarnings)
|
|
|
|
end
|
|
|
|
if (usingClang) then
|
|
|
|
forEach(object.clangIgnore, disablewarnings)
|
|
|
|
end
|
2021-06-03 13:00:02 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function handleEval(object)
|
|
|
|
if (isArray(object)) then
|
|
|
|
forEach(object, handleEval)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
if (type(object) == "string") then
|
|
|
|
eval(object)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
processJsonBlock(object)
|
|
|
|
end
|
|
|
|
|
2021-05-20 12:56:44 +00:00
|
|
|
local handleAction = function(action)
|
2021-06-17 23:58:12 +00:00
|
|
|
handleActionCommon(action, handleEval)
|
2021-05-20 12:56:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
forEach(result.require, handleRequire)
|
|
|
|
|
2021-05-21 19:34:30 +00:00
|
|
|
if (not isUtility) then
|
2021-06-03 13:00:02 +00:00
|
|
|
processJsonBlock(result)
|
|
|
|
forEach(result.impInclude, handleUserJsonInclude, info.path, true)
|
2021-05-20 12:56:44 +00:00
|
|
|
|
2021-05-21 19:15:38 +00:00
|
|
|
if (a.info.projectType:lower() == "sharedlib") then
|
2021-06-06 12:15:07 +00:00
|
|
|
forEach(result.dllexport, defines)
|
2021-05-21 19:15:38 +00:00
|
|
|
end
|
|
|
|
end
|
2021-05-20 12:56:44 +00:00
|
|
|
|
|
|
|
forEach(result.actions, handleAction, info.path)
|
2021-05-28 03:36:12 +00:00
|
|
|
forEach(result.events, handleBuildEvent, info.path)
|
2021-05-20 12:56:44 +00:00
|
|
|
|
2021-06-06 12:15:07 +00:00
|
|
|
if (info.isStatic) then
|
|
|
|
forEach(result.staticImpDefines, defines)
|
|
|
|
end
|
|
|
|
|
2021-06-17 23:58:12 +00:00
|
|
|
_G["_linkingcur"] = nil
|
|
|
|
|
2021-05-20 12:56:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
forEach(result.subprojs, function(subproj)
|
|
|
|
|
|
|
|
local subinfo = {
|
|
|
|
namespace = info.namespace,
|
|
|
|
path = info.path .. "/" .. subproj.path,
|
2021-05-21 19:15:38 +00:00
|
|
|
projectType = subproj.projectType,
|
2021-05-20 12:56:44 +00:00
|
|
|
out = info.out,
|
|
|
|
name = nil,
|
|
|
|
translations = info.translations
|
|
|
|
}
|
|
|
|
|
|
|
|
addVist(subinfo)
|
|
|
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
local interface = {}
|
|
|
|
interface.result = result
|
|
|
|
interface.info = info
|
2021-06-07 16:50:22 +00:00
|
|
|
interface.resolveDependencies = pokeDeps
|
2021-05-20 12:56:44 +00:00
|
|
|
interface.process = handleProcess
|
|
|
|
interface.handleLink = handleLink
|
|
|
|
interface.handleReference = handleReference
|
|
|
|
return interface
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
return JsonProcessor
|