cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

sdl_projects.lua (16074B)


      1-- Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
      2--
      3-- This software is provided 'as-is', without any express or implied
      4-- warranty.  In no event will the authors be held liable for any damages
      5-- arising from the use of this software.
      6--
      7-- Permission is granted to anyone to use this software for any purpose,
      8-- including commercial applications, and to alter it and redistribute it
      9-- freely.
     10--
     11-- Meta-build system using premake created and maintained by
     12-- Benjamin Henning <b.henning@digipen.edu>
     13
     14--[[
     15sdl_projects.lua
     16
     17	This file contains all the functions which are needed to define any project
     18	within the meta-build system. Many of these functions serve as
     19	pseudo-replacements for many similarly named premake functions, and that is
     20	intentional. Even the implementation of these functions are intended to look
     21	similar to regular premake code. These functions serve to dramatically
     22	simplify the project definition process to just a few lines of code, versus
     23	the many more needed for projects defined purely with premake.
     24
     25	This approach is possible because this meta-build system adds another layer of
     26	indirection to the premake system, creating a sort of 'meta-meta-build'
     27	system. Nevertheless, there is a lot more flexibility because the meta-build
     28	system itself can be used to check for dependencies in a much more complex way
     29	than premake originally intended. All of the functions useful to the project
     30	definition system are contained in this file and are documented.
     31]]
     32
     33projects = { }
     34
     35local currentProject = nil
     36local currentDep = nil
     37local nextFuncCompat = true -- by default, unless state otherwise changed
     38local dependencyFunctions = { }
     39local dependencyResults = { } -- for when the dependencies are executed
     40
     41-- query whether this function is compatible; resets internal state of
     42-- compatibility to true until SDL_isos is called again
     43local function oscompat()
     44	local compat = nextFuncCompat
     45	nextFuncCompat = true
     46	return compat
     47end
     48
     49-- determine whether the specific OS name is within a pattern.
     50local function osmatch(name, pattern)
     51	local checks = pattern:explode('|')
     52	for i,v in pairs(checks) do
     53		if name == v then
     54			return true
     55		end
     56	end
     57	return false
     58end
     59
     60-- Registers a dependency checker function based on a name. This function is
     61-- used in order to determine compatibility with the current system for a given
     62-- SDL_dependency. See SDL_depfunc for more information.
     63--
     64-- Specifies a function which will be invoked upon determining whether this
     65-- dependency is valid for the current system setup (ie, whether the system
     66-- has the right architecture, operating system, or even if it's installed).
     67-- The dependency function takes no arguments, but it must return the following
     68-- values:
     69--
     70--   <foundDep> [includePaths] [libPaths] [inputLibLibraries]
     71--
     72-- The last three are optional, unless foundDep is true. The name should be
     73-- descriptive of the outside dependency, since it may be shown to the user.
     74-- This function is intended to be used only after invoking SDL_dependency.
     75function SDL_registerDependencyChecker(name, func)
     76	dependencyFunctions[name:lower()] = func
     77end
     78
     79-- Initializes the definition of a SDL project given the name of the project.
     80function SDL_project(name)
     81	if not oscompat() then return end
     82	currentProject = { }
     83	currentProject.name = name
     84	currentProject.compat = true
     85	projects[name] = currentProject
     86	currentProject.dependencyTree = { }
     87	-- stores which dependencies have already been checked on behalf of this
     88	-- project
     89	currentProject.dependencyValues = { }
     90	currentDep = nil
     91end
     92
     93-- Specifies the build kind of the SDL project (e.g. StaticLib, SharedLib,
     94-- ConsoleApp, etc.), based on premake presets.
     95function SDL_kind(k)
     96	if not oscompat() then return end
     97	currentProject.kind = k
     98end
     99
    100-- Specifies which platforms this project supports. Note: this list is not the
    101-- exact list of supported platforms in the generated project. The list of
    102-- platforms this project supports will be the unique list of all combined
    103-- projects for this SDL solution. Thus, only one project needs to actually
    104-- maintain a list. This function is additive, that is, everytime it is called
    105-- it adds it to a unique list of platforms
    106function SDL_platforms(tbl)
    107	if not oscompat() then return end
    108	if not currentProject.platforms then
    109		currentProject.platforms = { }
    110	end
    111	for k,v in pairs(tbl) do
    112		currentProject.platforms[#currentProject.platforms + 1] = v
    113	end
    114end
    115
    116-- Specifies the programming language of the project, such as C or C++.
    117function SDL_language(k)
    118	if not oscompat() then return end
    119	currentProject.language = k
    120end
    121
    122-- Specifies the root directory in which the meta-build system should search for
    123-- source files, given the paths and files added.
    124function SDL_sourcedir(src)
    125	if not oscompat() then return end
    126	currentProject.sourcedir = src
    127end
    128
    129-- Specifies the destination location of where the IDE files related to the
    130-- project should be saved after generation.
    131function SDL_projectLocation(loc)
    132	if not oscompat() then return end
    133	currentProject.projectLocation = loc
    134end
    135
    136-- Specifies a table of files that should be copied from the source directory
    137-- to the end result build directory of the binary file.
    138function SDL_copy(tbl)
    139	if not oscompat() then return end
    140	currentProject.copy = tbl
    141end
    142
    143-- Specifies a list of other SDL projects in this workspace the currently active
    144-- project is dependent on. If the dependent project is a library, the binary
    145-- result will be copied from its directory to the build directory of the
    146-- currently active project automatically.
    147function SDL_projectDependencies(tbl)
    148	if not oscompat() then return end
    149	currentProject.projectDependencies = tbl
    150end
    151
    152-- Specifies a list of compiler-level preprocessor definitions that should be
    153-- set in the resulting project upon compile time. This adds to the current
    154-- table of defines.
    155function SDL_defines(tbl)
    156	if not oscompat() then return end
    157	if not currentProject.defines then
    158		currentProject.defines = { }
    159	end
    160	for k,v in pairs(tbl) do
    161		currentProject.defines[#currentProject.defines + 1] = v
    162	end
    163end
    164
    165-- Initializes an outside dependency this project has, such as X11 or DirectX.
    166-- This function, once invoked, may change the behavior of other SDL
    167-- project-related functions, so be sure to be familiar with all the functions
    168-- and any specified behavior when used around SDL_dependency.
    169function SDL_dependency(name)
    170	if not oscompat() then return end
    171	currentDep = { nil, compat = true, }
    172	currentDep.name = name
    173	table.insert(currentProject.dependencyTree, currentDep)
    174end
    175
    176-- Special function for getting the current OS. This factors in whether the
    177-- metabuild system is in MinGW, Cygwin, or iOS mode.
    178function SDL_getos()
    179	if _OPTIONS["ios"] ~= nil then
    180		return "ios"
    181	elseif _OPTIONS["mingw"] ~= nil then
    182		return "mingw"
    183	elseif _OPTIONS["cygwin"] ~= nil then
    184		return "cygwin"
    185	end
    186	return os.get()
    187end
    188
    189-- Specifies which operating system this dependency targets, such as windows or
    190-- macosx, as per premake presets.
    191function SDL_os(name)
    192	if not oscompat() then return end
    193	if not currentProject then return end
    194	if not currentDep then
    195		currentProject.opsys = name
    196		currentProject.compat = osmatch(SDL_getos(), name)
    197	else
    198		currentDep.opsys = name
    199		currentDep.compat = osmatch(SDL_getos(), name)
    200	end
    201end
    202
    203-- Specifies which operating system this dependency does not targets. This is
    204-- for nearly platform-independent projects or dependencies that will not work
    205-- on specific systems, such as ios.
    206function SDL_notos(name)
    207	if not oscompat() then return end
    208	if not currentProject then return end
    209	if not currentDep then
    210		currentProject.opsys = "~" .. name
    211		currentProject.compat = not osmatch(SDL_getos(), name)
    212	else
    213		currentDep.opsys = "~" .. name
    214		currentDep.compat = not osmatch(SDL_getos(), name)
    215	end
    216end
    217
    218-- Changes the internal state of function compatibility based on whether the
    219-- current os is the one expected; the next function will be affected by this
    220-- change, but no others. The name can be a pattern using '|' to separate
    221-- multiple operating systems, such as:
    222--   SDL_isos("windows|macosx")
    223function SDL_isos(name)
    224	nextFuncCompat = osmatch(SDL_getos(), name)
    225end
    226
    227-- Same as SDL_isos, except it negates the internal state for exclusion
    228-- checking.
    229function SDL_isnotos(name)
    230	nextFuncCompat = not osmatch(SDL_getos(), name)
    231end
    232
    233-- Changes the internal state of function compatibility based on whether the
    234-- current system is running a 64bit Operating System and architecture; the
    235-- next function will be affected by this change, but none thereafter.
    236function SDL_is64bit()
    237	nextFuncCompat = os.is64bit()
    238end
    239
    240-- Same as SDL_is64bit, except it negates the internal state for
    241-- exclusion checking.
    242function SDL_isnot64bit()
    243	nextFuncCompat = not os.is64bit()
    244end
    245
    246-- Look at SDL_depfunc and SDL_notdepfunc for detailed information about this
    247-- function.
    248local function SDL_depfunc0(funcname, exclude)
    249	if not oscompat() then return end
    250	if not currentDep.compat then return end
    251	local force = _OPTIONS[funcname:lower()] ~= nil
    252	local func = dependencyFunctions[funcname:lower()]
    253	if not func then
    254		print("Warning: could not find dependency function named: " .. funcname)
    255		currentDep.compat = false
    256		return
    257	end
    258	local cachedFuncResults = dependencyResults[funcname:lower()]
    259	local depFound, depInc, depLib, depInput
    260	if cachedFuncResults then
    261		depFound = cachedFuncResults.depFound
    262		-- just skip the rest of the function, the user was already warned
    263		-- exclude mode varies the compatibility slightly
    264		if force then
    265			depFound = true
    266		end
    267		if not depFound and not exclude then
    268			currentDep.compat = false
    269			return
    270		elseif depFound and exclude then
    271			currentDep.compat = false
    272			return
    273		end
    274		depInc = cachedFuncResults.depInc
    275		depLib = cachedFuncResults.depLib
    276		depInput = cachedFuncResults.depInput
    277	else
    278		local result = func()
    279		if result.found then
    280			depFound = result.found
    281		else
    282			depFound = false
    283		end
    284		if force then
    285			depFound = true
    286		end
    287		if result.incDirs then
    288			depInc = result.incDirs
    289		else
    290			depInc = { }
    291		end
    292		if result.libDirs then
    293			depLib = result.libDirs
    294		else
    295			depLib = { }
    296		end
    297		if result.libs then
    298			depInput = result.libs
    299		else
    300			depInput = { }
    301		end
    302		cachedFuncResults = { }
    303		cachedFuncResults.depFound = depFound
    304		cachedFuncResults.depInc = depInc
    305		cachedFuncResults.depLib = depLib
    306		cachedFuncResults.depInput = depInput
    307		dependencyResults[funcname:lower()] = cachedFuncResults
    308		if not depFound and not exclude then
    309			currentDep.compat = false
    310			return
    311		elseif depFound and exclude then
    312			currentDep.compat = false
    313			return
    314		end
    315	end
    316	-- we only want to embed this dependency if we're not in exclude mode
    317	if depFound and not exclude then
    318		local dependency = { }
    319		if not currentDep.includes then
    320			currentDep.includes = { }
    321		end
    322		for k,v in pairs(depInc) do
    323			currentDep.includes[v] = v
    324		end
    325		if not currentDep.libs then
    326			currentDep.libs = { }
    327		end
    328		for k,v in pairs(depLib) do
    329			currentDep.libs[v] = v
    330		end
    331		if not currentDep.links then
    332			currentDep.links = { }
    333		end
    334		for k,v in pairs(depInput) do
    335			currentDep.links[v] = v
    336		end
    337	else -- end of dependency found check
    338		-- if we are not excluding this dependency, then print a warning
    339		-- if not found
    340		if not exclude then
    341			print("Warning: could not find dependency: " .. funcname)
    342		end
    343		currentDep.compat = exclude
    344	end
    345end
    346
    347-- Given a dependency name, this function will register the dependency and try
    348-- to pair it with a dependency function that was registered through
    349-- SDL_registerDependencyChecker. If the function is not found, compatibility
    350-- will automatically be dropped for this project and a warning will be printed
    351-- to the standard output. Otherwise, the dependency function will be invoked
    352-- and compatibility for the project will be updated. If the project currently
    353-- is not compatible based on the Operating System or previous dependency, the
    354-- dependency function will not be checked at all and this function will
    355-- silently return.
    356function SDL_depfunc(funcname)
    357	SDL_depfunc0(funcname, false)
    358end
    359
    360-- Same as SDL_depfunc, except this forces dependency on the function failing,
    361-- rather than succeeding. This is useful for situations where two different
    362-- files are required based on whether a dependency is found (such as the
    363-- joystick and haptic systems).
    364function SDL_notdepfunc(funcname)
    365	SDL_depfunc0(funcname, true)
    366end
    367
    368-- Determines whether the specified dependency is supported without actually
    369-- executing the dependency or changing the internal states of the current
    370-- project or dependency definition. This function will only work if the
    371-- dependency has already been checked and its results cached within the
    372-- definition system. This function returns true if the dependency is known to
    373-- be supported, or false if otherwise (or if it cannot be known at this time).
    374function SDL_assertdepfunc(funcname)
    375	-- if forced, then of course it's on
    376	if _OPTIONS[funcname:lower()] then
    377		return true
    378	end
    379	local results = dependencyResults[funcname:lower()]
    380	if not results or not results.depFound then
    381		-- either not excuted yet, doesn't exist, or wasn't found
    382		print("Warning: required dependency not found: " .. funcname ..
    383			". Make sure your dependencies are in a logical order.")
    384		return false
    385	end
    386	return true
    387end
    388
    389-- Returns a list of currently registered dependencies. The values within the
    390-- table will be sorted, but their names will be lowercased due to internal
    391-- handling of case-insensitive dependency names.
    392function SDL_getDependencies()
    393	local deps = { }
    394	for k,_ in pairs(dependencyFunctions) do
    395		deps[#deps + 1] = k
    396	end
    397	table.sort(deps)
    398	return deps
    399end
    400
    401-- Specifies a list of libraries that should always be linked to in this
    402-- project, regardless of a dependency function. If after a dependency
    403-- declaration, these files will only be included in the project if the
    404-- dependency is compatible with the native system, given SDL_os usage and any
    405-- sort of custom dependency function.
    406function SDL_links(tbl)
    407	if not oscompat() then return end
    408	if currentDep and not currentDep.compat then return end
    409	if currentProject.customLinks == nil then
    410		currentProject.customLinks = { }
    411	end
    412	for i,v in ipairs(tbl) do
    413		currentProject.customLinks[#currentProject.customLinks + 1] = v
    414	end
    415end
    416
    417-- Specifies a list of configuration values that are assigned as preprocessor
    418-- definitions in the SDL configuration header, used to globally configure
    419-- features during the building of the SDL library. If after a dependency
    420-- declaration, these files will only be included in the project if the
    421-- dependency is compatible with the native system, given SDL_os usage and any
    422-- sort of custom dependency function.
    423function SDL_config(tbl)
    424	if not oscompat() then return end
    425	if not currentDep then
    426		currentProject.config = tbl
    427		return
    428	end
    429	if not currentDep.compat then return end
    430	currentDep.config = tbl
    431end
    432
    433-- Specifies a list of paths where all .c, .h, and .m files should be included
    434-- for compiling, where the source directory is the root. If after a dependency
    435-- declaration, these files will only be included in the project if the
    436-- dependency is compatible with the native system, given SDL_os usage and any
    437-- sort of custom dependency function.
    438function SDL_paths(tbl)
    439	if not oscompat() then return end
    440	if not currentDep then
    441		currentProject.paths = tbl
    442		return
    443	end
    444	if not currentDep.compat then return end
    445	currentDep.paths = tbl
    446end
    447
    448-- Specifies a list of files found within the source directory that this project
    449-- should include during compile time. If after a dependency declaration, these
    450-- files will only be included in the project if the dependency is compatible
    451-- with the native system, given SDL_os usage and any sort of custom dependency
    452-- function.
    453function SDL_files(tbl)
    454	if not oscompat() then return end
    455	if not currentDep then
    456		currentProject.files = tbl
    457		return
    458	end
    459	if not currentDep.compat then return end
    460	currentDep.files = tbl
    461end