Remove .a files before running ar, to avoid problems with renamed files remaining...
[kugel-rb.git] / tools / buildzip.pl
blob6e25f79e8e53644df69b1de924f853af5c495d9e
1 #!/usr/bin/perl
2 # __________ __ ___.
3 # Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 # \/ \/ \/ \/ \/
8 # $Id$
11 use strict;
13 use File::Copy; # For move() and copy()
14 use File::Find; # For find()
15 use File::Path; # For rmtree()
16 use Cwd 'abs_path';
17 use Getopt::Long qw(:config pass_through); # pass_through so not
18 # confused by -DTYPE_STUFF
20 sub glob_copy {
21 my ($pattern, $destination) = @_;
22 foreach my $path (glob($pattern)) {
23 copy($path, $destination);
27 sub glob_move {
28 my ($pattern, $destination) = @_;
29 foreach my $path (glob($pattern)) {
30 move($path, $destination);
34 sub glob_unlink {
35 my ($pattern) = @_;
36 foreach my $path (glob($pattern)) {
37 unlink($path);
41 sub find_copyfile {
42 my ($pattern, $destination) = @_;
43 return sub {
44 my $path = $_;
45 if ($path =~ $pattern && filesize($path) > 0 && !($path =~ /\.rockbox/)) {
46 copy($path, $destination);
47 chmod(0755, $destination.'/'.$path);
52 my $ROOT="..";
54 my $ziptool="zip -r9";
55 my $output="rockbox.zip";
56 my $verbose;
57 my $sim;
58 my $exe;
59 my $target;
60 my $archos;
61 my $incfonts;
62 my $target_id; # passed in, not currently used
64 # Get options
65 GetOptions ( 'r|root=s' => \$ROOT,
66 'z|ziptool=s' => \$ziptool,
67 't|target=s' => \$archos, # The target name as used in ARCHOS in the root makefile
68 'i|id=s' => \$target_id, # The target id name as used in TARGET_ID in the root makefile
69 'o|output=s' => \$output,
70 'f|fonts=s' => \$incfonts, # 0 - no fonts, 1 - fonts only 2 - fonts and package
71 'v|verbose' => \$verbose,
72 's|sim' => \$sim );
74 ($target, $exe) = @ARGV;
76 # Some basic sanity
77 die "No firmware found @ $exe" if !-f $exe;
79 my $firmdir="$ROOT/firmware";
80 my $appsdir="$ROOT/apps";
81 my $viewer_bmpdir="$ROOT/apps/plugins/bitmaps/viewer_defaults";
83 my $cppdef = $target;
85 sub gettargetinfo {
86 open(GCC, ">gcctemp");
87 # Get the LCD screen depth and graphical status
88 print GCC <<STOP
89 \#include "config.h"
90 #ifdef HAVE_LCD_BITMAP
91 Bitmap: yes
92 Depth: LCD_DEPTH
93 Icon Width: CONFIG_DEFAULT_ICON_WIDTH
94 Icon Height: CONFIG_DEFAULT_ICON_HEIGHT
95 #endif
96 Codec: CONFIG_CODEC
97 #ifdef HAVE_REMOTE_LCD
98 Remote Depth: LCD_REMOTE_DEPTH
99 Remote Icon Width: CONFIG_REMOTE_DEFAULT_ICON_WIDTH
100 Remote Icon Height: CONFIG_REMOTE_DEFAULT_ICON_HEIGHT
101 #else
102 Remote Depth: 0
103 #endif
104 #ifdef HAVE_RECORDING
105 Recording: yes
106 #endif
107 STOP
109 close(GCC);
111 my $c="cat gcctemp | gcc $cppdef -I. -I$firmdir/export -E -P -";
113 # print STDERR "CMD $c\n";
115 open(TARGET, "$c|");
117 my ($bitmap, $depth, $swcodec, $icon_h, $icon_w);
118 my ($remote_depth, $remote_icon_h, $remote_icon_w);
119 my ($recording);
120 my $icon_count = 1;
121 while(<TARGET>) {
122 # print STDERR "DATA: $_";
123 if($_ =~ /^Bitmap: (.*)/) {
124 $bitmap = $1;
126 elsif($_ =~ /^Depth: (\d*)/) {
127 $depth = $1;
129 elsif($_ =~ /^Icon Width: (\d*)/) {
130 $icon_w = $1;
132 elsif($_ =~ /^Icon Height: (\d*)/) {
133 $icon_h = $1;
135 elsif($_ =~ /^Codec: (\d*)/) {
136 # SWCODEC is 1, the others are HWCODEC
137 $swcodec = ($1 == 1);
139 elsif($_ =~ /^Remote Depth: (\d*)/) {
140 $remote_depth = $1;
142 elsif($_ =~ /^Remote Icon Width: (\d*)/) {
143 $remote_icon_w = $1;
145 elsif($_ =~ /^Remote Icon Height: (\d*)/) {
146 $remote_icon_h = $1;
148 if($_ =~ /^Recording: (.*)/) {
149 $recording = $1;
152 close(TARGET);
153 unlink("gcctemp");
155 return ($bitmap, $depth, $icon_w, $icon_h, $recording,
156 $swcodec, $remote_depth, $remote_icon_w, $remote_icon_h);
159 sub filesize {
160 my ($filename)=@_;
161 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
162 $atime,$mtime,$ctime,$blksize,$blocks)
163 = stat($filename);
164 return $size;
167 sub buildzip {
168 my ($image, $fonts)=@_;
170 my ($bitmap, $depth, $icon_w, $icon_h, $recording, $swcodec,
171 $remote_depth, $remote_icon_w, $remote_icon_h) = &gettargetinfo();
173 # print "Bitmap: $bitmap\nDepth: $depth\nSwcodec: $swcodec\n";
175 # remove old traces
176 rmtree('.rockbox');
178 mkdir ".rockbox", 0777;
180 if(!$bitmap) {
181 # always disable fonts on non-bitmap targets
182 $fonts = 0;
184 if($fonts) {
185 mkdir ".rockbox/fonts", 0777;
186 chdir(".rockbox/fonts");
187 my $cmd = "$ROOT/tools/convbdf -f $ROOT/fonts/*bdf >/dev/null 2>&1";
188 print($cmd."\n") if $verbose;
189 system($cmd);
190 chdir("../../");
192 if($fonts < 2) {
193 # fonts-only package, return
194 return;
198 # create the file so the database does not try indexing a folder
199 open(IGNORE, ">.rockbox/database.ignore") || die "can't open database.ignore";
200 close(IGNORE);
202 mkdir ".rockbox/langs", 0777;
203 mkdir ".rockbox/rocks", 0777;
204 mkdir ".rockbox/rocks/games", 0777;
205 mkdir ".rockbox/rocks/apps", 0777;
206 mkdir ".rockbox/rocks/demos", 0777;
207 mkdir ".rockbox/rocks/viewers", 0777;
209 if ($recording) {
210 mkdir ".rockbox/recpresets", 0777;
213 if($swcodec) {
214 mkdir ".rockbox/eqs", 0777;
216 glob_copy("$ROOT/apps/eqs/*.cfg", '.rockbox/eqs/'); # equalizer presets
219 mkdir ".rockbox/wps", 0777;
220 mkdir ".rockbox/themes", 0777;
221 if ($bitmap) {
222 open(THEME, ">.rockbox/themes/rockbox_default_icons.cfg");
223 print THEME <<STOP
224 # this config file was auto-generated to make it
225 # easy to reset the icons back to default
226 iconset: -
227 # taken from apps/gui/icon.c
228 viewers iconset: /.rockbox/icons/viewers.bmp
229 remote iconset: -
230 # taken from apps/gui/icon.c
231 remote viewers iconset: /.rockbox/icons/remote_viewers.bmp
233 STOP
235 close(THEME);
238 mkdir ".rockbox/codepages", 0777;
240 if($bitmap) {
241 system("$ROOT/tools/codepages");
243 else {
244 system("$ROOT/tools/codepages -m");
247 glob_move('*.cp', '.rockbox/codepages/');
249 if($bitmap) {
250 mkdir ".rockbox/codecs", 0777;
251 if($depth > 1) {
252 mkdir ".rockbox/backdrops", 0777;
255 find(find_copyfile(qr/.*\.codec/, abs_path('.rockbox/codecs/')), 'apps/codecs');
257 # remove directory again if no codec was copied
258 rmdir(".rockbox/codecs");
261 find(find_copyfile(qr/\.(rock|ovl)/, abs_path('.rockbox/rocks/')), 'apps/plugins');
263 open VIEWERS, "$ROOT/apps/plugins/viewers.config" or
264 die "can't open viewers.config";
265 my @viewers = <VIEWERS>;
266 close VIEWERS;
268 open VIEWERS, ">.rockbox/viewers.config" or
269 die "can't create .rockbox/viewers.config";
271 foreach my $line (@viewers) {
272 if ($line =~ /([^,]*),([^,]*),/) {
273 my ($ext, $plugin)=($1, $2);
274 my $r = "${plugin}.rock";
275 my $oname;
277 my $dir = $r;
278 my $name;
280 # strip off the last slash and file name part
281 $dir =~ s/(.*)\/(.*)/$1/;
282 # store the file name part
283 $name = $2;
285 # get .ovl name (file part only)
286 $oname = $name;
287 $oname =~ s/\.rock$/.ovl/;
289 # print STDERR "$ext $plugin $dir $name $r\n";
291 if(-e ".rockbox/rocks/$name") {
292 if($dir ne "rocks") {
293 # target is not 'rocks' but the plugins are always in that
294 # dir at first!
295 move(".rockbox/rocks/$name", ".rockbox/rocks/$r");
297 print VIEWERS $line;
299 elsif(-e ".rockbox/rocks/$r") {
300 # in case the same plugin works for multiple extensions, it
301 # was already moved to the viewers dir
302 print VIEWERS $line;
305 if(-e ".rockbox/rocks/$oname") {
306 # if there's an "overlay" file for the .rock, move that as
307 # well
308 move(".rockbox/rocks/$oname", ".rockbox/rocks/$dir");
312 close VIEWERS;
314 open CATEGORIES, "$ROOT/apps/plugins/CATEGORIES" or
315 die "can't open CATEGORIES";
316 my @rock_targetdirs = <CATEGORIES>;
317 close CATEGORIES;
318 foreach my $line (@rock_targetdirs) {
319 if ($line =~ /([^,]*),(.*)/) {
320 my ($plugin, $dir)=($1, $2);
321 move(".rockbox/rocks/${plugin}.rock", ".rockbox/rocks/$dir/${plugin}.rock");
325 if ($bitmap) {
326 mkdir ".rockbox/icons", 0777;
327 copy("$viewer_bmpdir/viewers.${icon_w}x${icon_h}x$depth.bmp", ".rockbox/icons/viewers.bmp");
328 if ($remote_depth) {
329 copy("$viewer_bmpdir/remote_viewers.${remote_icon_w}x${remote_icon_h}x$remote_depth.bmp", ".rockbox/icons/remote_viewers.bmp");
333 copy("$ROOT/apps/tagnavi.config", ".rockbox/");
334 copy("$ROOT/apps/plugins/disktidy.config", ".rockbox/rocks/apps/");
336 if($bitmap) {
337 copy("$ROOT/apps/plugins/sokoban.levels", ".rockbox/rocks/games/sokoban.levels"); # sokoban levels
338 copy("$ROOT/apps/plugins/snake2.levels", ".rockbox/rocks/games/snake2.levels"); # snake2 levels
341 if($image) {
342 # image is blank when this is a simulator
343 if( filesize("rockbox.ucl") > 1000 ) {
344 copy("rockbox.ucl", ".rockbox/rockbox.ucl"); # UCL for flashing
346 if( filesize("rombox.ucl") > 1000) {
347 copy("rombox.ucl", ".rockbox/rombox.ucl"); # UCL for flashing
350 # Check for rombox.target
351 if ($image=~/(.*)\.(\w+)$/)
353 my $romfile = "rombox.$2";
354 if (filesize($romfile) > 1000)
356 copy($romfile, ".rockbox/$romfile");
361 mkdir ".rockbox/docs", 0777;
362 for(("COPYING",
363 "LICENSES",
364 "KNOWN_ISSUES"
365 )) {
366 copy("$ROOT/docs/$_", ".rockbox/docs/$_.txt");
368 if ($fonts) {
369 copy("$ROOT/docs/profontdoc.txt", ".rockbox/docs/profontdoc.txt");
371 for(("sample.colours",
372 "sample.icons"
373 )) {
374 copy("$ROOT/docs/$_", ".rockbox/docs/$_");
377 # Now do the WPS dance
378 if(-d "$ROOT/wps") {
379 system("perl $ROOT/wps/wpsbuild.pl -r $ROOT $ROOT/wps/WPSLIST $target");
381 else {
382 print STDERR "No wps module present, can't do the WPS magic!\n";
385 # and the info file
386 copy("rockbox-info.txt", ".rockbox/rockbox-info.txt");
388 # copy the already built lng files
389 glob_copy('apps/lang/*lng', '.rockbox/langs/');
393 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
394 localtime(time);
396 $mon+=1;
397 $year+=1900;
399 #$date=sprintf("%04d%02d%02d", $year,$mon, $mday);
400 #$shortdate=sprintf("%02d%02d%02d", $year%100,$mon, $mday);
402 # made once for all targets
403 sub runone {
404 my ($target, $fonts)=@_;
406 # build a full install .rockbox directory
407 buildzip($target, $fonts);
409 unlink($output);
411 if($fonts == 1) {
412 # Don't include image file in fonts-only package
413 undef $target;
415 if($target && ($target !~ /(mod|ajz|wma)\z/i)) {
416 # On some targets, the image goes into .rockbox.
417 copy("$target", ".rockbox/$target");
418 undef $target;
421 if($verbose) {
422 print "$ziptool $output .rockbox $target >/dev/null\n";
425 if($sim) {
426 system("cp -r .rockbox archos/ >/dev/null");
428 else {
429 system("$ziptool $output .rockbox $target >/dev/null");
432 # remove the .rockbox afterwards
433 rmtree('.rockbox');
436 if(!$exe) {
437 # not specified, guess!
438 if($target =~ /(recorder|ondio)/i) {
439 $exe = "ajbrec.ajz";
441 elsif($target =~ /iriver/i) {
442 $exe = "rockbox.iriver";
444 else {
445 $exe = "archos.mod";
448 elsif($exe =~ /rockboxui/) {
449 # simulator, exclude the exe file
450 $exe = "";
453 runone($exe, $incfonts);