#
ifeq ($(DEP_TRACKING),true)
-COMPILE = ./tools/compile.lua
+COMPILE = ./tools/compile.lua
endif
+ifeq ($(AS_NEEDED),true)
+LINK = ./tools/link.lua
+endif
+
+INSTALL = ./tools/install.lua
+
# Include current directory to allow sources to #include "config.h".
CFLAGS += -I.
CXXFLAGS += -I.
COMMAND_CC = $(COMPILE) $(CC) $(CFLAGS) $(CF_TGT) -o $@ -c $<
COMMAND_CXX = $(COMPILE) $(CXX) $(CXXFLAGS) $(CF_TGT) -o $@ -c $<
-COMMAND_LD = $(CC) $(LDFLAGS) $(LF_TGT) -o $@ $^ $(LL_TGT) $(LIBS)
-COMMAND_LDX = $(CXX) $(LDFLAGS) $(LF_TGT) -o $@ $^ $(LL_TGT) $(LIBS)
+COMMAND_LD = $(LINK) $(CC) $(LDFLAGS) $(LF_TGT) -o $@ $^ $(LL_TGT) $(LIBS)
+COMMAND_LDX = $(LINK) $(CXX) $(LDFLAGS) $(LF_TGT) -o $@ $^ $(LL_TGT) $(LIBS)
COMMAND_CCLD = $(COMPILE) $(CC) $(CFLAGS) $(CF_TGT) $(LDFLAGS) $(LF_TGT) -o $@ $< $(LL_TGT) $(LIBS)
COMMAND_CXXLD = $(COMPILE) $(CXX) $(CXXFLAGS) $(CF_TGT) $(LDFLAGS) $(LF_TGT) -o $@ $< $(LL_TGT) $(LIBS)
COMMAND_AR = $(AR) rcs $@ $^; $(RANLIB) $@
COMMAND_RC = $(WINDRES) -I. $(DF_TGT) -o $@ -i $<
-COMMAND_INSTALL = ./tools/install.sh -m $1 $2 -d $3
+COMMAND_INSTALL = $(INSTALL) -m $1 $2 $3/
COMMAND_RM = rm -f $1
COMMAND_IN = sed -f config.sed <"$1" >"$2"
--mandir=DIR directory to install manual pages
--disable-dependency-tracking speed up one-time builds
- --enable-link-sh decrease the number of direct dependencies
+ --enable-asneeded decrease the number of direct dependencies
Program options:
--enable-debug include debugging symbols and code paths
--
-- Return true if a file exists, false otherwise.
-function file_exists(file)
- return os.execute("test -f "..file) == 0
+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 _,value in ipairs(arg) do
+ for i,value in ipairs(arg) do
print("fatal: "..tostring(value))
end
if file_exists(config_log) then
-- code zero) given some arguments. Returns nil if none were successful.
function find_command(commands, args)
if not args then args = "" end
- for _,command in ipairs(commands) do
+ for i,command in ipairs(commands) do
if try_run(command.." "..args) then return command end
end
return nil
print("warning: unknown or incomplete argument "..arg)
end
- for _,arg in ipairs(arg) do
+ for i,arg in ipairs(arg) do
parse_arg(arg)
end
config.USE_THREADS = get_feature("threads")
config.PROFILING_ENABLED = get_feature("profile") and add_cflag("-pg")
-if get_feature("link-sh") then
- -- TODO
+if get_feature("asneeded") then
+ define.AS_NEEDED = true
end
if get_package("gtk") then
<< " Compiler: " << COMPILER_STRING << std::endl
<< " Assets: " << assets << std::endl
<< "Build options: "
-#ifndef HAVE_CLOCK_GETTIME
+#if !USE_CLOCK_GETTIME
<< "-"
#endif
<< "clock_gettime "
-#ifdef NDEBUG
+#if !DEBUG
<< "-"
#endif
<< "debug "
-#ifndef USE_DOUBLE_PRECISION
+#if !USE_DOUBLE_PRECISION
<< "-"
#endif
<< "double-precision "
-#ifndef USE_GTK
+#if !USE_GTK
<< "-"
#endif
<< "gtk "
-#ifndef USE_HOTLOADING
+#if !USE_HOTLOADING
<< "-"
#endif
<< "hotloading "
-#ifndef PROFILING_ENABLED
+#if !PROFILING_ENABLED
<< "-"
#endif
<< "profile "
-#ifndef USE_QT4
+#if !USE_QT4
<< "-"
#endif
<< "qt4 "
-#ifndef USE_THREADS
+#if !USE_THREADS
<< "-"
#endif
<< "threads" << std::endl
table.insert(depfiles, depname)
for path in pairs(paths) do table.insert(depfiles, path.."/"..depname) end
-for _,gccdep in ipairs(depfiles) do
+for i,gccdep in ipairs(depfiles) do
tmpname = gccdep..".tmp"
-- Fix up the dependency file with correct paths.
if os.execute("test -f "..gccdep) == 0 and os.rename(gccdep, tmpname) then
--- /dev/null
+#!/usr/bin/env lua
+
+--
+-- Yoink
+-- This script is a predictable alternative to the system install program.
+--
+
+function show_help()
+ print([[
+
+Install files, optionally changing the mode of the installed files.
+Usage:
+ install.lua [-m MODE] SOURCE... DEST
+
+If DEST is a directory, the source(s) will be copied into DEST with their
+same names.
+]])
+end
+
+
+-- Get the next argument passed to the script.
+function shift()
+ var = arg[1]
+ table.remove(arg, 1)
+ return var
+end
+
+-- Execute a command and return its output or nil if the command failed to
+-- run.
+function backtick_run(command)
+ local fd = io.popen(command.." 2>/dev/null")
+ if fd then local stdout = fd:read("*l") fd:close() return stdout end
+ return nil
+end
+
+-- Return true if a filespec is a directory, false otherwise.
+function is_directory(path)
+ return os.execute(string.format("test -d %q", path)) == 0
+end
+
+-- Get the basename of a path.
+function basename(path, ext)
+ if not ext then ext = "" end
+ return backtick_run(string.format("basename %q %s", path, ext))
+end
+
+-- Get the directory part of a path.
+function dirname(path)
+ if path:sub(-1) == "/" then path = path .. "." end
+ return backtick_run(string.format("dirname %q", path))
+end
+
+-- Like mkdir -p except portable.
+function mkdir(path)
+ if path:sub(1,1) ~= "/" then path = os.getenv("PWD") .. "/" .. path end
+ path = path:gsub("/$", "")
+ path = path:gsub("/+", "/")
+ path = path:gsub("/[^/]+/%.%.", "")
+ path = path:gsub("%./", "")
+ path = path:gsub("/%.", "")
+
+ local compound = ""
+ for component in path:gmatch("(/[^/]*)") do
+ compound = compound .. component
+ if not is_directory(compound) then
+ local result = os.execute(string.format("mkdir %q", compound))
+ if result ~= 0 then os.exit(1) end
+ end
+ end
+end
+
+-- Change the mode of a file or directory.
+function chmod(mode, filespec)
+ if not mode or mode == "" then return end
+ local result = os.execute(string.format("chmod %s %q", mode, filespec))
+ if result ~= 0 then os.exit(1) end
+end
+
+-- Install a file. If destination is a directory, the source will be
+-- installed into the directory with the same name.
+function install(mode, source, dest)
+ if is_directory(dest) then dest = dest .. "/" .. basename(source) end
+ local result = os.execute(string.format("cp %q %q", source, dest))
+ if result == 0 then chmod(mode, dest) else os.exit(1) end
+end
+
+
+files = {}
+
+-- Consume and parse each argument.
+while 0 < #arg do
+ local v = shift()
+ if v == "-h" or v == "--help" then show_help() os.exit(0) end
+ if v == "-m" then mode = shift() else table.insert(files, v) end
+end
+
+-- Check the arguments and determine the target.
+if #files < 2 then show_help() os.exit(1)
+else target = table.remove(files) end
+
+-- Perform the installation.
+if 1 < #files then
+ mkdir(target)
+ for i,file in ipairs(files) do install(mode, file, target) end
+else
+ mkdir(dirname(target))
+ install(mode, files[1], target)
+end
+
+++ /dev/null
-#!/bin/sh
-#
-# INSTALL (C) 2002 Emile van Bergen. Distribution of this file is allowed under
-# the conditions detailed in the GNU General Public License (GPL). See the file
-# COPYING for more information.
-#
-# This script installs zero or more files into a specified directory. If one or
-# more components of the destination path do not exist, they are created. The
-# permissions of the destination file and the destination directory(s), if any
-# need to be created, can be specified separately. The user can also specify
-# that the operation must be skipped if the destination file or the destination
-# directory already exists. Source files are stripped of their directory
-# components before determining the destination name.
-#
-# It is intended to replace the /usr/bin/install command, which has no portable
-# subset of features that offers anything above /bin/cp. Each version is broken
-# in its own ways, the most annoying examples being that some can only install
-# a single file at a time and that some do not create destination directories
-# recursively. Hence this shell script, that is intended to be portable across
-# all POSIX-compliant /bin/sh shells. It does not assume a working 'mkdir -p'
-# command.
-#
-# Invocation:
-#
-# install arguments...
-#
-# Each argument is either an option, as specified below, a source file, or
-# a destination directory, with -d prepended. Each time a destination
-# directory is encountered, the source files leading up to it are installed,
-# and then all options are reset, allowing you to perform multiple install
-# operations with one command.
-#
-# Options:
-#
-# -h Show a brief usage message
-# -v Show what's being done
-# -m specify mode of destination files
-# -md specify mode of destination directories, if any are created
-# -n skip operation if destination file exists
-# -nd skip operation if destination directory exists
-#
-# Return values:
-#
-# 0 Successful completion
-# >0 Error occurred
-#
-# Limitations:
-#
-# * Source files cannot start with a '-' or contain spaces
-# * Destination directories cannot start with a '-' or contain spaces
-# * If multiple different modes are desired for files in a single destination
-# directory, you must specify multiple installation sets (-d options), one
-# for each mode (eg. install -m 644 file1 file2 -d dir file3 -m 600 -d dir).
-# * The /bin/sh shell used to run this script must support user-defined
-# functions.
-# * The system must have mkdir, chmod, basename, tr, sed and cp available.
-# If needed, basename and tr could be provided by sed, but I don't think
-# that should be done by default as they are very common.
-#
-# Notes (not bugs, features. Really!):
-#
-# * If the destination directory already exists, its mode is not changed
-# even if -md is specified; that mode is only used when creating new ones.
-# * If the destination file already exists but is overwritten because no -n
-# was specified, the new mode, if specified, is applied as well.
-# * QNX-style paths starting with // are honored, as are .. path components.
-# An initial .. works as expected, and a destination path a/b/../c creates
-# a, a/b, a/c and installs the files in a/c.
-#
-# History
-#
-# 2002/09/13 - EvB - Created
-
-
-make_dir() {
-
- dir="$1"
- [ -n "$verbose" ] && echo "Creating directory $dir"
-
- mkdir "$dir" || exit 1
-
- if [ -n "$mode_dir" ]
- then
- chmod "$mode_dir" "$dir" || exit 2
- fi
-
- return
-}
-
-
-make_dir_tree() {
-
- root=`echo $1 | sed -e 's/[^/].*$//g'`
- components=`echo $1 | tr / " "`
-
- cumul=
- for comp in $components
- do
- if [ -n "$cumul" ]
- then
- cumul="$cumul/$comp"
- else
- cumul="$comp"
- fi
- [ "$comp" = "." ] || [ "$comp" = ".." ] ||
- [ -d "$root$cumul" ] || make_dir "$root$cumul"
- done
-
- dest=$root$cumul
-}
-
-
-do_install() {
-
- dest="$1"
-
- if [ ! -d "$dest" ]
- then
- make_dir_tree "$dest"
- else
- if [ -n "$new_dir" ]
- then
- echo "$me: Directory $dest already exists -- skipping"
- return
- fi
- fi
-
- for src_file in $src
- do
- file=`basename $src_file`
- dest_file="$dest/$file"
-
- if [ -n "$new" ] && [ -f $dest_file ]
- then
- echo "$me: File $dest_file already exists -- skipping"
- continue
- fi
-
- [ -n "$verbose" ] && echo "Copying $src_file to $dest_file"
- cp "$src_file" "$dest_file" || exit 3
-
- if [ -n "$mode" ]
- then
- chmod "$mode" "$dest_file" || exit 4
- fi
- done
-
- return
-}
-
-
-init_opts() {
- verbose=
- mode=
- mode_dir=
- new=
- new_dir=
- src=
-}
-
-
-### Main entry point
-
-me=`basename $0`
-init_opts
-while [ -n "$1" ]
-do
- case "$1" in
-
- -v) verbose=1 ;;
-
- -m) mode="$2" ; shift ;;
- -md) mode_dir="$2" ; shift ;;
-
- -n) new=1 ;;
- -nd) new_dir=1 ;;
-
- -d) do_install "$2" ; init_opts ; shift ;;
-
- -*)
- echo Usage: $me [options] [file...] -d directory
- exit 5
- ;;
-
- *) src="$src $1" ;;
-
- esac
- shift
-done
-
-exit 0
--- /dev/null
+#!/usr/bin/env lua
+
+--
+-- Yoink
+-- Run this script to link the executable with fewer direct dependencies.
+--
+-- You shouldn't call this directly; instead, use the configure script's
+-- --enable-asneeded option and run make normally. This isn't enabled by
+-- default because there is the potential for runtime linking problems on
+-- some platforms. If you have a newer version of GCC, you should prefer
+-- the --as-needed linker flag over this method, though they both should
+-- accomplish the same thing.
+--
+
+
+-- List here any libraries that are known to not be needed on some
+-- platform.
+libraries = {
+ "atk-1.0",
+ "cairo",
+ "fontconfig",
+ "freetype",
+ "gdk-x11-2.0",
+ "gio-2.0",
+ "glib-2.0",
+ "gmodule-2.0",
+ "ogg",
+ "pango-1.0",
+ "pangocairo-1.0",
+ "pangoft2-1.0",
+ "pthread",
+ "vorbis"
+}
+
+
+-- We want to print only if verbose is set to true.
+do
+ local verbose = os.getenv("verbose") == "true"
+ local oldprint = print
+
+ print = function(...) if verbose then oldprint(unpack(arg)) end end
+end
+
+
+command = arg[1]
+removed = {}
+
+-- Get the link command as passed on the command-line.
+for i,arg in ipairs(arg) do
+ if i ~= 1 then
+ command = string.format("%s %q", command, arg)
+ end
+end
+
+original = command
+
+
+-- Check for libraries which aren't needed for successful linking.
+for i,library in ipairs(libraries) do
+ local new_command = command:gsub("%s\"%-l"..library.."+\"%s", " ")
+ if new_command ~= command then
+ if os.execute(new_command.." >/dev/null 2>&1") == 0 then
+ print("We DON'T need "..library)
+ table.insert(removed, library)
+ command = new_command
+ else
+ print("We DO need "..library)
+ end
+ end
+end
+
+
+-- Perform the final link.
+if 0 < #removed and os.execute(command.." >/dev/null 2>&1") == 0 then
+ local removed = table.concat(removed, ", ")
+ print("Linked fine without some libraries: "..removed)
+elseif os.execute(original.." >/dev/null 2>&1") == 0 then
+ print("Linked with the original link command.")
+else
+ print("The link failed. :-(")
+ os.exit(1)
+end
+
+++ /dev/null
-#!/bin/sh
-
-#
-# Yoink
-# Run this script to link the executable with fewer direct dependencies.
-#
-# You shouldn't call this directly; instead, use the configure script's
-# --enable-link-sh option and run make normally. This isn't enabled by
-# default because there is the potential for runtime linking problems on
-# some platforms. If you have a newer version of GCC, you should prefer
-# the --as-needed linker flag over this method, though they both should
-# accomplish the same thing.
-#
-# This script was adapted from some public domain code written by Bram
-# Moolenaar for Vim. The only input needed is the link command in the
-# variable LINK. It is expected that the linker will return an error code
-# or this will not work. The script caches the test results in the
-# `.link/link.sed' file; delete that file if you want to redetermine the
-# required direct dependencies.
-#
-
-
-# List here any libraries that are known to not be needed on some platform.
-libraries="\
- atk-1.0 \
- cairo \
- fontconfig \
- freetype \
- gdk-x11-2.0 \
- gio-2.0 \
- glib-2.0 \
- gmodule-2.0 \
- ogg \
- pango-1.0 \
- pangocairo-1.0 \
- pangoft2-1.0 \
- pthread \
- vorbis \
- $THE_END"
-
-
-linkdir=".link"
-logfile="$linkdir/link.log"
-sedfile="$linkdir/link.sed"
-
-workdir=$(mktemp -d tmp.XXXXXXXX)
-cmdfile="$workdir/link.cmd"
-runfile="$workdir/link.run"
-
-tmpfile1="$workdir/link.tmp1"
-tmpfile2="$workdir/link.tmp2"
-tmpfile3="$workdir/link.tmp3"
-
-
-printlog()
-{
- echo "link.sh: $@"
-}
-
-echo "$LINK " >$cmdfile
-exitcode=0
-
-
-if test -f $sedfile
-then
- printlog "The file $sedfile exists, which is now going to be used."
- printlog "If linking fails, try deleting the $sedfile file."
- printlog "If that fails, try creating an empty $sedfile file."
- printlog "If that fails, configure the package with --disable-link-sh."
-else
- cat $cmdfile
- if sh $cmdfile
- then
- mkdir -p $linkdir
- touch $sedfile
- cp $cmdfile $runfile
- for libname in $libraries
- do
- cont=yes
- while test -n "$cont"
- do
- if grep "l$libname " $runfile >/dev/null
- then
- if test ! -f $tmpfile1
- then
- printlog "Full linking works; now the fun begins."
- printlog "See $logfile for details."
- rm -f $logfile
- fi
- echo "s/-l$libname *//" >$tmpfile1
- sed -f $sedfile <$cmdfile | sed -f $tmpfile1 >$runfile
- # keep the last -lm; this is supposedly needed by HP-UX
- if test $libname != "m" || grep "lm " $runfile >/dev/null
- then
- printlog "Trying to remove the $libname library..."
- cat $runfile >>$logfile
- if sh $runfile >>$logfile 2>&1
- then
- printlog "We don't need the $libname library!"
- cat $tmpfile1 >>$sedfile
- continue
- else
- printlog "We DO need the $libname library."
- fi
- fi
- fi
- cont=
- cp $cmdfile $runfile
- done
- done
- if test ! -f $tmpfile1
- then
- printlog "Linked fine, no libraries can be removed."
- touch $tmpfile3
- fi
- else
- exitcode=$?
- fi
-fi
-
-
-if test -s $sedfile
-then
- printlog "Using $sedfile file to remove a few libraries."
- sed -f $sedfile <$cmdfile >$runfile
- cat $runfile
- if sh $runfile
- then
- exitcode=0
- printlog "Linked fine with a few libraries removed."
- else
- exitcode=$?
- printlog "Linking failed, making $sedfile empty and trying again."
- mv -f $sedfile $tmpfile2
- touch $sedfile
- fi
-fi
-
-if test -f $sedfile -a ! -s $sedfile -a ! -f $tmpfile3
-then
- printlog "Using unmodified link command."
- cat $cmdfile
- if sh $cmdfile
- then
- exitcode=0
- printlog "Linked OK."
- else
- exitcode=$?
- if test -f $tmpfile2
- then
- printlog "Linking doesn't work at all, removing $sedfile."
- rm -f $sedfile
- fi
- fi
-fi
-
-
-rm -rf "$workdir"
-exit $exitcode
-