Skip to content

Commit

Permalink
WIP new build system
Browse files Browse the repository at this point in the history
  • Loading branch information
GlynLeine committed Nov 3, 2023
1 parent 245c9d5 commit d2bf26f
Show file tree
Hide file tree
Showing 8 changed files with 336 additions and 49 deletions.
3 changes: 3 additions & 0 deletions premake/rythe/_preload.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
return function(cfg)
return true
end
72 changes: 72 additions & 0 deletions premake/rythe/context.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
local context = {}

local utils = dofile("utils.lua")

local function hasFilter(list, item)
if list then
if string.contains(list, "-" .. item) then
return false
end

return string.contains(list, item)
end

return true
end

-- Gets the command that was used to call premake with
function context.getCommand()
local cmd = ""
for k,v in pairs(_OPTIONS) do
cmd = cmd .. "--" .. k .. "=" .. tostring(v) .. " "
end

return utils.trim(cmd)
end

function context.hasConfiguration(configuration)
return hasFilter(_OPTIONS["configurations"], configuration)
end

-- Module names: e.g. core, graphics, audio
function context.hasModule(module)
return hasFilter(_OPTIONS["modules"], module)
end

-- Project types are e.g. test, module, application, static-libary, dynamic-library, header-only, util
function context.hasProjectType(projectType)
return hasFilter(_OPTIONS["types"], projectType)
end

-- Project groups are e.g. rythe, deps, my_plugin, my_game, etc
function context.hasProjectGroup(projectGroup)
return hasFilter(_OPTIONS["groups"], projectGroup)
end

-- Links as shared library, but does no runtime reloading
function context.linkShared()
return _OPTIONS["shared"] and not (_OPTIONS["dynamic"] or _OPTIONS["static"])
end

-- Enables runtime module loading, otherwise the same as shared
function context.linkDynamic()
return _OPTIONS["dynamic"] and not _OPTIONS["static"]
end

-- If no link target is defined, then static is chosen
function context.linkStatic()
return _OPTIONS["static"] or not (context.linkShared() or context.linkDynamic())
end

function context.linkTarget()
return context.linkStatic() and "StaticLib" or "SharedLib"
end

-- Tag to place at the end of a solution name
function context.solutionTag()
local tag = _OPTIONS["tag"]
if tag then return "-" .. tag end
return ""
end

return context
28 changes: 28 additions & 0 deletions premake/rythe/filesystem.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
local fs = {}

function fs.exists(file)
local f = io.open(file, "rb")
if f then io.close(f) end
return f ~= nil
end

function fs.readLines(file)
if not fs.exists(file) then return {} end

