Add FEATURE ramdisk to be able to select the use of INITRAMFS for a sub-target
[openwrt.git] / scripts / metadata.pl
1 #!/usr/bin/env perl
2 use FindBin;
3 use lib "$FindBin::Bin";
4 use strict;
5 use metadata;
6
7 my %board;
8
9 sub confstr($) {
10         my $conf = shift;
11         $conf =~ tr#/\.\-/#___#;
12         return $conf;
13 }
14
15 sub parse_target_metadata() {
16         my $file = shift @ARGV;
17         my ($target, @target, $profile);
18         my %target;
19
20         open FILE, "<$file" or do {
21                 warn "Can't open file '$file': $!\n";
22                 return;
23         };
24         while (<FILE>) {
25                 chomp;
26                 /^Target:\s*(.+)\s*$/ and do {
27                         my $name = $1;
28                         $target = {
29                                 id => $name,
30                                 board => $name,
31                                 boardconf => confstr($name),
32                                 conf => confstr($name),
33                                 profiles => [],
34                                 features => [],
35                                 depends => [],
36                                 subtargets => []
37                         };
38                         push @target, $target;
39                         $target{$name} = $target;
40                         if ($name =~ /([^\/]+)\/([^\/]+)/) {
41                                 push @{$target{$1}->{subtargets}}, $2;
42                                 $target->{board} = $1;
43                                 $target->{boardconf} = confstr($1);
44                                 $target->{subtarget} = 1;
45                                 $target->{parent} = $target{$1};
46                         }
47                 };
48                 /^Target-Kernel:\s*(\d+\.\d+)\s*$/ and $target->{kernel} = $1;
49                 /^Target-Name:\s*(.+)\s*$/ and $target->{name} = $1;
50                 /^Target-Path:\s*(.+)\s*$/ and $target->{path} = $1;
51                 /^Target-Arch:\s*(.+)\s*$/ and $target->{arch} = $1;
52                 /^Target-Features:\s*(.+)\s*$/ and $target->{features} = [ split(/\s+/, $1) ];
53                 /^Target-Depends:\s*(.+)\s*$/ and $target->{depends} = [ split(/\s+/, $1) ];
54                 /^Target-Description:/ and $target->{desc} = get_multiline(*FILE);
55                 /^Target-Optimization:\s*(.+)\s*$/ and $target->{cflags} = $1;
56                 /^Linux-Version:\s*(.+)\s*$/ and $target->{version} = $1;
57                 /^Linux-Release:\s*(.+)\s*$/ and $target->{release} = $1;
58                 /^Linux-Kernel-Arch:\s*(.+)\s*$/ and $target->{karch} = $1;
59                 /^Default-Packages:\s*(.+)\s*$/ and $target->{packages} = [ split(/\s+/, $1) ];
60                 /^Target-Profile:\s*(.+)\s*$/ and do {
61                         $profile = {
62                                 id => $1,
63                                 name => $1,
64                                 packages => []
65                         };
66                         push @{$target->{profiles}}, $profile;
67                 };
68                 /^Target-Profile-Name:\s*(.+)\s*$/ and $profile->{name} = $1;
69                 /^Target-Profile-Packages:\s*(.*)\s*$/ and $profile->{packages} = [ split(/\s+/, $1) ];
70                 /^Target-Profile-Description:\s*(.*)\s*/ and $profile->{desc} = get_multiline(*FILE);
71                 /^Target-Profile-Config:/ and $profile->{config} = get_multiline(*FILE, "\t");
72                 /^Target-Profile-Kconfig:/ and $profile->{kconfig} = 1;
73         }
74         close FILE;
75         foreach my $target (@target) {
76                 next if @{$target->{subtargets}} > 0;
77                 @{$target->{profiles}} > 0 or $target->{profiles} = [
78                         {
79                                 id => 'Default',
80                                 name => 'Default',
81                                 packages => []
82                         }
83                 ];
84         }
85         return @target;
86 }
87
88 sub gen_kconfig_overrides() {
89         my %config;
90         my %kconfig;
91         my $package;
92         my $pkginfo = shift @ARGV;
93         my $cfgfile = shift @ARGV;
94
95         # parameter 2: build system config
96         open FILE, "<$cfgfile" or return;
97         while (<FILE>) {
98                 /^(CONFIG_.+?)=(.+)$/ and $config{$1} = 1;
99         }
100         close FILE;
101
102         # parameter 1: package metadata
103         open FILE, "<$pkginfo" or return;
104         while (<FILE>) {
105                 /^Package:\s*(.+?)\s*$/ and $package = $1;
106                 /^Kernel-Config:\s*(.+?)\s*$/ and do {
107                         my @config = split /\s+/, $1;
108                         foreach my $config (@config) {
109                                 my $val = 'm';
110                                 my $override;
111                                 if ($config =~ /^(.+?)=(.+)$/) {
112                                         $config = $1;
113                                         $override = 1;
114                                         $val = $2;
115                                 }
116                                 if ($config{"CONFIG_PACKAGE_$package"} and ($config ne 'n')) {
117                                         $kconfig{$config} = $val;
118                                 } elsif (!$override) {
119                                         $kconfig{$config} or $kconfig{$config} = 'n';
120                                 }
121                         }
122                 };
123         };
124         close FILE;
125
126         foreach my $kconfig (sort keys %kconfig) {
127                 if ($kconfig{$kconfig} eq 'n') {
128                         print "# $kconfig is not set\n";
129                 } else {
130                         print "$kconfig=$kconfig{$kconfig}\n";
131                 }
132         }
133 }
134
135 sub merge_package_lists($$) {
136         my $list1 = shift;
137         my $list2 = shift;
138         my @l = ();
139         my %pkgs;
140
141         foreach my $pkg (@$list1, @$list2) {
142                 $pkgs{$pkg} = 1;
143         }
144         foreach my $pkg (keys %pkgs) {
145                 push @l, $pkg unless ($pkg =~ /^-/ or $pkgs{"-$pkg"});
146         }
147         return sort(@l);
148 }
149
150 sub target_config_features(@) {
151         my $ret;
152
153         while ($_ = shift @_) {
154                 /broken/ and $ret .= "\tdepends BROKEN\n";
155                 /display/ and $ret .= "\tselect DISPLAY_SUPPORT\n";
156                 /gpio/ and $ret .= "\tselect GPIO_SUPPORT\n";
157                 /pci/ and $ret .= "\tselect PCI_SUPPORT\n";
158                 /usb/ and $ret .= "\tselect USB_SUPPORT\n";
159                 /pcmcia/ and $ret .= "\tselect PCMCIA_SUPPORT\n";
160                 /squashfs/ and $ret .= "\tselect USES_SQUASHFS\n";
161                 /jffs2/ and $ret .= "\tselect USES_JFFS2\n";
162                 /ext2/ and $ret .= "\tselect USES_EXT2\n";
163                 /tgz/ and $ret .= "\tselect USES_TGZ\n";
164                 /cpiogz/ and $ret .= "\tselect USES_CPIOGZ\n";
165                 /fpu/ and $ret .= "\tselect HAS_FPU\n";
166                 /ramdisk/ and $ret .= "\tselect USES_INITRAMFS\n";
167         }
168         return $ret;
169 }
170
171 sub target_name($) {
172         my $target = shift;
173         my $parent = $target->{parent};
174         if ($parent) {
175                 return $target->{parent}->{name}." - ".$target->{name};
176         } else {
177                 return $target->{name};
178         }
179 }
180
181 sub kver($) {
182         my $v = shift;
183         $v =~ tr/\./_/;
184         $v =~ /(\d+_\d+_\d+)(_\d+)?/ and $v = $1;
185         return $v;
186 }
187
188 sub print_target($) {
189         my $target = shift;
190         my $features = target_config_features(@{$target->{features}});
191         my $help = $target->{desc};
192         my $kernel = $target->{kernel};
193         my $confstr;
194         $kernel =~ tr/./_/;
195
196         chomp $features;
197         $features .= "\n";
198         if ($help =~ /\w+/) {
199                 $help =~ s/^\s*/\t  /mg;
200                 $help = "\thelp\n$help";
201         } else {
202                 undef $help;
203         }
204
205         my $v = kver($target->{version});
206         if (@{$target->{subtargets}} == 0) {
207         $confstr = <<EOF;
208 config TARGET_$target->{conf}
209         bool "$target->{name}"
210         select LINUX_$kernel
211         select LINUX_$v
212 EOF
213         }
214         else {
215                 $confstr = <<EOF;
216 config TARGET_$target->{conf}
217         bool "$target->{name}"
218 EOF
219         }
220         if ($target->{subtarget}) {
221                 $confstr .= "\tdepends TARGET_$target->{boardconf}\n";
222         }
223         if (@{$target->{subtargets}} > 0) {
224                 $confstr .= "\tselect HAS_SUBTARGETS\n";
225         } else {
226                 $confstr .= "\tselect $target->{arch}\n";
227                 foreach my $dep (@{$target->{depends}}) {
228                         my $mode = "depends";
229                         my $flags;
230                         my $name;
231
232                         $dep =~ /^([@\+\-]+)(.+)$/;
233                         $flags = $1;
234                         $name = $2;
235
236                         next if $name =~ /:/;
237                         $flags =~ /-/ and $mode = "deselect";
238                         $flags =~ /\+/ and $mode = "select";
239                         $flags =~ /@/ and $confstr .= "\t$mode $name\n";
240                 }
241                 $confstr .= $features;
242         }
243
244         $confstr .= "$help\n\n";
245         print $confstr;
246 }
247
248 sub gen_target_config() {
249         my @target = parse_target_metadata();
250         my %defaults;
251
252         my @target_sort = sort {
253                 target_name($a) cmp target_name($b);
254         } @target;
255
256
257         print <<EOF;
258 choice
259         prompt "Target System"
260         default TARGET_brcm_2_4
261         reset if !DEVEL
262         
263 EOF
264
265         foreach my $target (@target_sort) {
266                 next if $target->{subtarget};
267                 print_target($target);
268         }
269
270         print <<EOF;
271 endchoice
272
273 choice
274         prompt "Subtarget" if HAS_SUBTARGETS
275
276 EOF
277         foreach my $target (@target) {
278                 next unless $target->{subtarget};
279                 print_target($target);
280         }
281
282 print <<EOF;
283 endchoice
284
285 choice
286         prompt "Target Profile"
287
288 EOF
289
290         foreach my $target (@target) {
291                 my $profiles = $target->{profiles};
292
293                 foreach my $profile (@$profiles) {
294                         print <<EOF;
295 config TARGET_$target->{conf}_$profile->{id}
296         bool "$profile->{name}"
297         depends TARGET_$target->{conf}
298 $profile->{config}
299 EOF
300                         $profile->{kconfig} and print "\tselect PROFILE_KCONFIG\n";
301                         my @pkglist = merge_package_lists($target->{packages}, $profile->{packages});
302                         foreach my $pkg (@pkglist) {
303                                 print "\tselect DEFAULT_$pkg\n";
304                                 $defaults{$pkg} = 1;
305                         }
306                         my $help = $profile->{desc};
307                         if ($help =~ /\w+/) {
308                                 $help =~ s/^\s*/\t  /mg;
309                                 $help = "\thelp\n$help";
310                         } else {
311                                 undef $help;
312                         }
313                         print "$help\n";
314                 }
315         }
316
317         print <<EOF;
318 endchoice
319
320 config HAS_SUBTARGETS
321         bool
322
323 config TARGET_BOARD
324         string
325
326 EOF
327         foreach my $target (@target) {
328                 $target->{subtarget} or print "\t\tdefault \"".$target->{board}."\" if TARGET_".$target->{conf}."\n";
329         }
330         print <<EOF;
331
332 config DEFAULT_TARGET_OPTIMIZATION
333         string
334 EOF
335         foreach my $target (@target) {
336                 next if @{$target->{subtargets}} > 0;
337                 print "\tdefault \"".$target->{cflags}."\" if TARGET_".$target->{conf}."\n";
338         }
339         print "\tdefault \"-Os -pipe -funit-at-a-time\"\n";
340
341         my %kver;
342         foreach my $target (@target) {
343                 my $v = kver($target->{version});
344                 next if $kver{$v};
345                 $kver{$v} = 1;
346                 print <<EOF;
347
348 config LINUX_$v
349         bool
350
351 EOF
352         }
353         foreach my $def (sort keys %defaults) {
354                 print "\tconfig DEFAULT_".$def."\n";
355                 print "\t\tbool\n\n";
356         }
357 }
358
359 my %dep_check;
360 sub __find_package_dep($$) {
361         my $pkg = shift;
362         my $name = shift;
363         my $deps = ($pkg->{vdepends} or $pkg->{depends});
364
365         return 0 unless defined $deps;
366         foreach my $dep (@{$deps}) {
367                 next if $dep_check{$dep};
368                 $dep_check{$dep} = 1;
369                 return 1 if $dep eq $name;
370                 return 1 if ($package{$dep} and (__find_package_dep($package{$dep},$name) == 1));
371         }
372         return 0;
373 }
374
375 # wrapper to avoid infinite recursion
376 sub find_package_dep($$) {
377         my $pkg = shift;
378         my $name = shift;
379
380         %dep_check = ();
381         return __find_package_dep($pkg, $name);
382 }
383
384 sub package_depends($$) {
385         my $a = shift;
386         my $b = shift;
387         my $ret;
388
389         return 0 if ($a->{submenu} ne $b->{submenu});
390         if (find_package_dep($a, $b->{name}) == 1) {
391                 $ret = 1;
392         } elsif (find_package_dep($b, $a->{name}) == 1) {
393                 $ret = -1;
394         } else {
395                 return 0;
396         }
397         return $ret;
398 }
399
400 sub mconf_depends {
401         my $pkgname = shift;
402         my $depends = shift;
403         my $only_dep = shift;
404         my $res;
405         my $dep = shift;
406         my $seen = shift;
407         my $parent_condition = shift;
408         $dep or $dep = {};
409         $seen or $seen = {};
410
411         $depends or return;
412         my @depends = @$depends;
413         foreach my $depend (@depends) {
414                 my $m = "depends";
415                 $depend =~ s/^([@\+]+)//;
416                 my $flags = $1;
417                 my $vdep;
418                 my $condition;
419
420                 if ($depend =~ /^(.+):(.+)$/) {
421                         if ($1 ne "PACKAGE_$pkgname") {
422                                 if ($parent_condition) {
423                                         $condition = "$parent_condition && $1";
424                                 } else {
425                                         $condition = $1;
426                                 }
427                         }
428                         $depend = $2;
429                 }
430                 next if $seen->{$depend};
431                 next if $package{$depend} and $package{$depend}->{buildonly};
432                 $seen->{$depend} = 1;
433                 if ($vdep = $package{$depend}->{vdepends}) {
434                         $depend = join("||", map { "PACKAGE_".$_ } @$vdep);
435                 } else {
436                         $flags =~ /\+/ and do {
437                                 # Menuconfig will not treat 'select FOO' as a real dependency
438                                 # thus if FOO depends on other config options, these dependencies
439                                 # will not be checked. To fix this, we simply emit all of FOO's
440                                 # depends here as well.
441                                 $package{$depend} and mconf_depends($pkgname, $package{$depend}->{depends}, 1, $dep, $seen, $condition);
442
443                                 $m = "select";
444                                 next if $only_dep;
445                         };
446                         $flags =~ /@/ or $depend = "PACKAGE_$depend";
447                         if ($condition) {
448                                 if ($m =~ /select/) {
449                                         $depend = "$depend if $condition";
450                                 } else {
451                                         $depend = "!($condition) || $depend";
452                                 }
453                         }
454                 }
455                 $dep->{$depend} =~ /select/ or $dep->{$depend} = $m;
456         }
457         foreach my $depend (keys %$dep) {
458                 my $m = $dep->{$depend};
459                 $res .= "\t\t$m $depend\n";
460         }
461         return $res;
462 }
463
464 sub print_package_config_category($) {
465         my $cat = shift;
466         my %menus;
467         my %menu_dep;
468
469         return unless $category{$cat};
470
471         print "menu \"$cat\"\n\n";
472         my %spkg = %{$category{$cat}};
473
474         foreach my $spkg (sort {uc($a) cmp uc($b)} keys %spkg) {
475                 foreach my $pkg (@{$spkg{$spkg}}) {
476                         next if $pkg->{buildonly};
477                         my $menu = $pkg->{submenu};
478                         if ($menu) {
479                                 $menu_dep{$menu} or $menu_dep{$menu} = $pkg->{submenudep};
480                         } else {
481                                 $menu = 'undef';
482                         }
483                         $menus{$menu} or $menus{$menu} = [];
484                         push @{$menus{$menu}}, $pkg;
485                 }
486         }
487         my @menus = sort {
488                 ($a eq 'undef' ?  1 : 0) or
489                 ($b eq 'undef' ? -1 : 0) or
490                 ($a cmp $b)
491         } keys %menus;
492
493         foreach my $menu (@menus) {
494                 my @pkgs = sort {
495                         package_depends($a, $b) or
496                         ($a->{name} cmp $b->{name})
497                 } @{$menus{$menu}};
498                 if ($menu ne 'undef') {
499                         $menu_dep{$menu} and print "if $menu_dep{$menu}\n";
500                         print "menu \"$menu\"\n";
501                 }
502                 foreach my $pkg (@pkgs) {
503                         my $title = $pkg->{name};
504                         my $c = (72 - length($pkg->{name}) - length($pkg->{title}));
505                         if ($c > 0) {
506                                 $title .= ("." x $c). " ". $pkg->{title};
507                         }
508                         print "\t";
509                         $pkg->{menu} and print "menu";
510                         print "config PACKAGE_".$pkg->{name}."\n";
511                         print "\t\t".($pkg->{tristate} ? 'tristate' : 'bool')." \"$title\"\n";
512                         print "\t\tdefault y if DEFAULT_".$pkg->{name}."\n";
513                         foreach my $default (split /\s*,\s*/, $pkg->{default}) {
514                                 print "\t\tdefault $default\n";
515                         }
516                         print mconf_depends($pkg->{name}, $pkg->{depends}, 0);
517                         print "\t\thelp\n";
518                         print $pkg->{description};
519                         print "\n";
520
521                         $pkg->{config} and print $pkg->{config}."\n";
522                 }
523                 if ($menu ne 'undef') {
524                         print "endmenu\n";
525                         $menu_dep{$menu} and print "endif\n";
526                 }
527         }
528         print "endmenu\n\n";
529
530         undef $category{$cat};
531 }
532
533 sub gen_package_config() {
534         parse_package_metadata($ARGV[0]) or exit 1;
535         print "menuconfig UCI_PRECONFIG\n\tbool \"Image configuration\"\n" if %preconfig;
536         foreach my $preconfig (keys %preconfig) {
537                 foreach my $cfg (keys %{$preconfig{$preconfig}}) {
538                         my $conf = $preconfig{$preconfig}->{$cfg}->{id};
539                         $conf =~ tr/\.-/__/;
540                         print <<EOF
541         config UCI_PRECONFIG_$conf
542                 string "$preconfig{$preconfig}->{$cfg}->{label}" if UCI_PRECONFIG
543                 depends PACKAGE_$preconfig
544                 default "$preconfig{$preconfig}->{$cfg}->{default}"
545
546 EOF
547                 }
548         }
549         print_package_config_category 'Base system';
550         foreach my $cat (keys %category) {
551                 print_package_config_category $cat;
552         }
553 }
554
555 sub get_conditional_dep($$) {
556         my $condition = shift;
557         my $depstr = shift;
558         if ($condition) {
559                 if ($condition =~ /^!(.+)/) {
560                         return "\$(if \$(CONFIG_$1),,$depstr)";
561                 } else {
562                         return "\$(if \$(CONFIG_$condition),$depstr)";
563                 }
564         } else {
565                 return $depstr;
566         }
567 }
568
569 sub gen_package_mk() {
570         my %conf;
571         my %dep;
572         my %done;
573         my $line;
574
575         parse_package_metadata($ARGV[0]) or exit 1;
576         foreach my $name (sort {uc($a) cmp uc($b)} keys %package) {
577                 my $config;
578                 my $pkg = $package{$name};
579                 my @srcdeps;
580
581                 next if defined $pkg->{vdepends};
582
583                 if ($ENV{SDK}) {
584                         $conf{$pkg->{src}} or do {
585                                 $config = 'm';
586                                 $conf{$pkg->{src}} = 1;
587                         };
588                 } else {
589                         $config = "\$(CONFIG_PACKAGE_$name)"
590                 }
591                 if ($config) {
592                         $pkg->{buildonly} and $config = "";
593                         print "package-$config += $pkg->{subdir}$pkg->{src}\n";
594                         $pkg->{prereq} and print "prereq-$config += $pkg->{subdir}$pkg->{src}\n";
595                 }
596
597                 next if $done{$pkg->{src}};
598                 $done{$pkg->{src}} = 1;
599
600                 if (@{$pkg->{buildtypes}} > 0) {
601                         print "buildtypes-$pkg->{subdir}$pkg->{src} = ".join(' ', @{$pkg->{buildtypes}})."\n";
602                 }
603
604                 foreach my $spkg (@{$srcpackage{$pkg->{src}}}) {
605                         foreach my $dep (@{$spkg->{depends}}, @{$spkg->{builddepends}}) {
606                                 $dep =~ /@/ or do {
607                                         $dep =~ s/\+//g;
608                                         push @srcdeps, $dep;
609                                 };
610                         }
611                 }
612                 foreach my $type (@{$pkg->{buildtypes}}) {
613                         my @extra_deps;
614                         my %deplines;
615
616                         next unless $pkg->{"builddepends/$type"};
617                         foreach my $dep (@{$pkg->{"builddepends/$type"}}) {
618                                 my $suffix = "";
619                                 my $condition;
620
621                                 if ($dep =~ /^(.+):(.+)/) {
622                                         $condition = $1;
623                                         $dep = $2;
624                                 }
625                                 if ($dep =~ /^(.+)(\/.+)/) {
626                                         $dep = $1;
627                                         $suffix = $2;
628                                 }
629                                 my $pkg_dep = $package{$dep};
630                                 next unless $pkg_dep;
631
632                                 my $idx = "";
633                                 if (defined $pkg_dep->{src}) {
634                                         $idx = $pkg_dep->{subdir}.$pkg_dep->{src};
635                                 } elsif (defined($srcpackage{$dep})) {
636                                         $idx = $subdir{$dep}.$dep;
637                                 }
638                                 my $depstr = "\$(curdir)/$idx$suffix/compile";
639                                 my $depline = get_conditional_dep($condition, $depstr);
640                                 if ($depline) {
641                                         $deplines{$dep} = $depline;
642                                 }
643                         }
644                         my $depline = join(" ", values %deplines);
645                         if ($depline) {
646                                 $line .= "\$(curdir)/".$pkg->{subdir}."$pkg->{src}/$type/compile += $depline\n";
647                         }
648                 }
649
650                 my $hasdeps = 0;
651                 my %deplines;
652                 foreach my $deps (@srcdeps) {
653                         my $idx;
654                         my $condition;
655                         my $prefix = "";
656                         my $suffix = "";
657
658                         if ($deps =~ /^(.+):(.+)/) {
659                                 $condition = $1;
660                                 $deps = $2;
661                         }
662                         if ($deps =~ /^(.+)(\/.+)/) {
663                                 $deps = $1;
664                                 $suffix = $2;
665                         }
666
667                         my $pkg_dep = $package{$deps};
668                         my @deps;
669
670                         if ($pkg_dep->{vdepends}) {
671                                 @deps = @{$pkg_dep->{vdepends}};
672                         } else {
673                                 @deps = ($deps);
674                         }
675
676                         foreach my $dep (@deps) {
677                                 $pkg_dep = $package{$deps};
678                                 if (defined $pkg_dep->{src}) {
679                                         ($pkg->{src} ne $pkg_dep->{src}) and $idx = $pkg_dep->{subdir}.$pkg_dep->{src};
680                                 } elsif (defined($srcpackage{$dep})) {
681                                         $idx = $subdir{$dep}.$dep;
682                                 }
683                                 undef $idx if $idx =~ /^(kernel)|(base-files)$/;
684                                 if ($idx) {
685                                         my $depline;
686                                         next if $pkg->{src} eq $pkg_dep->{src};
687                                         next if $dep{$pkg->{src}."->".$idx};
688                                         next if $dep{$pkg->{src}."->($dep)".$idx} and $pkg_dep->{vdepends};
689                                         my $depstr;
690
691                                         if ($pkg_dep->{vdepends}) {
692                                                 $depstr = "\$(if \$(CONFIG_PACKAGE_$dep),\$(curdir)/$idx$suffix/compile)";
693                                                 $dep{$pkg->{src}."->($dep)".$idx} = 1;
694                                         } else {
695                                                 $depstr = "\$(curdir)/$idx$suffix/compile";
696                                                 $dep{$pkg->{src}."->".$idx} = 1;
697                                         }
698                                         $depline = get_conditional_dep($condition, $depstr);
699                                         if ($depline) {
700                                                 $deplines{$idx.$dep} = $depline;
701                                         }
702                                 }
703                         }
704                 }
705                 my $depline = join(" ", values %deplines);
706                 if ($depline) {
707                         $line .= "\$(curdir)/".$pkg->{subdir}."$pkg->{src}/compile += $depline\n";
708                 }
709         }
710
711         if ($line ne "") {
712                 print "\n$line";
713         }
714         foreach my $preconfig (keys %preconfig) {
715                 my $cmds;
716                 foreach my $cfg (keys %{$preconfig{$preconfig}}) {
717                         my $conf = $preconfig{$preconfig}->{$cfg}->{id};
718                         $conf =~ tr/\.-/__/;
719                         $cmds .= "\techo \"uci set '$preconfig{$preconfig}->{$cfg}->{id}=\$(subst \",,\$(CONFIG_UCI_PRECONFIG_$conf))'\"; \\\n";
720                 }
721                 next unless $cmds;
722                 print <<EOF
723
724 \$(TARGET_DIR)/etc/uci-defaults/$preconfig: FORCE
725         ( \\
726 $cmds \\
727         ) > \$@
728         
729 ifneq (\$(UCI_PRECONFIG)\$(CONFIG_UCI_PRECONFIG),)
730   package/preconfig: \$(TARGET_DIR)/etc/uci-defaults/$preconfig
731 endif
732 EOF
733         }
734 }
735
736 sub gen_package_source() {
737         parse_package_metadata($ARGV[0]) or exit 1;
738         foreach my $name (sort {uc($a) cmp uc($b)} keys %package) {
739                 my $pkg = $package{$name};
740                 if ($pkg->{name} && $pkg->{source}) {
741                         print "$pkg->{name}: ";
742                         print "$pkg->{source}\n";
743                 }
744         }
745 }
746
747 sub parse_command() {
748         my $cmd = shift @ARGV;
749         for ($cmd) {
750                 /^target_config$/ and return gen_target_config();
751                 /^package_mk$/ and return gen_package_mk();
752                 /^package_config$/ and return gen_package_config();
753                 /^kconfig/ and return gen_kconfig_overrides();
754                 /^package_source$/ and return gen_package_source();
755         }
756         print <<EOF
757 Available Commands:
758         $0 target_config [file]         Target metadata in Kconfig format
759         $0 package_mk [file]            Package metadata in makefile format
760         $0 package_config [file]        Package metadata in Kconfig format
761         $0 kconfig [file] [config]      Kernel config overrides
762         $0 package_source [file]        Package source file information
763
764 EOF
765 }
766
767 parse_command();