local buildHooks = require("Core/BuildHooks") local targetingCmake = false local targetingWindows = os.host() == "windows" local bugHack = targetingCmake or targetingWindows local kPathPrefix = "!" local function configureProjectForSolution(prj) auFilter(auFilterConfig(Aurora.Settings.sNameOfDebug)) defines { "DEBUG" } if (Aurora.Settings.bIsBuildDirWd) then debugdir(Aurora.Settings.sAbsDebug) end flags "NoIncrementalLink" auFilter {} auFilter(auFilterConfig({Aurora.Settings.sNameOfInternal, Aurora.Settings.sNameOfShip})) defines { "NDEBUG" } optimize "Speed" auFilter {} auFilter(auFilterConfig(Aurora.Settings.sNameOfInternal)) defines { "STAGING" } if (Aurora.Settings.bIsBuildDirWd) then debugdir(Aurora.Settings.sAbsStage) end flags "NoIncrementalLink" auFilter {} auFilter(auFilterConfig(Aurora.Settings.sNameOfShip)) defines { "SHIP" } if (Aurora.Settings.bIsBuildDirWd) then debugdir(Aurora.Settings.sAbsShip) end if (Aurora.Settings.bIsShipLTOByDefault) then flags "LinkTimeOptimization" end auFilter {} local function setTargetDir(id) local name = Aurora.Settings["sNameOf" .. id] auFilter(auFilterConfig(name)) defines("AU_CFG_ID_" .. (id:upper())) local path = Aurora.Settings.sAbsCompilerWd .. "/Bin/" .. name if (Aurora.Settings.bSplitTargetDirByArch) then path = path .. "/%{cfg.architecture}" end targetdir(path) auFilter{} end setTargetDir("Debug") setTargetDir("Internal") setTargetDir("Ship") auFilterForConfigPlatforms(function(config, platformName, arch) local platform = Aurora.Platforms[platformName] if (Aurora.Settings.bDefinePartialABIInTargetName) then targetname(string.format("%s.%s.%s.%s", prj.name, config, platform.outputName, arch)) end if (not(config == Aurora.Settings.sNameOfShip)) then return end if (platform.requiresElfStrip and not platform.supportsElfStrip) then symbols "Off" end end) end local function setBestDebugDir(dest) if (not Aurora.Settings.bIsBuildDirWd) then return end 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, projectType) if (platform == "linux") then if (Aurora.Settings.bStaticRuntime) then buildoptions "-static" linkoptions "-l:libc++abi.a" linkoptions "-l:libc++.a" linkoptions "-Wl,--as-needed" end end if (platform == "win32") then characterset(Aurora.Settings.sMsvcDefCharset) if (Aurora.Settings.bStaticRuntime) then staticruntime("On") links "libucrt.lib" else staticruntime("Off") end if (not Aurora.Settings.bBasicMitigations) then buildoptions { --"/GS-", "/sdl-" } flags "NoBufferSecurityCheck" end 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 (not Aurora.Settings.bIsBuildDirWd) then debugdir(Aurora.Settings.sAbsWd) return end 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, platformName, 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,'.'" } 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 .. "/%{cfg.architecture}") 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") files(path .. "/**.inc") files(path .. "/**.ipp") 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 .. "/**.inc", path .. "/**.c", path .. "/**.cc", path .. "/**.cxx", path .. "/**.h", path .. "/**.asm", 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 }