X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=configure;h=09df45fdf580bdfd3bfddbca3e903027fe9e7db3;hp=8cc0b0d183071963c2c32602c3d19421f49f83fd;hb=6c9943707d4f33035830eba0587a61a34eaecbc2;hpb=af88821a172c4dfd138b91b2a5148ae50b502fa2 diff --git a/configure b/configure index 8cc0b0d..09df45f 100755 --- a/configure +++ b/configure @@ -1,607 +1,34 @@ -#!/usr/bin/env lua +#!/bin/sh --- --- Yoink --- Execute this file to configure the build system. --- +# +# Yoink +# Execute this file to configure the build system. +# --- 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-hotload automatically reload modified game assets - --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 -int main() -{ - printf("Hello world!\n"); - return 0; +die () { + while read line; do echo $line; done && exit ${1:-127} } -]]) - 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 -int main() -{ - std::cout << "Hello world!" << std::endl; - return 0; -} -]]) - tmpfile:close() - - function extra() if not cross_compile then return "g++", "c++" end end - CXX = find_command({ - CXX, - host.."-g++", host.."-c++", - alt_host.."-g++", alt_host.."-c++", - extra()}, tmpname.." -o "..tmpname..".tmp") - os.remove(tmpname) - os.remove(tmpname..".tmp") - if not CXX then die("Can't find a working C++ compiler.") end -else - die("failed to create temporary file: "..err) -end - --- Check for AR. -do - function extra() if not cross_compile then return "ar" end end - AR = find_command({ - AR, - host.."-ar", - alt_host.."-ar", - extra()}, "--version") - if not AR then die("Can't find a working archiver.") end -end - --- Check for RANLIB. -do - function extra() if not cross_compile then return "ranlib" end end - RANLIB = find_command({ - RANLIB, - host.."-ranlib", - alt_host.."-ranlib", - extra()}, "--version") - if not RANLIB then die("Can't find a working library indexer.") end -end - --- Check for WINDRES. -if platform == "win32" then - function extra() if not cross_compile then return "windres" end end - WINDRES = find_command({ - WINDRES, - host.."-windres", - alt_host.."-windres", - extra()}, "--version") - if not WINDRES then die("Can't find a working resource compiler.") end -end - - --- --- Configure the features and packages. --- - -if get_feature("debug") then - set_cflag("-O0") - add_cflag("-Wall -Wno-uninitialized") - config.DEBUG = true -else - config.NDEBUG = true -end - -config.ENABLE_CLOCK_GETTIME = get_feature("clock_gettime") -config.ENABLE_DOUBLE_PRECISION = get_feature("double-precision") -config.ENABLE_HOTLOADING = get_feature("hotload") -config.ENABLE_THREADS = get_feature("threads") -if get_feature("profile") then - config.ENABLE_PROFILING = true - add_cflag("-pg") - LDFLAGS = LDFLAGS .. "-pg" -end - -if get_package("gtk") then config.WITH_GTK = true end -if get_package("qt4") then config.WITH_QT4 = true end - - --- --- Check for the libraries we need. --- - -do - local dependencies = "sdl gl glu libpng openal vorbisfile lua" - - if get_package("gtk") then - dependencies = dependencies.." gtk+-2.0" - elseif get_package("qt4") then - dependencies = dependencies.." QtGui" - end - - add_cflag(pkg_config_cflags(dependencies)) - LDFLAGS = LDFLAGS .." "..pkg_config_ldflags(dependencies) - LIBS = LIBS .." "..pkg_config_libs(dependencies) - - if platform == "win32" then - LIBS = LIBS.." -lws2_32" - exe_extension = ".exe" - else - exe_extension = "" - end -end - - --- --- Define the exports and definitions. --- - -if platform == "win32" then - -- These are used in src/yoink.rc. - local vmajor, vminor, vrevis = version:match("^(%d*)%.?(%d*)%.?(%d*)") - config.VERSION_MAJOR = tonumber(vmajor) or 0 - config.VERSION_MINOR = tonumber(vminor) or 0 - config.VERSION_REVISION = tonumber(vrevis) or 0 -end - -config.PACKAGE = tarname -config.PACKAGE_NAME = project -config.PACKAGE_VERSION = version -config.PACKAGE_STRING = project.." "..version -config.PACKAGE_TARNAME = tarname -config.PACKAGE_URL = website -config.PACKAGE_BUGREPORT = contact -config.YOINK_GITHEAD = backtick_run("git describe master") -config.YOINK_DATADIR = datadir - -define.PACKAGE = project -define.TARNAME = tarname.."-"..version -define.TARGET = host -define.PLATFORM = platform -define.CC = CC -define.CXX = CXX -define.AR = AR -define.RANLIB = RANLIB -define.WINDRES = WINDRES -define.CFLAGS = reduce_whitespace(CFLAGS) -define.CXXFLAGS = reduce_whitespace(CXXFLAGS) -define.LDFLAGS = reduce_whitespace(LDFLAGS) -define.LIBS = reduce_whitespace(LIBS) -define.prefix = prefix -define.bindir = bindir -define.datadir = datadir -define.mandir = mandir -define.EXEEXT = exe_extension -define.DEP_TRACKING = get_feature("dependency-tracking") -define.DEP_MINIMIZING = get_feature("special-linking") - -export.datadir = datadir -- Used in doc/yoink.6.in. -export.PACKAGE_BUGREPORT = contact -- Used in doc/yoink.6.in. - - --- --- All done; output the configuration files. --- - --- Output the program options. -output = io.open("config.h", "w") -for key,value in pairs(config) do - key = tostring(key) - if type(value) == "boolean" then - if value then - output:write("#define "..key.." 1") - else - output:write("#undef "..key) - end - elseif type(value) == "string" then - output:write(string.format("#define %s %q", key, tostring(value))) - else - output:write(string.format("#define %s %s", key, tostring(value))) - end - output:write("\n") -end -output:close() - --- Output the make definitions. -output = io.open("config.mk", "w") -for key,value in pairs(define) do - key = tostring(key) - value = tostring(value) - output:write(string.format("%s = %s\n", key, value)) -end -output:close() - --- Output the exported variables. -output = io.open("config.sed", "w") -for key,value in pairs(export) do - key = key:gsub("/", "\\/") - value = value:gsub("/", "\\/") - output:write(string.format("s/@%s@/%s/g\n", key, value)) -end -output:close() +[ -f build/config.lua ] || die 1 <<"END" +You must first `cd' to the project directory root where the Makefile is. +There is no support for out-of-tree builds. +END +LUA=${LUA:-lua} +"$LUA" -v >/dev/null 2>&1 || die 2 </dev/null && \ + ! (cd build && ${MAKE:-make} dialog) && die 3 <