diff --git a/tools/release/bins.pl b/tools/release/bins.pl
index bb4aa68..caea7a4 100755
--- a/tools/release/bins.pl
+++ b/tools/release/bins.pl
@@ -1,28 +1,64 @@
#!/usr/bin/perl

$version="3.0";
+use Cwd;
+use Getopt::Long;
+
+my $cwd = &Cwd::cwd();
+my $verbose = '';
+my $update = '';
+my $srcroot = '';
+my $buildroot = '';
+my $outdir = 'output';
+
+GetOptions('v|verbose' => \$verbose,
+ 'u|update' => \$update,
+ 's|srcroot=s' => \$srcroot,
+ 'b|buildroot=s' => \$buildroot,
+ 'o|outdir=s' => \$outdir
+ );
+
+if($srcroot !~ /^\//)
+{
+ if ($srcroot)
+ {
+ $srcroot = "$cwd/$srcroot";
+ } else {
+ $srcroot = $cwd;
+ }
+}

-my $verbose;
-if($ARGV[0] eq "-v") {
- $verbose =1;
- shift @ARGV;
+if($buildroot !~ /^\//)
+{
+ if ($buildroot)
+ {
+ $buildroot = "$cwd/$buildroot";
+ } else {
+ $buildroot = $cwd;
+ }
}

-my $update;
-if($ARGV[0] eq "-u") {
- $update =1;
- shift @ARGV;
+if($outdir !~ /^\//)
+{
+ if ($outdir)
+ {
+ $outdir = "$cwd/$outdir";
+ } else {
+ $outdir = $cwd;
+ }
}

-my $doonly;
-if($ARGV[0]) {
- $doonly = $ARGV[0];
- print "only build $doonly\n" if($verbose);
+if(@ARGV) {
+ foreach (@ARGV)
+ {
+ print "including target $_\n";
+ $targets{$_} = 1;
+ }
}

if($update) {
# svn update!
- system("svn -q up");
+ system(("svn", "-q", "up"));
}

$rev = `svnversion`;
@@ -34,29 +70,27 @@ sub runone {
my ($dir, $confnum, $extra)=@_;
my $a;

- if($doonly && ($doonly ne $dir)) {
+ if(%targets && !$targets{$dir}) {
return;
}

- mkdir "build-$dir";
- chdir "build-$dir";
- print "Build in build-$dir\n" if($verbose);
+ system(("mkdir", "-p", "$buildroot/build-$dir"));
+ chdir "$buildroot/build-$dir";
+ print "Build in $buildroot/build-$dir\n" if($verbose);

# build the manual(s)
$a = buildit($dir, $confnum, $extra);

- chdir "..";
-
- my $o="build-$dir/rockbox.zip";
+ my $o="$buildroot/build-$dir/rockbox.zip";
if (-f $o) {
- my $newo="output/rockbox-$dir-$version.zip";
- system("mkdir -p output");
- system("mv $o $newo");
+ my $newo="$outdir/rockbox-$dir-$version.zip";
+ system(("mkdir", "-p", "$outdir"));
+ system(("mv", "$o", "$newo"));
print "moved $o to $newo\n" if($verbose);
}

- print "remove all contents in build-$dir\n" if($verbose);
- system("rm -rf build-$dir");
+ print "remove all contents in $buildroot/build-$dir\n" if($verbose);
+ system(("rm", "-rf", "$buildroot/build-$dir"));

return $a;
};
@@ -69,24 +103,22 @@ sub fonts {
return;
}

- mkdir "build-$dir";
- chdir "build-$dir";
- print "Build fonts in build-$dir\n" if($verbose);
+ system(("mkdir", "-p", "$buildroot/build-$dir"));
+ chdir "$buildroot/build-$dir";
+ print "Build fonts in $buildroot/build-$dir\n" if($verbose);

# build the manual(s)
$a = buildfonts($dir, $confnum, $newl);

- chdir "..";
-
- my $o="build-$dir/rockbox-fonts.zip";
+ my $o="$buildroot/build-$dir/rockbox-fonts.zip";
if (-f $o) {
- my $newo="output/rockbox-fonts-$version.zip";
- system("mv $o $newo");
+ my $newo="$outdir/rockbox-fonts-$version.zip";
+ system(("mv", "$o", "$newo"));
print "moved $o to $newo\n" if($verbose);
}

- print "remove all contents in build-$dir\n" if($verbose);
- system("rm -rf build-$dir");
+ print "remove all contents in $buildroot/build-$dir\n" if($verbose);
+ system(("rm", "-rf", "$buildroot/build-$dir"));

return $a;
};
@@ -98,14 +130,14 @@ sub buildit {

`rm -rf * >/dev/null 2>&1`;

- my $c = sprintf('echo -e "%s\n%sn\n" | ../tools/configure',
- $confnum, $extra);
+ my $c = sprintf('echo -e "%s\n%sn\n" | %s/tools/configure',
+ $confnum, $extra, $srcroot);

print "C: $c\n" if($verbose);
`$c`;

print "Run 'make'\n" if($verbose);
- `make -j 2>/dev/null`;
+ `make -j 2>&1 1>/dev/null | egrep 'warning|error'`;

print "Run 'make zip'\n" if($verbose);
`make zip 2>/dev/null`;
@@ -119,8 +151,8 @@ sub buildfonts {

`rm -rf * >/dev/null 2>&1`;

- my $c = sprintf("printf '%s\n%sn\n' | ../tools/configure",
- $confnum, $newl?'\n':'');
+ my $c = sprintf('echo -e "%s\n%sn\n" | %s/tools/configure',
+ $confnum, $newl?'\n':'', $srcroot);

print "C: $c\n" if($verbose);
`$c`;