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