Hint: If you are looking for an easy to use build system for OGRE, have a look at the [[Building From Source]] page.

Introduction

This is a little php script that compiles your application under linux systems. I'm not that sure if it works, because I wrote this long time ago and I'm not able to test it at the moment, but I was asked to wiki it. So here it is:

You need to copy the two php files you find on the bottom of this entry to some directory, e.g. the root of your project. For example we take a little project from me: a library with some common classes like an angle-class and so on. The project is called libTools and it creates the file libTools.so. The following is the directory structure of the project:

/game - the root of all my projects
 /game/Tools - the root of the project libTools
 /game/Tools/src - the directory which contains the source code
 /game/Tools/include - the directory which contains the headers
 /game/Tools/Build - the directory I want the temporary files to be saved


I copied the both php files to /game. In this directory the *.PROJECT files have to be stored (they are similar to the .dsp files of MSVC, or the .DEV files from Dev-C++). This is the .PROJECT file of the example project, it's called libTools.PROJECT, but it maybe called however you want. Only the extension .PROJECT is important.

The *.PROJECT files

Tools.PROJECT

<?
//the name of your project - this name is the target you have to pass to the build tool later
$NAME = "libTools";
$Project[$NAME] = Array(
	//WorkingDir: the dir in which the objects will be stored
	"WorkingDir" => "Build",

	//ShortDesc: a short description. This is showed by "build.php info [target]"
	"ShortDesc" => "Network and Logging tools",

	//Description: a more detailed description. This is showed by "build.php info [target]"
	"Description" => "%(c) 2005 by CORVUS MEDIA",
    
	"Output" => Array(
		//Filename: the filename of the executable/library you want to create
		"Filename" => "libTools.so", 

		//Path: the path where this file shall be stored
		"Path" => "/usr/lib",

		//SU: set this to true if you want the build tool to change to superuser mode before
		//    copying the file to it's destination (e.g. if you want to copy it to /usr/lib)
		"SU" => true,
	),
	
	"Compiler" => Array(
		//Includes: a list of directories that contain headers
		"Includes" => Array(
			"Tools/include",
		),
	
		//Packages: a list of packages the compiler needs to use (for pkg-config)
		"Packages" => Array(
			"OGRE",
		),
	    
		//Flags: additional compiler flags if needed
		"Flags" => "-g -O2",
	),
	
	"Linker" => Array(
		//Libraries: a list of libraries that you want to be linked to
		"Libraries" => Array(
		),
	
		//LibPaths: a list of directories which contain libraries the linker links to
		"LibPaths" => Array(
		),
	
		//Packages: see Compiler: Packages
		"Packages" => Array(
			"OGRE",
		),
	    
		//Flags: see Compiler: Flags
		"Flags" => "-g -O2 -shared ",
	),
    
	//SourceDirs: a list of directories in which the compiler compiles all *.cpp files
	"SourceDirs" => Array(
		"Tools/src",
	),
    
	//AdditionalSourceFiles: a list of single source files you want the compiler to compile, which
	//                       are not in the SourceDirs (see above)
	"AdditionalSourceFiles" => Array(
	),
);
?>

How to use

To use the build tool: Change to the directory that contains the both php files and execute build.php. You will be guided through the commands.
Here some of the common commands for the example:

~# cd /game
/game# php build.php info libTools
/game# php build.php config libTools
/game# php build.php build libTools
/game# php build.php clean libTools


Explanation:
info will show you some information about the target (in this case libTools): mainly it shows the descriptions<br />
config will check if everything is ready and gather information from packages etc.<br />
build will compile all ConfigDirs and AdditionConfigFiles and link them. Then it will copy them to Output/Path<br />
clean will delete all temporary build files, for example objects

Requirements

You need PHP, pkg-config, a compiler (e.g. gcc) and a linker (e.g. g++). This should be all.

Information

The build tool will automatically check for every source file if the headers which are included by the source file have changed since the last build (this is done by comparing the ctime of the header and the object). If the objects got deleted it recompiles the source files.
The tool actually should work. Maybe some paths to the compiler or so are wrong for your distribution. It's written under SuSE Linux Professional 9.2.

