Build/Core/project.lua

410 lines
13 KiB
Lua

local buildHooks = require("Core/BuildHooks")
local targetingCmake = false
local targetingWindows = os.host() == "windows"
local bugHack = targetingCmake or targetingWindows
local kPathPrefix = "!"
local function configureProjectForSolution(prj)
filter(auFilterConfig(Aurora.Settings.sNameOfDebug))
defines { "DEBUG" }
targetdir(Aurora.Settings.sAbsCompilerWd .. "/Bin/" .. Aurora.Settings.sNameOfDebug)
debugdir(Aurora.Settings.sAbsDebug)
flags "NoIncrementalLink"
filter(auFilterConfig({Aurora.Settings.sNameOfInternal, Aurora.Settings.sNameOfShip}))
defines { "NDEBUG" }
optimize "Speed"
filter(auFilterConfig(Aurora.Settings.sNameOfInternal))
defines { "STAGING" }
targetdir(Aurora.Settings.sAbsCompilerWd .. "/Bin/" .. Aurora.Settings.sNameOfInternal)
debugdir(Aurora.Settings.sAbsStage)
flags "NoIncrementalLink"
filter(auFilterConfig(Aurora.Settings.sNameOfShip))
defines { "SHIP" }
targetdir(Aurora.Settings.sAbsCompilerWd .. "/Bin/" .. Aurora.Settings.sNameOfShip)
debugdir(Aurora.Settings.sAbsShip)
flags "LinkTimeOptimization"
filter {}
auFilterForConfigPlatforms(function(config, platformName, arch)
if (Aurora.Settings.bDefinePartialABIInTargetName) then
targetname(string.format("%s.%s.%s.%s", prj.name, config, platformName:gsub("^%l", string.upper), arch))
end
if (not(config == Aurora.Settings.sNameOfShip)) then return end
local platform = Aurora.Platforms[platformName]
if (platform.requiresElfStrip and not platform.supportsElfStrip) then
symbols "Off"
end
end)
end
local function setBestDebugDir(dest)
if (not dest or dest:starts(kPathPrefix)) then
local append = dest and dest:sub(#kPathPrefix + 1)
if (not append) then append = "" end
filter(auFilterConfig(Aurora.Settings.sNameOfDebug))
debugdir(Aurora.Settings.sAbsDebug .. "/" .. append)
filter(auFilterConfig(Aurora.Settings.sNameOfInternal))
debugdir(Aurora.Settings.sAbsStage .. "/" .. append)
filter(auFilterConfig(Aurora.Settings.sNameOfShip))
debugdir(Aurora.Settings.sAbsShip .. "/" .. append)
filter {}
else
debugdir(auGetRoot() .. dest)
end
end
local function configureProjectForCompiler()
if (targetingCmake) then
filter {"toolset:msc"}
end
if (bugHack) then
buildoptions {"-utf-8"}
end
if (targetingCmake) then
filter {"toolset:msc", "files:**.cpp or files:**.cc or files:**.cxx"}
elseif (bugHack) then
filter {"files:**.cpp or files:**.cc or files:**.cxx"}
end
if (bugHack) then
buildoptions {"/experimental:module-", "/Zc:__cplusplus"}
end
filter {}
end
local function configureProjectForPlatform(platform, projType)
if (platform == "win32") then
characterset(Aurora.Settings.sMsvcDefCharset)
staticruntime("Off")
if (Aurora.Settings.bHotswap) then
justmycode("On")
else
justmycode("Off")
end
defines "_CRT_SECURE_NO_WARNINGS"
else
if ((projectType == "SharedLib") or
(projectType == "StaticLib")) then
pic "On"
end
end
end
local function configureProjectForPlatforms(projType)
auFilterForPlatforms(function(platformName)
configureProjectForPlatform(platformName, projType)
end)
end
local function configureProjectErrors()
if (not Aurora.Settings.bDisableWarningsThatAnnoyRec) then
return
end
filter {"toolset:clang"}
buildoptions {"-fms-extensions"}
disablewarnings
{
-- we live life on the edge
"unused-result",
-- warning: unused unused enumeration
"unused-value",
-- :(
"unknown-warning-option"
}
filter{}
if (targetingCmake) then
filter {"toolset:msc"}
end
if (bugHack) then
disablewarnings
{
"4996", -- The whiny C99 is no longer supported nag
-- please needlessly use '_s' and '_'d functions __error__
"4251", -- MSVC's hurrdurr abis will break if you dynamically link classes
-- counter: sod off again. we have full control of the build process, and we only link against
-- dynamic c/stl runtimes. which brainlet thought this was a good idea?
-- even microsofts own documentation doesn't state what is guaranteed to be safe.
-- dont mix optimizations, mitigation flags, and so on.
-- rtti works; the stl doesn't abuse inline/module specific globals; who cares?
"4244" -- conversion from 'double' to 'float', possible loss of data
-- this warning is extremely important; however, we're developing a game engine and utilities
-- pragma warning push + disable + pop and/or static_casts to hint we expect floating point precision
-- loss is extremely annoying and impractical. further, projects including harfbuzz, freetype,
-- and v8 don't seem to care about this warning either
}
end
filter {}
end
local function configureProjectForDebug(prj)
local debugDir = nil
if (type(prj.dest) == "string") then
debugDir = prj.dest
end
if (type(prj.dest) == "table") then
debugDir = prj.dest[1]
end
setBestDebugDir(debugDir)
end
local function configureProjectForTarget()
auRequire("Core/Target").startProject()
end
local function configureProjectForLd(prj)
-- I'm not going to deal with this argument
--
-- I don't care for the opinions of greybeards who are stuck in the opinions put forth by AT&Ts meme of an OS
-- In *NIX land, you have +X, use it. I don't want to hear about how operating systems that have more aggressive
-- executable policies than macos and windows, with their vast ecosystem of file system sandboxing extensions,
-- can't cope with loosely following the intentions of the NT loader for the sake of uniformity across platforms.
--
-- https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#standard-search-order-for-desktop-applications
--
-- inb4 LD_LIBRARY_PATH screeching as if users should be expected to mess around with env vars before launching
-- each application. no, just no.
--
-- inb4 muh security. A malcious dependency injection would be the product of a hostile manipulation of the accessible
-- file system files and/or directories. Both are systematic issues we aren't going to make a dent in. The latter being
-- the fundamental issue your administrators should be focused on mitigating; sandbox all apps that could perform hostile IO.
-- If an attacker can write a malicious module or system lib proxy somewhere, you've failed basic attack mitigation,
-- and you're going to be pwned on non-POSIX targets no matter what.
-- Elevation exploits shouldn't be a problem so long as the linkoptions order is maintained so that $origin and then
-- system libraries are considered before any malcious user-installed libraries could possibly be loaded.
-- If you're running a broken arse system with missing protected libraries and you run software as write-level groups,
-- you have bigger issues than my 'lets treat POSIX systems more like NT for cross-compatibility and sanity' assumption.
-- If you're worried about ld.so running unsigned code, go complain to glib iq-lets who maintain ld.so and force them
-- into developing actual .text and .rodata signature validation with respect to a global root-writable certificate,
-- instead of spreading the ball of responsiblity like hot-fucking-potato in a game of respecting the UNIX :tm: way
-- of doing things (IE, expecting the user to know how to lockdown vendor supplied packages, RO all LD_LIBRARY_PATHs
-- and other undocumented vendor paths, and do god knows what to harden specific softwares dumped without thought
-- across an arahic FHS/XDG tree, while the developers do jack shit to improve stability, maintainablity, and security).
--
-- Change my mind (without parroting what some dude said on some forum over a decade ago)
-- Don't like it? Disable: Aurora.Settings.bForceWin32EscLd
if (prj.projectType ~= "SharedLib" and
prj.projectType ~= "WindowedApp" and
prj.projectType ~= "ConsoleApp") then
return
end
if (not Aurora.Settings.bForceWin32EscLd) then
return
end
auFilterForConfigPlatforms(function(config, platform, arch)
local platform = Aurora.Platforms[platformName]
if (not platform) then
return
end
if (not platform.elfSupportsRPath) then
return
end
linkoptions { "-Wl,-rpath,'$ORIGIN'", "-Wl,-rpath,'/lib'" }
if (arch == "x86_64" or arch == "arm") then
linkoptions { "-Wl,-rpath,'/lib64'" }
elseif (arch == "x86_32") then
linkoptions { "-Wl,-rpath,'/lib32'" }
end
linkoptions { "-Wl,-rpath,'/usr/lib'" }
if (arch == "x86_64" or arch == "arm") then
linkoptions { "-Wl,-rpath,'/usr/lib64'" }
elseif (arch == "x86_32") then
linkoptions { "-Wl,-rpath,'/usr/lib32'" }
end
linkoptions { "-Wl,-rpath,'$PWD'" }
linkoptions { "-Wl,-rpath,'/usr/local/lib'" }
if (arch == "x86_64" or arch == "arm") then
linkoptions { "-Wl,-rpath,'/usr/local/lib64'" }
elseif (arch == "x86_32") then
linkoptions { "-Wl,-rpath,'/usr/local/lib32'" }
end
end)
end
local function processorDispatchRun(processor)
processor:process()
-- TODO: m4/protobuf/etc support
end
local function processorTranslateDep(this, dep)
if (not this._info.translations) then
return dep
end
local override = this._info.translations[dep]
if (override) then
return override
end
return dep
end
local function processorGetInfo(this)
return this._info
end
local function expendBaseProcessor(prj)
prj.processor._info = prj.info
prj.processor.dispatch = processorDispatchRun
prj.processor.translateDep = processorTranslateDep
prj.processor.getInfo = processorGetInfo
prj.processor.getMeta = processorGetInfo
end
local function setupProject(prj)
print("project", prj.name)
project(prj.name)
language("C++") -- C and MASM drivers are still available to files requiring different compilers
justmycode("Off") -- HACK: default off
targetname(prj.name) -- TODO (reece): you know what to do
kind(prj.projectType)
cppdialect(Aurora.Settings.sCppVersion)
targetprefix(Aurora.Settings.sLibPrefix)
objdir(Aurora.Settings.sAbsCompilerWd .. "/" .. prj.name)
configureProjectForSolution(prj)
configureProjectErrors()
configureProjectForCompiler()
configureProjectForPlatforms(prj.projectType)
configureProjectForTarget()
configureProjectForDebug(prj)
configureProjectForLd(prj)
defines "_AU_HAS_ATOMIC_INTRINS"
defines("_AU_BUILDING_" .. string.upper(prj.projectType))
if (prj.root) then
location(prj.root)
else
location(os.getcwd())
end
defines
{
"_ITERATOR_DEBUG_LEVEL=0",
}
if (Aurora.Settings.bIncludeAuIncludeIfExists) then
local commonInclude = auGetRoot() .. "/Include"
if (os.isdir(commonInclude)) then
includedirs(commonInclude)
files(commonInclude .. "/**.h*")
end
end
-- add includes, if available
auForEach(prj.inc, function(path)
print("", "include", _G.path.normalize(path))
includedirs(path)
files(path .. "/**.h")
files(path .. "/**.hpp")
files(path .. "/**.inl")
end)
-- add sources, if available
auForEach(prj.src, function(path, root)
print("", "source", _G.path.normalize(path))
--if (string.sub(path, -2) == ".*") then
if (string.find(path, "*")) then
files {path}
return
end
if (os.isfile(path)) then
files {path}
return
end
if (not root) then
includedirs(path)
end
files
{
path .. "/**.*pp",
path .. "/**.inl",
path .. "/**.c",
path .. "/**.cc",
path .. "/**.cxx",
path .. "/**.h",
path .. "/**.masm" -- required explicitly
}
end, root)
buildHooks.startProject(prj.name, prj.projectType)
auForEach(prj.dest, function(v)
buildHooks.addDest(prj.name, prj.projectType, v)
end)
print()
end
local function setupProjectCompat(name, projectType, src, inc, dest, root)
local project =
{
name = name,
projectType = projectType,
src = src,
inc = inc,
dest = dest,
root = root
}
setupProject(project)
end
return
{
expendBaseProcessor = expendBaseProcessor,
setupProjectCompat = setupProjectCompat,
startProject = setupProject
}