123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- -- Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
- --
- -- This software is provided 'as-is', without any express or implied
- -- warranty. In no event will the authors be held liable for any damages
- -- arising from the use of this software.
- --
- -- Permission is granted to anyone to use this software for any purpose,
- -- including commercial applications, and to alter it and redistribute it
- -- freely.
- --
- -- Meta-build system using premake created and maintained by
- -- Benjamin Henning <b.henning@digipen.edu>
- --[[
- sdl_projects.lua
- This file contains all the functions which are needed to define any project
- within the meta-build system. Many of these functions serve as
- pseudo-replacements for many similarly named premake functions, and that is
- intentional. Even the implementation of these functions are intended to look
- similar to regular premake code. These functions serve to dramatically
- simplify the project definition process to just a few lines of code, versus
- the many more needed for projects defined purely with premake.
- This approach is possible because this meta-build system adds another layer of
- indirection to the premake system, creating a sort of 'meta-meta-build'
- system. Nevertheless, there is a lot more flexibility because the meta-build
- system itself can be used to check for dependencies in a much more complex way
- than premake originally intended. All of the functions useful to the project
- definition system are contained in this file and are documented.
- ]]
- projects = { }
- local currentProject = nil
- local currentDep = nil
- local nextFuncCompat = true -- by default, unless state otherwise changed
- local dependencyFunctions = { }
- local dependencyResults = { } -- for when the dependencies are executed
- -- query whether this function is compatible; resets internal state of
- -- compatibility to true until SDL_isos is called again
- local function oscompat()
- local compat = nextFuncCompat
- nextFuncCompat = true
- return compat
- end
- -- determine whether the specific OS name is within a pattern.
- local function osmatch(name, pattern)
- local checks = pattern:explode('|')
- for i,v in pairs(checks) do
- if name == v then
- return true
- end
- end
- return false
- end
- -- Registers a dependency checker function based on a name. This function is
- -- used in order to determine compatibility with the current system for a given
- -- SDL_dependency. See SDL_depfunc for more information.
- --
- -- Specifies a function which will be invoked upon determining whether this
- -- dependency is valid for the current system setup (ie, whether the system
- -- has the right architecture, operating system, or even if it's installed).
- -- The dependency function takes no arguments, but it must return the following
- -- values:
- --
- -- <foundDep> [includePaths] [libPaths] [inputLibLibraries]
- --
- -- The last three are optional, unless foundDep is true. The name should be
- -- descriptive of the outside dependency, since it may be shown to the user.
- -- This function is intended to be used only after invoking SDL_dependency.
- function SDL_registerDependencyChecker(name, func)
- dependencyFunctions[name:lower()] = func
- end
- -- Initializes the definition of a SDL project given the name of the project.
- function SDL_project(name)
- if not oscompat() then return end
- currentProject = { }
- currentProject.name = name
- currentProject.compat = true
- projects[name] = currentProject
- currentProject.dependencyTree = { }
- -- stores which dependencies have already been checked on behalf of this
- -- project
- currentProject.dependencyValues = { }
- currentDep = nil
- end
- -- Specifies the build kind of the SDL project (e.g. StaticLib, SharedLib,
- -- ConsoleApp, etc.), based on premake presets.
- function SDL_kind(k)
- if not oscompat() then return end
- currentProject.kind = k
- end
- -- Specifies which platforms this project supports. Note: this list is not the
- -- exact list of supported platforms in the generated project. The list of
- -- platforms this project supports will be the unique list of all combined
- -- projects for this SDL solution. Thus, only one project needs to actually
- -- maintain a list. This function is additive, that is, everytime it is called
- -- it adds it to a unique list of platforms
- function SDL_platforms(tbl)
- if not oscompat() then return end
- if not currentProject.platforms then
- currentProject.platforms = { }
- end
- for k,v in pairs(tbl) do
- currentProject.platforms[#currentProject.platforms + 1] = v
- end
- end
- -- Specifies the programming language of the project, such as C or C++.
- function SDL_language(k)
- if not oscompat() then return end
- currentProject.language = k
- end
- -- Specifies the root directory in which the meta-build system should search for
- -- source files, given the paths and files added.
- function SDL_sourcedir(src)
- if not oscompat() then return end
- currentProject.sourcedir = src
- end
- -- Specifies the destination location of where the IDE files related to the
- -- project should be saved after generation.
- function SDL_projectLocation(loc)
- if not oscompat() then return end
- currentProject.projectLocation = loc
- end
- -- Specifies a table of files that should be copied from the source directory
- -- to the end result build directory of the binary file.
- function SDL_copy(tbl)
- if not oscompat() then return end
- currentProject.copy = tbl
- end
- -- Specifies a list of other SDL projects in this workspace the currently active
- -- project is dependent on. If the dependent project is a library, the binary
- -- result will be copied from its directory to the build directory of the
- -- currently active project automatically.
- function SDL_projectDependencies(tbl)
- if not oscompat() then return end
- currentProject.projectDependencies = tbl
- end
- -- Specifies a list of compiler-level preprocessor definitions that should be
- -- set in the resulting project upon compile time. This adds to the current
- -- table of defines.
- function SDL_defines(tbl)
- if not oscompat() then return end
- if not currentProject.defines then
- currentProject.defines = { }
- end
- for k,v in pairs(tbl) do
- currentProject.defines[#currentProject.defines + 1] = v
- end
- end
- -- Initializes an outside dependency this project has, such as X11 or DirectX.
- -- This function, once invoked, may change the behavior of other SDL
- -- project-related functions, so be sure to be familiar with all the functions
- -- and any specified behavior when used around SDL_dependency.
- function SDL_dependency(name)
- if not oscompat() then return end
- currentDep = { nil, compat = true, }
- currentDep.name = name
- table.insert(currentProject.dependencyTree, currentDep)
- end
- -- Special function for getting the current OS. This factors in whether the
- -- metabuild system is in MinGW, Cygwin, or iOS mode.
- function SDL_getos()
- if _OPTIONS["ios"] ~= nil then
- return "ios"
- elseif _OPTIONS["mingw"] ~= nil then
- return "mingw"
- elseif _OPTIONS["cygwin"] ~= nil then
- return "cygwin"
- end
- return os.get()
- end
- -- Specifies which operating system this dependency targets, such as windows or
- -- macosx, as per premake presets.
- function SDL_os(name)
- if not oscompat() then return end
- if not currentProject then return end
- if not currentDep then
- currentProject.opsys = name
- currentProject.compat = osmatch(SDL_getos(), name)
- else
- currentDep.opsys = name
- currentDep.compat = osmatch(SDL_getos(), name)
- end
- end
- -- Specifies which operating system this dependency does not targets. This is
- -- for nearly platform-independent projects or dependencies that will not work
- -- on specific systems, such as ios.
- function SDL_notos(name)
- if not oscompat() then return end
- if not currentProject then return end
- if not currentDep then
- currentProject.opsys = "~" .. name
- currentProject.compat = not osmatch(SDL_getos(), name)
- else
- currentDep.opsys = "~" .. name
- currentDep.compat = not osmatch(SDL_getos(), name)
- end
- end
- -- Changes the internal state of function compatibility based on whether the
- -- current os is the one expected; the next function will be affected by this
- -- change, but no others. The name can be a pattern using '|' to separate
- -- multiple operating systems, such as:
- -- SDL_isos("windows|macosx")
- function SDL_isos(name)
- nextFuncCompat = osmatch(SDL_getos(), name)
- end
- -- Same as SDL_isos, except it negates the internal state for exclusion
- -- checking.
- function SDL_isnotos(name)
- nextFuncCompat = not osmatch(SDL_getos(), name)
- end
- -- Changes the internal state of function compatibility based on whether the
- -- current system is running a 64bit Operating System and architecture; the
- -- next function will be affected by this change, but none thereafter.
- function SDL_is64bit()
- nextFuncCompat = os.is64bit()
- end
- -- Same as SDL_is64bit, except it negates the internal state for
- -- exclusion checking.
- function SDL_isnot64bit()
- nextFuncCompat = not os.is64bit()
- end
- -- Look at SDL_depfunc and SDL_notdepfunc for detailed information about this
- -- function.
- local function SDL_depfunc0(funcname, exclude)
- if not oscompat() then return end
- if not currentDep.compat then return end
- local force = _OPTIONS[funcname:lower()] ~= nil
- local func = dependencyFunctions[funcname:lower()]
- if not func then
- print("Warning: could not find dependency function named: " .. funcname)
- currentDep.compat = false
- return
- end
- local cachedFuncResults = dependencyResults[funcname:lower()]
- local depFound, depInc, depLib, depInput
- if cachedFuncResults then
- depFound = cachedFuncResults.depFound
- -- just skip the rest of the function, the user was already warned
- -- exclude mode varies the compatibility slightly
- if force then
- depFound = true
- end
- if not depFound and not exclude then
- currentDep.compat = false
- return
- elseif depFound and exclude then
- currentDep.compat = false
- return
- end
- depInc = cachedFuncResults.depInc
- depLib = cachedFuncResults.depLib
- depInput = cachedFuncResults.depInput
- else
- local result = func()
- if result.found then
- depFound = result.found
- else
- depFound = false
- end
- if force then
- depFound = true
- end
- if result.incDirs then
- depInc = result.incDirs
- else
- depInc = { }
- end
- if result.libDirs then
- depLib = result.libDirs
- else
- depLib = { }
- end
- if result.libs then
- depInput = result.libs
- else
- depInput = { }
- end
- cachedFuncResults = { }
- cachedFuncResults.depFound = depFound
- cachedFuncResults.depInc = depInc
- cachedFuncResults.depLib = depLib
- cachedFuncResults.depInput = depInput
- dependencyResults[funcname:lower()] = cachedFuncResults
- if not depFound and not exclude then
- currentDep.compat = false
- return
- elseif depFound and exclude then
- currentDep.compat = false
- return
- end
- end
- -- we only want to embed this dependency if we're not in exclude mode
- if depFound and not exclude then
- local dependency = { }
- if not currentDep.includes then
- currentDep.includes = { }
- end
- for k,v in pairs(depInc) do
- currentDep.includes[v] = v
- end
- if not currentDep.libs then
- currentDep.libs = { }
- end
- for k,v in pairs(depLib) do
- currentDep.libs[v] = v
- end
- if not currentDep.links then
- currentDep.links = { }
- end
- for k,v in pairs(depInput) do
- currentDep.links[v] = v
- end
- else -- end of dependency found check
- -- if we are not excluding this dependency, then print a warning
- -- if not found
- if not exclude then
- print("Warning: could not find dependency: " .. funcname)
- end
- currentDep.compat = exclude
- end
- end
- -- Given a dependency name, this function will register the dependency and try
- -- to pair it with a dependency function that was registered through
- -- SDL_registerDependencyChecker. If the function is not found, compatibility
- -- will automatically be dropped for this project and a warning will be printed
- -- to the standard output. Otherwise, the dependency function will be invoked
- -- and compatibility for the project will be updated. If the project currently
- -- is not compatible based on the Operating System or previous dependency, the
- -- dependency function will not be checked at all and this function will
- -- silently return.
- function SDL_depfunc(funcname)
- SDL_depfunc0(funcname, false)
- end
- -- Same as SDL_depfunc, except this forces dependency on the function failing,
- -- rather than succeeding. This is useful for situations where two different
- -- files are required based on whether a dependency is found (such as the
- -- joystick and haptic systems).
- function SDL_notdepfunc(funcname)
- SDL_depfunc0(funcname, true)
- end
- -- Determines whether the specified dependency is supported without actually
- -- executing the dependency or changing the internal states of the current
- -- project or dependency definition. This function will only work if the
- -- dependency has already been checked and its results cached within the
- -- definition system. This function returns true if the dependency is known to
- -- be supported, or false if otherwise (or if it cannot be known at this time).
- function SDL_assertdepfunc(funcname)
- -- if forced, then of course it's on
- if _OPTIONS[funcname:lower()] then
- return true
- end
- local results = dependencyResults[funcname:lower()]
- if not results or not results.depFound then
- -- either not excuted yet, doesn't exist, or wasn't found
- print("Warning: required dependency not found: " .. funcname ..
- ". Make sure your dependencies are in a logical order.")
- return false
- end
- return true
- end
- -- Returns a list of currently registered dependencies. The values within the
- -- table will be sorted, but their names will be lowercased due to internal
- -- handling of case-insensitive dependency names.
- function SDL_getDependencies()
- local deps = { }
- for k,_ in pairs(dependencyFunctions) do
- deps[#deps + 1] = k
- end
- table.sort(deps)
- return deps
- end
- -- Specifies a list of libraries that should always be linked to in this
- -- project, regardless of a dependency function. If after a dependency
- -- declaration, these files will only be included in the project if the
- -- dependency is compatible with the native system, given SDL_os usage and any
- -- sort of custom dependency function.
- function SDL_links(tbl)
- if not oscompat() then return end
- if currentDep and not currentDep.compat then return end
- if currentProject.customLinks == nil then
- currentProject.customLinks = { }
- end
- for i,v in ipairs(tbl) do
- currentProject.customLinks[#currentProject.customLinks + 1] = v
- end
- end
- -- Specifies a list of configuration values that are assigned as preprocessor
- -- definitions in the SDL configuration header, used to globally configure
- -- features during the building of the SDL library. If after a dependency
- -- declaration, these files will only be included in the project if the
- -- dependency is compatible with the native system, given SDL_os usage and any
- -- sort of custom dependency function.
- function SDL_config(tbl)
- if not oscompat() then return end
- if not currentDep then
- currentProject.config = tbl
- return
- end
- if not currentDep.compat then return end
- currentDep.config = tbl
- end
- -- Specifies a list of paths where all .c, .h, and .m files should be included
- -- for compiling, where the source directory is the root. If after a dependency
- -- declaration, these files will only be included in the project if the
- -- dependency is compatible with the native system, given SDL_os usage and any
- -- sort of custom dependency function.
- function SDL_paths(tbl)
- if not oscompat() then return end
- if not currentDep then
- currentProject.paths = tbl
- return
- end
- if not currentDep.compat then return end
- currentDep.paths = tbl
- end
- -- Specifies a list of files found within the source directory that this project
- -- should include during compile time. If after a dependency declaration, these
- -- files will only be included in the project if the dependency is compatible
- -- with the native system, given SDL_os usage and any sort of custom dependency
- -- function.
- function SDL_files(tbl)
- if not oscompat() then return end
- if not currentDep then
- currentProject.files = tbl
- return
- end
- if not currentDep.compat then return end
- currentDep.files = tbl
- end
|