Tip_icon.png Attention! This tool was actually only coded for home use. It may be specific for my projects!
If you have problems you may post in this thread in the help forum:
http://www.ogre3d.org/phpBB2/viewtopic.php?t=12786

The php files

Attention! The line breaks in the following to files are no mistakes!
build.php

<?
include "functions.php";

function gettargets()
{
    $targets = rscan(".", ".PROJECT");
    if (count($targets) == 0)
	$targets_txt = "  no targets found!\n";
	
    else
    {
	$targets_txt = "";
	foreach ($targets as $t)
	{
	    include($t);
	
	    $pos = strrpos($t, "/");
	    if ($pos !== false) $pos++;
	    $part1 = "  $NAME";
	    if (strlen($part1) > 27) $part1 = substr($part1, 0, 27);
	    else $part1 .= str_repeat(" ", 27-strlen($part1));
	    
	    $targets_txt .= "$part1 -- ".substr($Project[$NAME]["ShortDesc"], 0, 40)."\n";	}
    }
    
    return $targets_txt;
}

echo "############### PALABA BUILD SYSTEM ###############\n";
register_parameters();
$rebuild = false;
$info = false;
$conf = false;
$clean = false;

if ($argc == 1)
{
    $targets_txt = gettargets();
    $t = explode("\n", $targets_txt);
    $c = 1;
    $tnames[0] = "all";
    $rnames[0] = "all";
    foreach ($t as $i => $v)
    {
	if (trim($v) != "")
	{
	    $t[$i] = (($c < 10) ? "  " : "   ") . $c . " |". substr($v, 1);
	    $tnames[$c] = "'".trim(substr(trim($v), 0, strpos(trim($v), " ")))."'";
	    $rnames[$c] = trim(substr(trim($v), 0, strpos(trim($v), " ")));
	    $c++;
	}
    }
    $targets_txt = implode("\n", $t);
    
    echo 
"No parameters set, maybe you should take a look at 'build help'

Aviable targets:
 id | target 
  0 | all
$targets_txt

If you want to build any targets, you can now enumerate them.
Please type in the ids of the targets you want to build seperated by spaces.
Example: 1 2
ids to build: ";
    $tt_build = trim(fgets(STDIN));
    echo 
"
Do you want a to rebuild those targets (y/n)? ";
    $reb = trim(fgets(STDIN));
    if ($reb == "y")	
	$rebuild = true;

    $a = explode(" ", "$tt_build ");
    $b = Array();
    $s = Array();
    foreach ($a as $i => $v)
    {
	if ($v == "0")
	{
	    $b = Array("0");
	    break;
	}
	
	else if ($v == "")
	{
	}
	
	else
	{
	    if (intval($v) >= $c)
		$a[$i] = -1;
	    
	    else
	    {
		if (!$s[intval($v)])
		{
		    $s[intval($v)] = true;
		    $b[] = intval($v);
		}
	    }
	}
    }
    
    $max = count($b);
    if ($max == 1)
    {
	$text = $tnames[$b[0]];
	$argv[] = $rnames[$b[0]];
    }
	
    elseif ($max == 0)
	die();
	
    else
    {
	$text = "";
	foreach ($b as $i => $v)
	{
	    if ($v > 0)
	    {
		$concat = ($i == $max - 1) ? " and " : ", ";
	    
		if ($i > 0)
		    $text .= $concat;
		
		$text  .= $tnames[$v]; 
		$argv[] = $rnames[$v];
	    }
	}
    }

    echo "
Do you really want to ".(($rebuild)?"re":"")."build $text? (y/n) ";
    $sure = trim(fgets(STDIN));
    
    if ($sure != "y")
	die();
}

if ($params["help"])
{
    $targets_txt = gettargets();

    echo 
"Possible commands:
  build all                 -- build all targets
  build [target]            -- build special target
  build rebuild all         -- rebuild all targets
  build rebuild [target]    -- rebuild special target
  build clean all           -- remove temporary files
  build clean [target]      -- remove temporary files
  build config all          -- configure the targets
  build config [target]     -- configure the targets
  build help                -- show this screen
  build info [target]       -- show information
  
Possible targets:
$targets_txt

";
    die();
}

