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