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