else if ($params["rebuild"])
{
    $rebuild = true;

    $argv[1] = $argv[0];    
    array_shift($argv);
}

else if ($params["clean"])
{
    $clean = true;
    $argv[1] = $argv[0];    
    array_shift($argv);
}

else if ($params["info"])
{
    $info = true;

    $argv[1] = $argv[0];    
    array_shift($argv);
}

else if ($params["config"])
{
    $conf = true;

    $argv[1] = $argv[0];    
    array_shift($argv);
}

$targets = $argv;
array_shift($targets);

if (count($targets) == 0)
{
    echo "ERROR: no targets\n";
    die();
}

$configs = rscan(".", ".CONFIG");
foreach ($configs as $cfg)
    include($cfg);

$avaiable_targets = rscan(".", ".PROJECT");
$av_tar_name = Array();
foreach ($avaiable_targets as $target)
{
    include($target);
    $av_tar_name[] = $NAME;
}
	
if ($argv[1] == "all")
    $targets = $av_tar_name;

echo "Targets in queue: ".implode(" ", $targets)."\n";
    
$missing_targets = Array();
foreach ($targets as $target)
    if (!is_array($Project[$target]))
        $missing_targets[] = $target;
	    
if (count($missing_targets) > 0)
{
    echo "\nERROR: Missing targets: ".implode(" ", $missing_targets)."\n\n";
    die();
}
    
echo "\nAll targets found, continuing!\n";
    
foreach ($targets as $target)
{
    if ($info)
	printDesc($target);
	
    else if ($clean)
	clean($target);
    
    else if ($conf)
	configure($target);
	
    else
	build($target, $rebuild);
}
?>


functions.php

<?
function register_parameters()
{
    global $params, $argv;
    $params = Array();
    
    $params[$argv[1]] = true;
}

function rscan($dir, $file)
{
    $ret = Array();
    $w = dir($dir);
    
    while ($f = $w->read())
    {
	if ($f != "." && $f != "..")
	{
	    if (is_file($dir."/".$f))
	    {
		if (substr($f, -strlen($file)) == $file)
		    $ret[] = $dir."/".$f;
	    }
	    else
		$ret = array_merge($ret, rscan($dir."/".$f, $file));
	}
    }
    $w->close();
    
    return $ret;
}

function printDesc($target)
{
    global $Project;
    $p = $Project[$target];

    $tmp = explode("\n", $p["Description"]."\n");
    $desc = "";
    
    foreach ($tmp as $e)
    {
	$centered = false;
	if (substr($e, 0, 1) == "%")
	{
	    $centered = true;
	    $e = substr($e, 1);
	}
	
	$e = substr($e, 0, 42);
	
	if ($centered)
	{
	    //centered
	    $rest = 42 - strlen($e);
	    $ladd = floor($rest/2);
	    $radd = ceil ($rest/2);
	}
	
	else
	{
	    $ladd = 0;
	    $radd = 42 - strlen($e);
	}
	
	$desc .= "# ".str_repeat(" ", $ladd)."$e".str_repeat(" ", $radd)." #\n";
    }
    
    if (strlen($target) <= 42) 
    {
	$rest = 42 - strlen($target);
	$ladd = floor($rest/2);
	$radd = ceil ($rest/2);
	
	$target_txt = str_repeat(" ", $ladd).$target.str_repeat(" ", $radd);
    }
    
    else $target_txt = substr($target, 0, 42);
    echo "
##############################################
# $target_txt #
##############################################
#                                            #
$desc##############################################

";
}

