--- Define project, version, tarname, website, and contact.
-project = "Yoink"
-version = "0.1"
-tarname = project:lower():gsub("%s+", "-")
-website = "http://www.dogcows.com/yoink"
-contact = "onefriedrice@brokenzipper.com"
-
-
--- This script will create three different config files from three tables
--- with values determined by the host and configuration options:
---
--- The table `config' contains key-value pairs to be written to the file
--- `config.h' which is included by sources files. Boolean values will
--- either #define or #undef the key with no associated values. String
--- values will be defined as quoted strings while any other value,
--- particularly numbers, will be defined unquoted.
---
--- The table `define' contains key-value pairs to be written to the file
--- `config.mk' which is included by the Makefile. Values are assigned to
--- their keys as they are, unquoted.
---
--- The table `export' contains key-value pairs to be written to the file
--- `config.sed' which is used by sed to perform search-and-replace on files
--- containing @REPLACE_ME@-style keywords. When used with sed, such
--- keyworded keys will be replaced by their values as they are, unquoted.
-
-
-function show_help()
- print([[
-
-This script prepares ]]..project..[[ for building on your system.
-Usage: ./configure [OPTION]... [VAR=VALUE]...
-
-This is NOT an autoconf-generated configure script, though it was written
-to be familiar by supporting many of the same options.
-
-Basic configuration:
- -h, --help display this help and exit
- --host=HOST cross-compile the program to run on HOST
-
- --prefix=DIR base directory to install programs to
- --bindir=DIR directory to install executables
- --datadir=DIR directory to install shared data files
- --mandir=DIR directory to install manual pages
-
- --disable-dependency-tracking speed up one-time builds (maybe)
- --disable-special-linking do not use direct dependency minimizer
- --enable-profile compile in gprof profiling instructions
-
-Program options:
- --enable-clock_gettime use a very accurate timing function
- --enable-debug compile in assertion checks and other debug helps
- --enable-double-precision use larger floating-point numbers
- --enable-hotloading watch assets and automatically reload them
- --enable-threads use threads for concurrency where appropriate
-
- --with-gtk use the gtk2 toolkit (overrides --with-qt4)
- --with-qt4 use the qt4 gui toolkit
-]])
-end
-
-
---
--- Setup a temporary file to collect error messages.
---
-
-config_log = "config.log"
-os.remove(config_log)
-
-
---
--- Define some useful functions.
---
-
--- Return true if a file exists, false otherwise.
-function file_exists(path)
- return os.execute(string.format("test -f %q", path)) == 0
-end
-
--- Print an error message and exit with an error.
-function die(...)
- for i,value in ipairs(arg) do
- print("fatal: "..tostring(value))
- end
- if file_exists(config_log) then
- print()
- print("Look through the file `config.log' for more information:\n")
- os.execute("tail "..config_log)
- end
- os.exit(1)
-end
-
--- Execute a command and return its output or nil if the command failed to
--- run.
-function backtick_run(command)
- os.execute("echo '# "..command.."' >>"..config_log)
- local fd = io.popen(command.." 2>>"..config_log)
- if fd then
- local stdout = fd:read("*l")
- fd:close()
- return stdout
- end
- return nil
-end
-
--- Try to execute a command and return true if the command finished
--- successfully (with an exit code of zero).
-function try_run(command)
- os.execute("echo '# "..command.."' >>"..config_log)
- return os.execute(command.." >/dev/null 2>>"..config_log) == 0
-end
-
--- Remove the whitespace surrounding a string.
-function trim(str)
- str = str:gsub("^%s+", "")
- return str:gsub("%s+$", "")
-end
-
--- Trim the string and convert all sequences of whitespace to a single
--- space.
-function reduce_whitespace(str)
- str = str:gsub("%s+", " ")
- return trim(str)
-end
-
--- Get the CFLAGS from pkg-config for the passed libraries.
-function pkg_config_cflags(libs)
- local env = "PKG_CONFIG_PATH="..libdir.."/pkgconfig:$PKG_CONFIG_PATH"
- local cmd = env.." pkg-config"
- return backtick_run(cmd.." --cflags "..libs)
-end
-
--- Get the LDFLAGS from pkg-config for the passed libraries.
-function pkg_config_ldflags(libs)
- local env = "PKG_CONFIG_PATH="..libdir.."/pkgconfig:$PKG_CONFIG_PATH"
- local cmd = env.." pkg-config"
- return (" "..backtick_run(cmd.." --libs "..libs)):gsub("%s%-l%S*", "")
-end
-
--- Get the LIBS flags from pkg-config for the passed libraries.
-function pkg_config_libs(libs)
- local env = "PKG_CONFIG_PATH="..libdir.."/pkgconfig:$PKG_CONFIG_PATH"
- local cmd = env.." pkg-config"
- return backtick_run(cmd.." --libs-only-l "..libs)
-end
-
--- Add a flag to the CFLAGS and CXXFLAGS variables.
-function add_cflag(flag)
- if CFLAGS == "" then
- CFLAGS = flag
- else
- CFLAGS = string.format("%s %s", CFLAGS, flag)
- end
- if CXXFLAGS == "" then
- CXXFLAGS = flag
- else
- CXXFLAGS = string.format("%s %s", CXXFLAGS, flag)
- end
-end
-
--- Replace a flag in the CFLAGS and CXXFLAGS variables.
-function set_cflag(flag)
- local cflag_set, cxxflag_set = false, false
- CFLAGS = CFLAGS:gsub("%"..flag:sub(1, 2).."%S+", function()
- cflag_set = true
- return flag
- end)
- CXXFLAGS = CXXFLAGS:gsub("%"..flag:sub(1, 2).."%S+", function()
- cxxflag_set = true
- return flag
- end)
- if not cflag_set or not cxxflag_set then add_cflag(flag) end
-end
-
--- Look for a command from a list that can complete successfully (with exit
--- code zero) given some arguments. Returns nil if none were successful.
-function find_command(commands, args)
- if not args then args = "" end
- for i,command in ipairs(commands) do
- if try_run(command.." "..args) then return command end
- end
- return nil
-end
-
-
---
--- Perform a quick sanity check.
---
-
-if not file_exists("configure") or not file_exists("Makefile") then
- -- This script doesn't support out-of-tree builds.
- die("You must `cd' to the project root where the Makefile is.")
-end
-
-
---
--- Parse the command-line options.
---
-
--- This script supports many of the options provided by autoconf-generated
--- scripts. In particular, all the directory-related options are
--- supported, including --prefix, --exec-prefix, and all the --dirDIR
--- options for configuring installation paths. If passed, the option
--- parsing routine below will place these options in the global namespace
--- (i.e. prefix, eprefix, bindir, datadir, etc).
---
--- Feature and package options are also supported. The value of any option
--- of the form --enable-OPT= and --with-OPT= can be obtained with the
--- functions get_feature and get_package, respectively. Like
--- autoconf-generated scripts, passing --disable-OPT or --without-OPT is
--- equivalent to passing --enable-OPT=no and --without-OPT=no,
--- respectively. Values that are either yes or no are interpreted as
--- booleans. Any other values are interpreted as strings.
---
--- Definitions of the form KEY=VALUE are also supported. If passed, the
--- option parsing routine below will place these options in the global
--- namespace.
---
--- Finally, the options -h, --help, and --host are also supported, the
--- former two calling the show_help function and the latter setting the
--- host global variable.
-
-do
- local features = {}
- local packages = {}
- local handlers = {}
-
-
- -- Define the option-parsing rules and handlers.
-
- handlers["--help"] = function()
- show_help()
- os.exit(0)
- end
- handlers["-h"] = handlers["--help"]
-
- handlers["--host=(.+)"] = function(triplet)
- host = triplet
- cross_compile = true
- end
-
- local add_feature = function(feature, value)
- if value == "yes" or value == "" then value = true end
- if value == "no" then value = false end
- features[feature] = value
- end
- handlers["--enable%-([%w_-]+)=?(.*)"] = add_feature
- handlers["--disable%-([%w_-]+)"] = function(feature)
- add_feature(feature, "no")
- end
-
- local add_package = function(package, value)
- if value == "yes" or value == "" then value = true end
- if value == "no" then value = false end
- packages[package] = value
- end
- handlers["--with%-([%w_-]+)=?(.*)"] = add_package
- handlers["--without%-([%w_-]+)"] = function(package)
- add_package(package, "no")
- end
-
- handlers["--(%l+)dir=(.+)"] = function(dir, path)
- _G[dir.."dir"] = path
- end
- handlers["--prefix=(.+)"] = function(path)
- prefix = path
- end
- handlers["--exec-prefix=(.+)"] = function(path)
- eprefix = path
- end
-
- handlers["([%w_]+)=(.*)"] = function(key, value)
- _G[key] = value
- end
-
-
- -- Define the feature and package accessors.
-
- function get_feature(feature) return features[feature] end
- function get_package(package) return packages[package] end
-
-
- -- Now read and parse the command-line options.
-
- local function parse_arg(arg)
- for key,value in pairs(handlers) do
- local matches = {arg:match(key)}
- if matches[1] then value(unpack(matches)) return end
- end
- print("warning: unknown or incomplete argument "..arg)
- end
-
- for i,arg in ipairs(arg) do
- parse_arg(arg)
- end
-
-
- -- Define default values for significant variables.
-
- local function define(symbol, value)
- if not _G[symbol] then _G[symbol] = value end
- end
-
- define("CC", "")
- define("CXX", "")
- define("AR", "")
- define("RANLIB", "")
- define("WINDRES", "")
-
- define("CFLAGS", "-g -O2")
- define("CXXFLAGS", CFLAGS)
- define("LDFLAGS", "")
- define("LIBS", "")
-
- define("host", backtick_run("tools/config.guess"))
- define("alt_host", backtick_run("tools/config.sub "..host))
-
- define("prefix", "/usr/local")
- define("eprefix", prefix)
- define("bindir", eprefix.."/bin")
- define("sbindir", eprefix.."/sbin")
- define("libexecdir", eprefix.."/libexec")
- define("sysconfdir", prefix.."/etc")
- define("localstatedir", prefix.."/var")
- define("libdir", eprefix.."/lib")
- define("includedir", prefix.."/include")
- define("datarootdir", prefix.."/share")
- define("datadir", datarootdir.."/"..tarname)
- define("infodir", datarootdir.."/info")
- define("localedir", datarootdir.."/locale")
- define("mandir", datarootdir.."/man")
- define("docdir", datarootdir.."/doc/"..tarname)
-
- if features["dependency-tracking"] == nil then
- features["dependency-tracking"] = true
- end
-
- if features["special-linking"] == nil then
- features["special-linking"] = true
- end
-
- define("config", {})
- define("define", {})
- define("export", {})
-end
-
-
---
--- Determine special target platforms.
---
-
--- Win32 has some special cases related to its resource file, src/yoinkrc.
-if host:match("mingw32") then platform = "win32" end
-
-
---
--- Look for a working toolchain.
---
-
-print("Please wait...")
-
--- Check for CC.
-tmpname = os.tmpname()..".c"
-tmpfile, err = io.open(tmpname, "w")
-if tmpfile then
- tmpfile:write([[
-#include <stdio.h>
-int main()
-{
- printf("Hello world!\n");
- return 0;
-}
-]])
- tmpfile:close()
-
- function extra() if not cross_compile then return "gcc", "cc" end end
- CC = find_command({
- CC,
- host.."-gcc", host.."-cc",
- alt_host.."-gcc", alt_host.."-cc",
- extra()}, tmpname.." -o "..tmpname..".tmp")
- os.remove(tmpname)
- os.remove(tmpname..".tmp")
- if not CC then die("Can't find a working C compiler.") end
-else
- die("failed to create temporary file: "..err)
-end
-
--- Check for CXX.
-tmpname = os.tmpname()..".cpp"
-tmpfile, err = io.open(tmpname, "w")
-if tmpfile then
- tmpfile:write([[
-#include <iostream>
-int main()
-{
- std::cout << "Hello world!" << std::endl;
- return 0;