JD2022-TU1/main/extern/gear4/buildfolder/generation/project.lua

223 lines
6.3 KiB
Lua

-- Implement a Project definition, including blob generation
require "utils"
require "harvester"
Project = {
-- The harvester factory that find the files for this library
Harvester = FileHarvester,
-- custom defines
defines = {},
-- custom configurations (with options)
configurations = {
Debug = {},
Release = {},
Retail = {}
},
-- directory containing the eal libs
eallibdir = joindir("eal","implementations","eal_gear3","lib"),
eallibdirspu = joindir("eal","implementations","simpleal","lib"),
libext = "",
targetprefix = ""
}
function Project:New(proj)
proj = proj or {}
setmetatable(proj, self)
self.__index = self
return proj
end
function Project:Populate()
self.sources = collect(self:GetFiles(self.modules))
self.extrafiles = collect(self:GetFiles(self.extramodules))
self.excludefiles = { }
end
-- Log a message preceded by the library name.
function Project:Log(log, ...)
printf("%s: " .. log, self.name, unpack(arg))
end
-- Log a message only on debug.
function Project:Debug(...)
if _debug then
self:Log(unpack(arg))
end
end
function Project:UpdateConfigurations(configs)
self.configurations = copytable(self.configurations)
for name, config in pairs(configs) do
local newconfig = copytable(self.configurations[name] or {})
for option, value in pairs(config) do
local oldvalue = newconfig[option] or ""
if type(oldvalue) == "table" then
if type(value) ~= "table" then value = { value } end
newconfig[option] = collect(oldvalue, value)
else
newconfig[option] = value
end
end
self.configurations[name] = newconfig
end
end
function Project:Harvest(directory)
self:Debug("Harvesting files in " .. path.getabsolute(joindir(os.getcwd(), directory)))
if not self.harvester then
self.harvester = self.Harvester:New{satelliteName = self.library.name, platform = self.platform, extensions = self.extensions, isInBlobMode = not self.noblob}
end
return self.harvester:Harvest(directory)
end
-- return the files associated with self.files.
function Project:GetFiles(modules)
-- Harvest for source in the specified directories
local harvest = partial(Project.Harvest, self)
local scandirs = map(partial(joindir,self.dir), modules)
local ifiles = map(harvest, scandirs)
return concat_from_iterable(ifiles)
end
-- Generate all configurations
function Project:GenerateConfigurations()
for config,options in pairs(self.configurations) do
configuration{config}
for option, values in pairs(options) do
if not _G[option] then error("Attempt to run option " .. option, 2) end
_G[option](values)
end
end
suffix = self.platform
if self.suffix ~= "" then
suffix = suffix .. "_" .. self.suffix
end
configuration{ "*" }
end
function Project:GenerateBlobFile(sources, ext)
local function filter_file(fname)
local fext = path.getextension(fname):lower()
return fext == ext
end
local allfiles = collect( difference( filter(filter_file, sources),
self.excludefilefromblob) )
if #allfiles ~= 0 then
excludefilefrombuild( collect(map(cwdrelative,allfiles)) )
else
self:Debug("No files to add to blob for ext " .. ext)
end
end
-- Generate the blob file
function Project:GenerateBlobFiles(sources)
self:GenerateBlobFile(sources, ".cpp")
self:GenerateBlobFile(sources, ".mm")
end
function Project:GenerateDependencies()
if self.dependencies then
local function add_platform(dep)
return dep .. "_" .. self.platform .. self.suffix
end
self:Debug("Dependencies for " .. self.name)
links(collect(map(add_platform,self.dependencies)))
end
if self.externals then
-- all externals are supposed to be in extern
includedirs{cwdrelative(joindir(self.dir, "extern"))}
end
if self.links then
links(self.links)
end
end
-- Generate the project
function Project:Generate()
self:Log("Generating %s %s on %s", self.kind, self.name, self.platform)
if (self.kind == "ConsoleApp") and (self.platform == "durango") then
project ( string.gsub( self.name,
'_(.)',
function(x) return string.upper(x) end ) )
else
project ( self.name )
end
kind ( self.kind )
if self.language then
language(self.language)
end
objdir ( cwdrelative(self.location) )
targetdir ( cwdrelative(self.targetdir) )
location ( cwdrelative(self.location) )
defines ( self.defines )
includedirs ( cwdrelative(self.includedirs) )
targetprefix ( self.targetprefix )
assert(self.sources)
files (cwdrelative(self.sources))
-- handle the precompiled headers (if supported)
if self.pch then
local pchfiles = { src = cwdrelative(self.pch .. ".cpp"),
h = cwdrelative(self.pch .. ".h") }
files(collect(pchfiles))
if not self.nopch then
pchsource ( pchfiles.src )
pchheader ( pchfiles.h )
else
-- Usually no symbols are defined inside,
-- so we avoid a warning by not compiling it.
excludefilefrombuild{pchfiles.src}
flags{"NoPCH"}
end
end
-- generate the blob file (if required)
if not self.noblob then
self:GenerateBlobFiles(self.sources)
end
files(cwdrelative(self.extrafiles))
if self.excludefiles ~= nil then
excludefilefrombuild(cwdrelative(self.excludefiles))
end
-- fill up dependencies
self:GenerateDependencies()
-- configuration and post-processing
self:GenerateConfigurations()
end
-- Default options for library project
LibProject = Project:New{
kind = "StaticLib",
defines = { },
nopch = true,
}
-- Default options for test executable project
TestProject = Project:New{
kind = "ConsoleApp",
}
function TestProject:GenerateBlobFiles()
-- Do nothing for now.
return nil
end
function TestProject:GenerateConfigurations()
Project.GenerateConfigurations(self)
-- Reset the configurations
configuration{ "*" }
debugargs { "--gtest_filter=-*perf_*" }
end