local lines = {}
for line in io.lines(file) do
lines[#lines + 1] = line
end

return lines
end

function fs.parentPath(path)
return string.match(path, "^(.+)[/\\]")
end

function fs.fileName(path)
return string.match(path, "([^/\\]+)$")
end

return fs
173 changes: 173 additions & 0 deletions premake/rythe/projects.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
local fs = dofile("filesystem.lua")
local ctx = dofile("context.lua")
local utils = dofile("utils.lua")

local rythe = premake.rythe
local loadedProjects = rythe.loadedProjects
local buildSettings = rythe.buildSettings

local projects = {}

local function find(projectPath)
local projectName = fs.fileName(projectPath)
local group = fs.parentPath(projectPath)

local projectFile = projectPath .. "/project.lua"

if not os.isfile(projectFile) then
projectFile = projectPath .. "/" .. projectName .. ".lua"

if not os.isfile(projectFile) then
return nil, group, projectName
end
end

return projectFile, group, projectName
end

local function kindName(projectType, config)
if projectType == "module" then
return ctx.linkTarget()
elseif projectType == "test" then
return "ConsoleApp"
elseif projectType == "application" then
if config == rythe.Configuration.RELEASE then
return "WindowedApp"
else
return "ConsoleApp"
end
elseif projectType == "static-libary" then
return "SharedLib"
elseif projectType == "header-only" then
return "SharedItems"
elseif projectType == "util" then
return "Utility"
end
assert(false, "Unknown project type: \"" .. projectType .. "\"")
end

function projects.load(projectPath)
print("Loading project at \"" .. projectPath .. "\"")

local project = loadedProjects[projectPath]

if project ~= nil then
return project
end

local projectFile, group, name = find(projectPath)

if projectFile == nil then
print("Could not find project \"" .. group .. "/" .. name .. "\"")
return nil
end

project = dofile(projectFile)

if project == nil then
print("Could not initialize project \"" .. group .. "/" .. name .. "\"")
return nil
end

assert(project.group == group, "Group folder structure mismatch \"" .. group .. "\" vs \"" .. project.group .. "\"")
assert(project.name == name, "Project name folder structure mismatch \"" .. name .. "\" vs \"" .. project.name .. "\"")
assert(not utils.tableIsEmpty(project.types), "Project must hold an assembly type. (Use the type \"util\" if no source code is required)")
if next(project.dependencies) == nil then
project.dependencies = nil
end

if utils.tableIsEmpty(project.defines) then
project.defines = { "PROJECT_NAME=" .. project.name }
else
project.defines = utils.concatTables(project.defines, { "PROJECT_NAME=" .. project.name })
end

project.src = projectFile
project.location = projectPath

loadedProjects[projectPath] = project

return project
end

local function setupRelease()
filter("configurations:Release")
defines { "NDEBUG" }
optimize("Full")
end

local function setupDevelopment()
filter("configurations:Development")
defines { "DEBUG" }
optimize("Debug")
inlining("Explicit")
symbols("On")
end

local function setupDebug()
filter("configurations:Debug")
defines { "DEBUG" }
symbols("On")
end

function projects.submit(project)
local configSetup = {
[rythe.Configuration.RELEASE] = setupRelease,
[rythe.Configuration.DEVELOPMENT] = setupDevelopment,
[rythe.Configuration.DEBUG] = setupDebug
}

for i, projectType in ipairs(project.types) do
group(project.group)
project(project.name)
architecture(buildSettings.platform)
toolset("clang")
language("C++")
cppdialect("C++23")
defines(project.defines)
for i, config in ipairs(rythe.Configuration) do
configSetup[config]()
kind(kindName(projectType, config))
end
end
end

function projects.scan(path)
local srcDirs = {}
local thirdpartyDirs = {}

for i, dir in ipairs(os.matchdirs(path .. "**/src")) do
if string.find(dir, "third_party") then
thirdpartyDirs[#thirdpartyDirs + 1] = dir
else
srcDirs[#srcDirs + 1] = dir
end
end

for i, dir in ipairs(srcDirs) do
local projectPath = fs.parentPath(dir)
local project = projects.load(projectPath)

if project ~= nil then
local message = "Found project:"
message = message .. "\n Group: " .. project.group
message = message .. "\n Name: " .. project.name

message = message .. "\n Assembly types:"
for i, assem in ipairs(project.types) do
message = message .. "\n\t" .. assem
end

if project.dependencies ~= nil then
message = message .. "\n Dependencies:"
for i, dep in ipairs(project.dependencies) do
message = message .. "\n\t" .. dep
end
end

print(message)
end
end
end

return projects
23 changes: 23 additions & 0 deletions premake/rythe/rythe.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
include("_preload.lua")

premake.rythe = {
Configuration = {
RELEASE = 1,
DEVELOPMENT = 2,
DEBUG = 3
},
loadedProjects = {},
buildSettings = {
platform = "x86_64"
}
}

local rythe = premake.rythe

local projects = dofile("projects.lua")

function rythe.test()
projects.scan("./")
end

return rythe
18 changes: 18 additions & 0 deletions premake/rythe/utils.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
local utils = {}

function utils.trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end

function utils.concatTables(lhs, rhs)
for i=1, #rhs do
lhs[#lhs + 1] = rhs[i]
end
return lhs
end

function utils.tableIsEmpty(t)
return t == nil or next(t) == nil
end

return utils
Loading

0 comments on commit d2bf26f

Please sign in to comment.