Root/scripts/metadata.pl

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

Archive Download this file



interactive