function build($target, $rebuild = false)
{
    global $Project, $Config, $objects, $error, $counter, $cmd;
    
    $objects = Array();
    $p = $Project[$target];
    $c = $Config[$target];
    
    if ($c["COMPILER"] == "") 
	$c["COMPILER"] = "g++";
	
    if ($c["LINKER"] == "") 
	$c["LINKER"] = "g++";
	
    if ($c["PKGCONFIG"] == "")
	$c["PKGCONFIG"] = "pkg-config";
    
    printDesc($target);
    
    $wd = $p["WorkingDir"];
    if (!is_dir($wd))
	mkdir($wd);
	
    $cmd  = $c["COMPILER"]." -c ";
    $cmd .= $p["Compiler"]["Flags"];
    $cmd .= $c["CFLAGS"];
    
    if (count($p["Compiler"]["Packages"]) && $c["PKGCONFIG"] != "-")
    {
        $pkgflags = "";
	exec($c["PKGCONFIG"]." --cflags ".implode(" ", $p["Compiler"]["Packages"])." 2>&1", $pkgflags);
	$cmd .= " $pkgflags[0] ";
    }
    
    foreach ($p["Compiler"]["Includes"] as $inc)
        $cmd .= " -I$inc";
    
    foreach ($p["SourceDirs"] as $sd)
    {
	$error = false;
	$wdn = $wd."/".$sd;
        mkdir2($wdn);
	    
	echo "Diving into SourceDir '$sd':\n";
	
	$d = @dir($sd);
	if ($d === false)
	    echo "Warning: Could not find SourceDir '$sd'! Resuming.\n";

	else
	{
	    if ($rebuild)
	    {
		echo "Removing objects (rebuild mode)\n";
		while ($file = $d->read())
		{
		    if ($file != "." && $file != ".." && is_file($sd."/".$file))
		    {
			$file = "$wdn/".substr($file, 0, strrpos($file, ".")).".o";
			if (file_exists($file))
			    unlink($file);
		    }
		}
		$d->rewind();
	    }
	    
	    $counter = 0;
	    while ($file = $d->read())
	    {
		if ($file != "." && 
		    $file != ".." && 
		    is_file($sd."/".$file) && 
		    (substr($file, -4) == ".cpp" || 
		     substr($file, -2) == ".c"   || 
		     substr($file, -3) == ".cc"))
		    compileFile($file, $wdn, $sd);
	    }
	    
	    echo "$counter files compiled".($error?" - errrors occured!\n\n" : " - everything OK\n\n");
	}
    }
    
    $asf = $p["AdditionSourceFiles"];
    if (count($asf))
    {
	$error = false;
	echo "\nProcessing additional files:\n";
	foreach ($asf as $as)
	{
	    if (strpos($as, "/") === false)
	    {
		$path = ".";
		$file = $as;
	    }
	    else
	    {
		$path = substr($as, 0, strrpos($as, "/"));
		$file = substr($as, strlen($path) + 1);
	    }
	    
	    if (!is_file("$path/$file"))
	    {
		echo "ERROR: Cannot find additional source file '$path/$file'
Continue? (y/n) ";
		$yn = trim(fgets(STDIN));
		
		if ($yn != "y")
		    die();
	    }
	    else
	    {
		$wdn = "$wd/$path";
		mkdir2($wdn);
		
		compileFile($file, $wdn, $path);		
	    }
	}
	echo "$counter files compiled".(($error)?" - errrors occured!\n\n" : " - everything OK\n\n");
    }
    
    if ($error)
	return;
    
    if ($p["Output"]["SU"])
	echo "Maybe you will be asked for your root password now:\n";
	
    $exec_cmd = $p["Linker"]["Flags"] . $c["LFLAGS"];
    
    if (count($p["Linker"]["Packages"]) && $c["PKGCONFIG"] != "-")
    {
	$pkgflags = "";
	exec($c["PKGCONFIG"]." --libs ".implode(" ", $p["Linker"]["Packages"])." 2>&1", $pkgflags);
	$exec_cmd .= " $pkgflags[0] ";
    }

    foreach ($p["Linker"]["Libraries"] as $lib)
        $exec_cmd .= " -l$lib";
	
    foreach ($p["Linker"]["LibPaths"] as $lp)
	$exec_cmd .= " -L$lp";
	
    $exec_cmd = (($p["Output"]["SU"]) ? "sudo " : "").$c["LINKER"]." -pass-exit-codes $exec_cmd -o ".$p["Output"]["Path"]."/".$p["Output"]["Filename"]." ".implode(" ", $objects)." 2>&1";
    
    if ($counter > 0 || 
	!file_exists($p["Output"]["Path"]."/".$p["Output"]["Filename"]) ||
	timecheck2($p["Output"]["Path"]."/".$p["Output"]["Filename"], $objects))
    {
	echo "  [LD] ".$p["Output"]["Path"]."/".$p["Output"]["Filename"]."\n";
	exec($exec_cmd, $output, $ret);
    
	$error = false;
	if ($ret > 0)
	{
	    echo "ERROR while linking!
Do you want to see the linker output? (y/n) ";
	    $line = trim(fgets(STDIN));
	    if ($line == "y")
	    {
		echo "Linker output: $exec_cmd\n";
		echo implode("\n", $output);
	    }
	    echo "
Do you want to save the linker output to link.log? (y/n) ";
	    $line = trim(fgets(STDIN));
	    if ($line == "y")
	    {
		$fh = fopen("link.log", "w+");
		fwrite($fh, "Linker output: $exec_cmd
".implode("\n", $output));
		fclose($fh);
	    }
	    echo "
Continue? (y/n) ";
	    $yn = trim(fgets(STDIN));
		
	    if ($yn != "y")
	    {
		echo"\n";
		die();
	    }
	    
	    $error = true;
	}
	echo "File successfully linked - ".(($error)?"errors occured!\n":"everything OK\n");
    }

    if (!$error)    
	echo "Build of '$target' completed!\n";
	
    echo "\n\n";
}

function compileFile($file, $wdn, $sd)
{
    global $cmd, $objects, $counter, $error;
    $output = "";
    $ret = "";
    $filename = substr($file, 0, strrpos($file, "."));
    $object = "$wdn/$filename.o";
    
    $objects[] = $object; 
    $exec_cmd = "$cmd -o $object $sd/$file 2>&1";
	    
    if (timecheck($cmd, "$sd/$file", $object))
    {
	if (is_file($object))
	    unlink($object);
    
	$counter++;
	echo "  [CC] $file\n";
	exec($exec_cmd, $output, $ret);
	if ($ret > 0)
	{
	    echo "ERROR while compiling!\nDo you want to see the compilers output? (y/n) ";
	    $line = trim(fgets(STDIN));
	    if ($line == "y")
	    {
		echo "Compiler output: $exec_cmd\n";
		echo implode("\n", $output);
	    }
	    echo "
Do you want to continue? (y/n) ";
	    $error = true;
	    
	    $line = trim(fgets(STDIN));
	    if ($line != "y")
	    {
		echo "\n\n";
		die();
	    }
	}
    }
}

function timecheck($cmd, $file, $obj, $level = 1)
{
    if ($level >= 4)
	return false;
	
    if (@filemtime($obj) < filemtime($file))
	return true;
	
    $content = file_get_contents($file);
    preg_match_all("/\#include [\<\"]([^\n]*)[\>\"]/si", $content, $out);
    preg_match_all("/\-I([^ ]*)/si", $cmd, $out2);
    
    $headers = $out[1];
    $paths = $out2[1];
    
    foreach ($headers as $header)
    {
	if (is_file($header))
//	    if (filemtime($header) > filemtime($obj))
	    if (timecheck($cmd, $header, $obj, $level + 1))
		return true;
		
	foreach ($paths as $path)
	{
	    if (is_file($path."/".$header))
//		if (filemtime("$path/$header") > filemtime($obj))
		if (timecheck($cmd, "$path/$header", $obj, $level + 1))
		    return true;
	}	
    }
	
    return false;
}

function timecheck2($target, $objs)
{
    $tt = filemtime($target);

    foreach ($objs as $obj)
    {
	if (!file_exists($obj))
	    return true;
	    
	else
	    if (filemtime($obj) > $tt)
		return true;
    }
    
    return false;
}

function mkdir2($dir)
{
    if (is_dir($dir)) 
	return;
	
    $dir_above = substr($dir, 0, strrpos($dir, "/"));
    mkdir2($dir_above);
    mkdir($dir);
}

function clean($target)
{
    global $Project;
    
    $objects = Array();
    $p = $Project[$target];
    
    $wd = $p["WorkingDir"];
    
    foreach ($p["SourceDirs"] as $sd)
    {
	$wdn = $wd."/".$sd;
	echo "Diving into SourceDir '$sd':\n";
	
	if (!is_dir($wdn))
	    echo "Warning: Could not find TempObjDir '$wdn'! Resuming.\n";
	
	$d = @dir($sd);
	if ($d === false)
	    echo "Warning: Could not find SourceDir '$sd'! Resuming.\n";

	else
	{
	    echo "Removing objects\n";
	    while ($file = $d->read())
	    {
		if ($file != "." && $file != ".." && is_file($sd."/".$file))
		{
		    $file = "$wdn/".substr($file, 0, strrpos($file, ".")).".o";
		    if (file_exists($file))
			unlink($file);
		}
	    }
	}
    }
    echo "Clean complete!\n\n";
}

function configure($target)
{
    global $Project, $Config;
    $p = $Project[$target];
    $c = Array();
    
    echo "Configuring $target:\n";
    ////// run some tests
    // check for programs: g++ pkg-config
    $ncmd = checkForCMD("g++", "g++", false);
    $c["COMPILER"] = $ncmd;
    $c["LINKER"] = $ncmd;
    
    if (count($p["Linker"]["Packages"]) + count($p["Compiler"]["Packages"]) > 0)
    {
	if (($ncmd = checkForCMD("pkg-config", "pkg-config")) === false)
	{
	    $cflags = "";
	    $lflags = "";
	
	    foreach ($p["Compiler"]["Packages"] as $pck)
	    {
		echo "Specify the compiler flags (CFLAGS) needed for $pck
: ";
		$cflags .= " " . trim(fgets(STDIN));
	    }

	    foreach ($p["Linker"]["Packages"] as $pck)
	    {
		echo "Specify the linker flags (LFLAGS) needed for $pck
: ";
		$lflags .= " " . trim(fgets(STDIN));
	    }
	
	    $c["CFLAGS"] = $cflags;
	    $c["LFLAGS"] = $lflags;
	    $c["PKGCONFIG"] = "-";
	}
	else
	    $c["PKGCONFIG"] = $ncmd;
    }
    else
	$c["PKGCONFIG"] = "-";

    //test for modules:
    if ($c["PKGCONFIG"] != "-")
    {
	$ps = array_unique(array_merge($p["Compiler"]["Packages"], $p["Linker"]["Packages"]));
    
	foreach ($ps as $pkg)
	{
	    $nc = checkForPKG($c["PKGCONFIG"], $pkg);
	    $c["CFLAGS"] .= " ".$nc["CFLAGS"];
	    $c["LFLAGS"] .= " ".$nc["LFLAGS"];
	}	
    }
    
    //test for pathes:
    foreach ($p["Compiler"]["Includes"] as $dir)
	if (!is_dir($dir))
	    echo "Warning: '$dir' not found (Compiler>Includes)\n";
    
    preg_match_all("/\-I([^ ]*) /", $p["Compiler"]["Flags"]." ".$c["CFLAGS"], $ret);
    foreach ($ret[1] as $dir)
	if (!is_dir($dir))
	    echo "Warning: '$dir' not found (Compiler>Flags)\n";
	
    foreach ($p["Linker"]["LibPaths"] as $dir)
	if (!is_dir($dir))
	    echo "Warning: '$dir' not found (Linker>LibPaths)\n";
	
    preg_match_all("/\-I([^ ]*) /", $p["Linker"]["Flags"]." ".$c["LFLAGS"], $ret);
    foreach ($ret[1] as $dir)
	if (!is_dir($dir))
	    echo "Warning: '$dir' not found (Linker>Flags)\n";
	
    foreach ($p["SourceDirs"] as $dir)
	if (!is_dir($dir))
	    echo "Warning: '$dir' not found (SourceDirs)\n";
	
    foreach ($p["AdditionalSourceFiles"] as $file)
	if (!is_file($file))
	    echo "Warning: '$file' not found (AdditionalSourceFiles)\n";
	    
    //test for libraries
    $linkpathes = "";
    foreach ($p["Linker"]["LibPaths"] as $dir)
	$linkpaths .= " -L$dir";
	
    preg_match_all("/\-I([^ ]*) /", $p["Linker"]["Flags"]." ".$c["LFLAGS"], $ret);
    foreach ($ret[1] as $dir)
	$linkpaths .= " -L$dir";

    foreach ($p["Linker"]["Libraries"] as $lib)
    {
	echo "test for lib '$lib'...";
	exec("ld -o /dev/null --noinhibit-exec --unresolved-symbols=ignore-all $linkpaths -l$lib 2>&1", $out, $ret);
	if ($ret != 0)
	    echo "failed\nWarning: '$lib' not found (Linker>Libraries)\n";
	    
	else
	    echo "ok\n";
    }
	
    preg_match_all("/\-l([^ ]*) /", $p["Linker"]["Flags"]." ".$c["LFLAGS"], $ret);
    foreach ($ret[1] as $lib)
    {
	echo "test for lib '$lib'...";
	exec("ld --noinhibit-exec --unresolved-symbols=ignore-all $linkpaths -l$lib 2>&1", $out, $ret);
	if ($ret != 0)
	    echo "failed\nWarning: '$lib' not found (Linker>Libraries)\n";
	    
	else
	    echo "ok\n";
    }
    
    echo "Configuration completed!\n\n";
    
    $fh = fopen("$target.CONFIG", "w+");
    $config_code = var_export($c, true);
    fwrite($fh, "<?
\$Config[\"$target\"] = $config_code
?>
");
    fclose($fh);
    
    $Config[$target] = $c;
}

function checkForPKG($cmd, $pkg)
{
    echo "test for pkg $pkg...";
    
    exec("$cmd --exists $pkg 2>&1", $out, $ret);
    if ($ret == 0)
    {
	echo "ok\n";
	return Array();
    }
    
    echo "failed
Do you want to set your own flags? (y/n) ";
    $yn = trim(fgets(STDIN));
    
    $name = Array(
	"OGRE" => "Ogre3D Rendering Engine",
	"CEGUI" => "Crazy Eddies Gui System",
    );
    
    if ($yn != "y")
	die("ERROR: Could not find package $pkg
".(($name[$pkg])?"Are you sure you have installed ".$name[$pkg]."?":"")."

"	);
    
echo "Specify the compiler flags (CFLAGS) needed for $pkg
: ";
    $cflags .= " " . trim(fgets(STDIN));
    
    echo "Specify the linker flags (LFLAGS) needed for $pkg
: ";
    $lflags .= " " . trim(fgets(STDIN));

    $c = Array();
    $c["CFLAGS"] = $cflags;
    $c["LFLAGS"] = $lflags;
    return $c;
}

function checkForCMD($org, $cmd, $bSel = true)
{
    echo "test for $org...";
    exec("$cmd --version 2>&1", $out, $ret);
    if ($ret > 0)
    {
	echo "failed\nERROR: Cannot find $cmd
";	
	if ($bSel)
	{
	    echo "Do you want to use $org? (y/n) ";
	    $yn = trim(fgets(STDIN));
	}
	else
	    $yn = "y";
	    
	if ($yn == "y")
	{
	    echo "Please specify the full command to $org (i.e. /usr/bin/$org)
: ";
	    $new_cmd = trim(fgets(STDIN));
	    return checkForCMD($org, $new_cmd, $bSel);
	}
	else
	{
	    return false;
	}
    }
    else
    {
        echo "ok\n";
	return $cmd;
    }
}
?>

<HR>
Creative Commons Copyright -- Some rights reserved.


THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.

BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.

1. Definitions

  • "Collective Work" means a work, such as a periodical issue, anthology or encyclopedia, in which the Work in its entirety in unmodified form, along with a number of other contributions, constituting separate and independent works in themselves, are assembled into a collective whole. A work that constitutes a Collective Work will not be considered a Derivative Work (as defined below) for the purposes of this License.
  • "Derivative Work" means a work based upon the Work or upon the Work and other pre-existing works, such as a translation, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or any other form in which the Work may be recast, transformed, or adapted, except that a work that constitutes a Collective Work will not be considered a Derivative Work for the purpose of this License. For the avoidance of doubt, where the Work is a musical composition or sound recording, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered a Derivative Work for the purpose of this License.
  • "Licensor" means the individual or entity that offers the Work under the terms of this License.
  • "Original Author" means the individual or entity who created the Work.
  • "Work" means the copyrightable work of authorship offered under the terms of this License.
  • "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
  • "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike.

2. Fair Use Rights

Nothing in this license is intended to reduce, limit, or restrict any rights arising from fair use, first sale or other limitations on the exclusive rights of the copyright owner under copyright law or other applicable laws.

3. License Grant

Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:

  • to reproduce the Work, to incorporate the Work into one or more Collective Works, and to reproduce the Work as incorporated in the Collective Works;
  • to create and reproduce Derivative Works;
  • to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission the Work including as incorporated in Collective Works;
  • to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission Derivative Works.
  • For the avoidance of doubt, where the work is a musical composition:
    • Performance Royalties Under Blanket Licenses. Licensor waives the exclusive right to collect, whether individually or via a performance rights society (e.g. ASCAP, BMI, SESAC), royalties for the public performance or public digital performance (e.g. webcast) of the Work.
    • Mechanical Rights and Statutory Royalties. Licensor waives the exclusive right to collect, whether individually or via a music rights society or designated agent (e.g. Harry Fox Agency), royalties for any phonorecord You create from the Work ("cover version") and distribute, subject to the compulsory license created by 17 USC Section 115 of the US Copyright Act (or the equivalent in other jurisdictions).
    • Webcasting Rights and Statutory Royalties. For the avoidance of doubt, where the Work is a sound recording, Licensor waives the exclusive right to collect, whether individually or via a performance-rights society (e.g. SoundExchange), royalties for the public digital performance (e.g. webcast) of the Work, subject to the compulsory license created by 17 USC Section 114 of the US Copyright Act (or the equivalent in other jurisdictions).


The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by Licensor are hereby reserved.

4. Restrictions

The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:

  • You may distribute, publicly display, publicly perform, or publicly digitally perform the Work only under the terms of this License, and You must include a copy of, or the Uniform Resource Identifier for, this License with every copy or phonorecord of the Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Work that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Work itself to be made subject to the terms of this License. If You create a Collective Work, upon notice from any Licensor You must, to the extent practicable, remove from the Collective Work any credit as required by clause 4(c), as requested. If You create a Derivative Work, upon notice from any Licensor You must, to the extent practicable, remove from the Derivative Work any credit as required by clause 4(c), as requested.
  • You may distribute, publicly display, publicly perform, or publicly digitally perform a Derivative Work only under the terms of this License, a later version of this License with the same License Elements as this License, or a Creative Commons iCommons license that contains the same License Elements as this License (e.g. Attribution-ShareAlike 2.5 Japan). You must include a copy of, or the Uniform Resource Identifier for, this License or other license specified in the previous sentence with every copy or phonorecord of each Derivative Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Derivative Works that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder, and You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Derivative Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Derivative Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Derivative Work itself to be made subject to the terms of this License.
  • If you distribute, publicly display, publicly perform, or publicly digitally perform the Work or any Derivative Works or Collective Works, You must keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or (ii) if the Original Author and/or Licensor designate another party or parties (e.g. a sponsor institute, publishing entity, journal) for attribution in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; the title of the Work if supplied; to the extent reasonably practicable, the Uniform Resource Identifier, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and in the case of a Derivative Work, a credit identifying the use of the Work in the Derivative Work (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). Such credit may be implemented in any reasonable manner; provided, however, that in the case of a Derivative Work or Collective Work, at a minimum such credit will appear where any other comparable authorship credit appears and in a manner at least as prominent as such other comparable authorship credit.

5. Representations, Warranties and Disclaimer

UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE MATERIALS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.

6. Limitation on Liability.

EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

7. Termination

  • This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Derivative Works or Collective Works from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
  • Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.

8. Miscellaneous

  • Each time You distribute or publicly digitally perform the Work or a Collective Work, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
  • Each time You distribute or publicly digitally perform a Derivative Work, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
  • If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
  • No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
  • This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.