400 lines
9.3 KiB
Lua
400 lines
9.3 KiB
Lua
local jsonProcessor = auRequire("Core/Legacy/jsonProcessor")
|
|
|
|
-------------------------------------------------------
|
|
-- globals
|
|
-------------------------------------------------------
|
|
_auProjects = {}
|
|
_auProjectsBlocked = {}
|
|
_auNamespacesEmitted = {}
|
|
_auResolvedDep = {}
|
|
_auCurrentProject = {}
|
|
|
|
-------------------------------------------------------
|
|
-- utils
|
|
-------------------------------------------------------
|
|
|
|
local function normalizeSourceRoot(path)
|
|
local backup = path
|
|
path = os.realpath(_G.path.join(os.getcwd(), path));
|
|
if (not path) then
|
|
print("path error, not found?", backup)
|
|
return
|
|
end
|
|
return path
|
|
end
|
|
|
|
local function extendInfo(this)
|
|
local type = this.projectType:lower()
|
|
this.isShared = type == "sharedlib"
|
|
this.isStatic = type == "staticlib"
|
|
this.isExec = type == "consoleapp" or type == 'windowedapp'
|
|
this.isConsole = type == "consoleapp"
|
|
this.isWindowed = type == "windowedapp"
|
|
end
|
|
|
|
-------------------------------------------------------
|
|
-- project loading
|
|
-------------------------------------------------------
|
|
|
|
local function addVisit(ina)
|
|
local args = {
|
|
namespace = ina.namespace,
|
|
name = ina.name, -- OPT: recommended
|
|
path = ina.path,
|
|
type = ina.type,
|
|
out = ina.out,
|
|
options = ina.options,
|
|
translations = ina.translations -- OPT: dictionary of dependency maps
|
|
}
|
|
|
|
local path = normalizeSourceRoot(args.path)
|
|
if (not path) then
|
|
return
|
|
end
|
|
|
|
local info = {
|
|
namespace = args.namespace,
|
|
path = path,
|
|
projectType = args.type,
|
|
out = args.out,
|
|
name = args.name,
|
|
translations = args.translations,
|
|
options = args.options
|
|
}
|
|
|
|
extendInfo(info)
|
|
|
|
local project = {
|
|
info = info,
|
|
processor = nil,
|
|
deps = {}
|
|
}
|
|
|
|
local cwd = auGetRoot()
|
|
|
|
local remoteLua = path .. "/Aurora.lua"
|
|
local remoteJson = path .. "/Aurora.json"
|
|
local localJson = cwd .. Aurora.Settings.sRelRepoScripts .. "/" .. args.name .. ".aurora.json"
|
|
local localLua = cwd .. Aurora.Settings.sRelRepoScripts .. "/" .. args.name .. ".aurora.lua"
|
|
|
|
if (os.isfile(localLua)) then
|
|
project.processor = auRequireAbs(localLua)(info)
|
|
elseif (os.isfile(localJson)) then
|
|
info.jpath = localJson
|
|
project.processor = jsonProcessor(info)
|
|
elseif (os.isfile(remoteLua)) then
|
|
project.processor = auRequireAbs(remoteLua)(info)
|
|
elseif (os.isfile(remoteJson)) then
|
|
info.jpath = remoteJson
|
|
project.processor = jsonProcessor(info)
|
|
else
|
|
print("Couldnt find Aurora build script for: ", path)
|
|
return
|
|
end
|
|
|
|
auRequire("Core").project.expendBaseProcessor(project)
|
|
|
|
_auProjects[info.name] = project
|
|
end
|
|
|
|
|
|
local function addScript(ina)
|
|
local args = {
|
|
namespace = ina.namespace,
|
|
script = ina.script,
|
|
path = ina.path,
|
|
type = ina.type,
|
|
out = ina.out,
|
|
options = ina.options,
|
|
translations = ina.translations
|
|
}
|
|
|
|
local path = normalizeSourceRoot(args.path)
|
|
if (not path) then
|
|
return
|
|
end
|
|
|
|
local info = {
|
|
namespace = args.namespace,
|
|
path = path,
|
|
projectType = args.type,
|
|
out = args.out,
|
|
translations = args.translations,
|
|
options = args.options
|
|
}
|
|
|
|
extendInfo(info)
|
|
|
|
local project = {
|
|
info = info,
|
|
processor = nil,
|
|
deps = {}
|
|
}
|
|
|
|
local procesor = userRequire(args.script)
|
|
if (not procesor) then
|
|
processor = auRequireAbs(args.script)
|
|
if (not procesor) then
|
|
print("missing project script:", args.script, path)
|
|
return
|
|
end
|
|
end
|
|
|
|
project.processor = procesor(info)
|
|
if (not project.processor) then
|
|
print("script error")
|
|
return
|
|
end
|
|
|
|
_auProjects[info.name] = project
|
|
end
|
|
|
|
-- private
|
|
local function processInit(project)
|
|
if (project.isInitialized) then
|
|
return
|
|
end
|
|
project.isInitialized = true
|
|
|
|
if (project.processor.init) then
|
|
project.processor:init()
|
|
end
|
|
end
|
|
|
|
-- private
|
|
local function initializeDependencyTree(proj, resolveProject)
|
|
local name = proj.info.name
|
|
|
|
_auResolvedDep[name] = name
|
|
|
|
if (not proj.resolvedDeps) then
|
|
if (proj.processor.resolveDependencies) then
|
|
proj.processor:resolveDependencies(function(name, soft)
|
|
|
|
table.insert(proj.deps, name)
|
|
|
|
if (_auResolvedDep[name]) then
|
|
return
|
|
end
|
|
|
|
local depProj = _auProjects[name]
|
|
if (not depProj) then
|
|
if (not soft) then
|
|
auFatal("missing dependency: ", name)
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
initializeDependencyTree(depProj, true)
|
|
end)
|
|
end
|
|
proj.resolvedDeps = true
|
|
end
|
|
|
|
processInit(proj)
|
|
end
|
|
|
|
local processProject = {}
|
|
-- private
|
|
local function processNS(namespace)
|
|
local projs = {}
|
|
local projsIdxs = {}
|
|
|
|
auForEach(_auProjects, function(proj)
|
|
if (proj.info.namespace ~= namespace) then
|
|
return
|
|
end
|
|
|
|
local name = proj.info.name
|
|
projs[name] = proj
|
|
|
|
table.insert(projsIdxs, name)
|
|
end)
|
|
|
|
table.sort(projsIdxs, function(a, b)
|
|
return a:upper() < b:upper()
|
|
end)
|
|
|
|
auForEach(projsIdxs, function(idx)
|
|
initializeDependencyTree(projs[idx], true)
|
|
end)
|
|
|
|
auForEach(projsIdxs, function(idx)
|
|
processProject(projs[idx].info.name)
|
|
end)
|
|
end
|
|
|
|
local function processSolution()
|
|
local hack = {}
|
|
|
|
local hackIdx = {}
|
|
auForEach(_auProjects, function(proj)
|
|
table.insert(hackIdx, proj.info.namespace)
|
|
end)
|
|
|
|
table.sort(hackIdx, function(a, b)
|
|
return a:upper() < b:upper()
|
|
end)
|
|
|
|
auForEach(hackIdx, processNS)
|
|
end
|
|
|
|
local function attemptNS(ns)
|
|
local attemptLoad = false
|
|
if (not _auNamespacesEmitted[ns]) then
|
|
auStartGroup(ns) -- only print the group once
|
|
|
|
attemptLoad = true
|
|
end
|
|
|
|
group(ns)
|
|
return attemptLoad
|
|
end
|
|
|
|
processProject = function(name, required, noNs)
|
|
local a = _auProjects[name]
|
|
if (not a) then
|
|
if (required) then
|
|
auFatal("missing project: ", name)
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
-- ensure the project is initializd
|
|
processInit(a)
|
|
|
|
-- recursion protection
|
|
if (_auProjectsBlocked[name]) then
|
|
return true
|
|
end
|
|
_auProjectsBlocked[name] = name
|
|
|
|
-- process all within the namespace before processing the requested project
|
|
local ns = a.info.namespace
|
|
local loadOthers = attemptNS(ns)
|
|
|
|
-- {
|
|
local cwd = os.getcwd()
|
|
local old = _auCurrentProject
|
|
|
|
_auCurrentProject = name
|
|
os.chdir(a.info.path)
|
|
|
|
a.processor:process()
|
|
|
|
os.chdir(cwd)
|
|
_auCurrentProject = old
|
|
-- }
|
|
|
|
-- cont
|
|
if (loadOthers) then
|
|
_auNamespacesEmitted[ns] = "";
|
|
processNS(ns)
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
function isWeakCircularReference(depName)
|
|
local dep = _auProjects[depName]
|
|
if (not dep) then
|
|
return
|
|
end
|
|
|
|
-- TODO: recursion
|
|
for index, value in ipairs(dep.deps) do
|
|
if value == _auCurrentProject then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function isProjectLoaded(name)
|
|
local a = _auProjects[name]
|
|
if (not a) then
|
|
return false
|
|
end
|
|
|
|
return a.isInitialized
|
|
end
|
|
|
|
local function getProjectProcessor(name)
|
|
if (not name) then
|
|
return
|
|
end
|
|
local scre = _auProjects[name]
|
|
if (not scre) then
|
|
return
|
|
end
|
|
return scre.processor
|
|
end
|
|
|
|
local function getProjectProcessorOrThrow(name)
|
|
local ret = getProjectProcessor(name)
|
|
|
|
if (not ret) then
|
|
auFatal("Missing project", name)
|
|
end
|
|
|
|
return ret
|
|
end
|
|
|
|
local function getCurrentProjectName()
|
|
return _auCurrentProject
|
|
end
|
|
|
|
local function importAndLinkProject(dep, soft)
|
|
local processor = getProjectProcessorOrThrow(dep)
|
|
|
|
processor:handleReference(isWeakCircularReference(dep))
|
|
|
|
if (auGetCurrentProjectMeta().isStatic) then
|
|
return true
|
|
end
|
|
processor:handleLink()
|
|
return true
|
|
end
|
|
|
|
local function includeAuProject(dep, soft)
|
|
local processor = getProjectProcessorOrThrow(dep)
|
|
processor:handleReference()
|
|
return true
|
|
end
|
|
|
|
local function linkAuProject(dep, soft)
|
|
local processor = getProjectProcessorOrThrow(dep)
|
|
if (not processor:getMeta().isStatic) then
|
|
processor:handleLink()
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function addFeature(feature)
|
|
--print("adding feature ", feature)
|
|
|
|
local script = Aurora.Settings.sAbsRoot .. Aurora.Settings.sRelScripts .. "/Features/" .. feature:lower() .. ".lua"
|
|
|
|
if (not os.isfile(script)) then
|
|
auFatal("missing feature", feature, script)
|
|
return
|
|
end
|
|
|
|
auRequireAbs(script)()
|
|
end
|
|
|
|
return {
|
|
addVisit = addVisit,
|
|
addScript = addScript,
|
|
addFeature = addFeature,
|
|
linkAuProject = linkAuProject,
|
|
includeAuProject = includeAuProject,
|
|
importAndLinkProject = importAndLinkProject,
|
|
getProjectProcessor = getProjectProcessor,
|
|
isProjectLoaded = isProjectLoaded,
|
|
getCurrentProjectName = getCurrentProjectName,
|
|
processSolution = processSolution
|
|
} |