mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-24 03:50:37 +02:00
df68e5dff3
thus if BAR depends on FOO and FOO depends on other config options, these dependencies will not be checked. To fix this, we simply emit all of FOO's depends (only real dependencies, no select) for BAR as well. git-svn-id: svn://svn.openwrt.org/openwrt/trunk@6293 3c298f89-4303-0410-b956-a3cf2f4a3e73
471 lines
10 KiB
Perl
Executable File
471 lines
10 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
use strict;
|
|
my %package;
|
|
my %category;
|
|
|
|
sub parse_target_metadata() {
|
|
my ($target, @target, $profile);
|
|
while (<>) {
|
|
chomp;
|
|
/^Target:\s*((.+)-(\d+\.\d+))\s*$/ and do {
|
|
my $conf = uc $3.'_'.$2;
|
|
$conf =~ tr/\.-/__/;
|
|
$target = {
|
|
id => $1,
|
|
conf => $conf,
|
|
board => $2,
|
|
kernel => $3,
|
|
profiles => []
|
|
};
|
|
push @target, $target;
|
|
};
|
|
/^Target-Name:\s*(.+)\s*$/ and $target->{name} = $1;
|
|
/^Target-Path:\s*(.+)\s*$/ and $target->{path} = $1;
|
|
/^Target-Arch:\s*(.+)\s*$/ and $target->{arch} = $1;
|
|
/^Target-Features:\s*(.+)\s*$/ and $target->{features} = [ split(/\s+/, $1) ];
|
|
/^Target-Description:/ and do {
|
|
my $desc;
|
|
while (<>) {
|
|
last if /^@@/;
|
|
$desc .= $_;
|
|
}
|
|
$target->{desc} = $desc;
|
|
};
|
|
/^Linux-Version:\s*(.+)\s*$/ and $target->{version} = $1;
|
|
/^Linux-Release:\s*(.+)\s*$/ and $target->{release} = $1;
|
|
/^Linux-Kernel-Arch:\s*(.+)\s*$/ and $target->{karch} = $1;
|
|
/^Default-Packages:\s*(.+)\s*$/ and $target->{packages} = [ split(/\s+/, $1) ];
|
|
/^Target-Profile:\s*(.+)\s*$/ and do {
|
|
$profile = {
|
|
id => $1,
|
|
name => $1,
|
|
packages => []
|
|
};
|
|
push @{$target->{profiles}}, $profile;
|
|
};
|
|
/^Target-Profile-Name:\s*(.+)\s*$/ and $profile->{name} = $1;
|
|
/^Target-Profile-Packages:\s*(.*)\s*$/ and $profile->{packages} = [ split(/\s+/, $1) ];
|
|
/^Target-Profile-Description:/ and do {
|
|
my $desc;
|
|
while (<>) {
|
|
last if /^@@/;
|
|
$desc .= $_;
|
|
}
|
|
$profile->{desc} = $desc;
|
|
};
|
|
}
|
|
foreach my $target (@target) {
|
|
@{$target->{profiles}} > 0 or $target->{profiles} = [
|
|
{
|
|
id => 'Default',
|
|
name => 'Default',
|
|
packages => []
|
|
}
|
|
];
|
|
}
|
|
return @target;
|
|
}
|
|
|
|
sub parse_package_metadata() {
|
|
my $pkg;
|
|
my $makefile;
|
|
my $src;
|
|
while (<>) {
|
|
chomp;
|
|
/^Source-Makefile: \s*(.+\/([^\/]+)\/Makefile)\s*$/ and do {
|
|
$makefile = $1;
|
|
$src = $2;
|
|
undef $pkg;
|
|
};
|
|
/^Package: \s*(.+)\s*$/ and do {
|
|
$pkg = {};
|
|
$pkg->{src} = $src;
|
|
$pkg->{makefile} = $makefile;
|
|
$pkg->{name} = $1;
|
|
$pkg->{default} = "m if ALL";
|
|
$package{$1} = $pkg;
|
|
};
|
|
/^Version: \s*(.+)\s*$/ and $pkg->{version} = $1;
|
|
/^Title: \s*(.+)\s*$/ and $pkg->{title} = $1;
|
|
/^Menu: \s*(.+)\s*$/ and $pkg->{menu} = $1;
|
|
/^Submenu: \s*(.+)\s*$/ and $pkg->{submenu} = $1;
|
|
/^Submenu-Depends: \s*(.+)\s*$/ and $pkg->{submenudep} = $1;
|
|
/^Default: \s*(.+)\s*$/ and $pkg->{default} = $1;
|
|
/^Provides: \s*(.+)\s*$/ and do {
|
|
my @vpkg = split /\s+/, $1;
|
|
foreach my $vpkg (@vpkg) {
|
|
$package{$vpkg} or $package{$vpkg} = { vdepends => [] };
|
|
push @{$package{$vpkg}->{vdepends}}, $pkg->{name};
|
|
}
|
|
};
|
|
/^Depends: \s*(.+)\s*$/ and do {
|
|
my @dep = split /\s+/, $1;
|
|
$pkg->{depends} = \@dep;
|
|
};
|
|
/^Category: \s*(.+)\s*$/ and do {
|
|
$pkg->{category} = $1;
|
|
defined $category{$1} or $category{$1} = {};
|
|
defined $category{$1}->{$src} or $category{$1}->{$src} = [];
|
|
push @{$category{$1}->{$src}}, $pkg;
|
|
};
|
|
/^Description: \s*(.*)\s*$/ and do {
|
|
my $desc = "\t\t$1\n\n";
|
|
my $line;
|
|
while ($line = <>) {
|
|
last if $line =~ /^@@/;
|
|
$desc .= "\t\t$line";
|
|
}
|
|
$pkg->{description} = $desc;
|
|
};
|
|
/^Config: \s*(.*)\s*$/ and do {
|
|
my $conf = "$1\n";
|
|
my $line;
|
|
while ($line = <>) {
|
|
last if $line =~ /^@@/;
|
|
$conf .= "$line";
|
|
}
|
|
$pkg->{config} = $conf;
|
|
}
|
|
}
|
|
return %category;
|
|
}
|
|
|
|
|
|
sub gen_target_mk() {
|
|
my @target = parse_target_metadata();
|
|
|
|
@target = sort {
|
|
$a->{id} cmp $b->{id}
|
|
} @target;
|
|
|
|
foreach my $target (@target) {
|
|
my ($profiles_def, $profiles_eval);
|
|
my $conf = uc $target->{kernel}.'_'.$target->{board};
|
|
$conf =~ tr/\.-/__/;
|
|
|
|
foreach my $profile (@{$target->{profiles}}) {
|
|
$profiles_def .= "
|
|
define Profile/$conf\_$profile->{id}
|
|
ID:=$profile->{id}
|
|
NAME:=$profile->{name}
|
|
PACKAGES:=".join(" ", @{$profile->{packages}})."
|
|
endef";
|
|
$profiles_eval .= "
|
|
\$(eval \$(call Profile,$conf\_$profile->{id}))"
|
|
}
|
|
print "
|
|
ifeq (\$(CONFIG_LINUX_$conf),y)
|
|
define Target
|
|
KERNEL:=$target->{kernel}
|
|
BOARD:=$target->{board}
|
|
BOARDNAME:=$target->{name}
|
|
LINUX_VERSION:=$target->{version}
|
|
LINUX_RELEASE:=$target->{release}
|
|
LINUX_KARCH:=$target->{karch}
|
|
DEFAULT_PACKAGES:=".join(" ", @{$target->{packages}})."
|
|
endef$profiles_def
|
|
endif$profiles_eval
|
|
|
|
"
|
|
}
|
|
print "\$(eval \$(call Target))\n";
|
|
}
|
|
|
|
sub target_config_features(@) {
|
|
my $ret;
|
|
|
|
while ($_ = shift @_) {
|
|
/broken/ and $ret .= "\tdepends BROKEN\n";
|
|
/pci/ and $ret .= "\tselect PCI_SUPPORT\n";
|
|
/usb/ and $ret .= "\tselect USB_SUPPORT\n";
|
|
/atm/ and $ret .= "\tselect ATM_SUPPORT\n";
|
|
/pcmcia/ and $ret .= "\tselect PCMCIA_SUPPORT\n";
|
|
/video/ and $ret .= "\tselect VIDEO_SUPPORT\n";
|
|
/squashfs/ and $ret .= "\tselect USES_SQUASHFS\n";
|
|
/jffs2/ and $ret .= "\tselect USES_JFFS2\n";
|
|
/ext2/ and $ret .= "\tselect USES_EXT2\n";
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
|
|
sub gen_target_config() {
|
|
my @target = parse_target_metadata();
|
|
|
|
@target = sort {
|
|
$a->{name} cmp $b->{name}
|
|
} @target;
|
|
|
|
|
|
print <<EOF;
|
|
choice
|
|
prompt "Target System"
|
|
default LINUX_2_4_BRCM
|
|
|
|
EOF
|
|
|
|
foreach my $target (@target) {
|
|
my $features = target_config_features(@{$target->{features}});
|
|
my $help = $target->{desc};
|
|
my $kernel = $target->{kernel};
|
|
$kernel =~ tr/./_/;
|
|
|
|
chomp $features;
|
|
$features .= "\n";
|
|
if ($help =~ /\w+/) {
|
|
$help =~ s/^\s*/\t /mg;
|
|
$help = "\thelp\n$help";
|
|
} else {
|
|
undef $help;
|
|
}
|
|
|
|
print <<EOF
|
|
config LINUX_$target->{conf}
|
|
bool "$target->{name}"
|
|
select $target->{arch}
|
|
select LINUX_$kernel
|
|
$features$help
|
|
|
|
EOF
|
|
}
|
|
|
|
print <<EOF;
|
|
if DEVEL
|
|
|
|
config LINUX_2_6_ARM
|
|
bool "UNSUPPORTED little-endian arm platform"
|
|
depends BROKEN
|
|
select LINUX_2_6
|
|
select arm
|
|
|
|
config LINUX_2_6_CRIS
|
|
bool "UNSUPPORTED cris platform"
|
|
depends BROKEN
|
|
select LINUX_2_6
|
|
select cris
|
|
|
|
config LINUX_2_6_M68K
|
|
bool "UNSUPPORTED m68k platform"
|
|
depends BROKEN
|
|
select LINUX_2_6
|
|
select m68k
|
|
|
|
config LINUX_2_6_SH3
|
|
bool "UNSUPPORTED little-endian sh3 platform"
|
|
depends BROKEN
|
|
select LINUX_2_6
|
|
select sh3
|
|
|
|
config LINUX_2_6_SH3EB
|
|
bool "UNSUPPORTED big-endian sh3 platform"
|
|
depends BROKEN
|
|
select LINUX_2_6
|
|
select sh3eb
|
|
|
|
config LINUX_2_6_SH4
|
|
bool "UNSUPPORTED little-endian sh4 platform"
|
|
depends BROKEN
|
|
select LINUX_2_6
|
|
select sh4
|
|
|
|
config LINUX_2_6_SH4EB
|
|
bool "UNSUPPORTED big-endian sh4 platform"
|
|
depends BROKEN
|
|
select LINUX_2_6
|
|
select sh4eb
|
|
|
|
config LINUX_2_6_SPARC
|
|
bool "UNSUPPORTED sparc platform"
|
|
depends BROKEN
|
|
select LINUX_2_6
|
|
select sparc
|
|
|
|
endif
|
|
|
|
endchoice
|
|
|
|
choice
|
|
prompt "Target Profile"
|
|
|
|
EOF
|
|
|
|
foreach my $target (@target) {
|
|
my $profiles = $target->{profiles};
|
|
|
|
foreach my $profile (@$profiles) {
|
|
print <<EOF;
|
|
config LINUX_$target->{conf}_$profile->{id}
|
|
bool "$profile->{name}"
|
|
depends LINUX_$target->{conf}
|
|
EOF
|
|
my %pkgs;
|
|
foreach my $pkg (@{$target->{packages}}, @{$profile->{packages}}) {
|
|
$pkgs{$pkg} = 1;
|
|
}
|
|
foreach my $pkg (keys %pkgs) {
|
|
print "\tselect DEFAULT_$pkg\n" unless ($pkg =~ /^-/ or $pkgs{"-$pkg"});
|
|
}
|
|
print "\n";
|
|
}
|
|
}
|
|
|
|
print "endchoice\n";
|
|
}
|
|
|
|
sub find_package_dep($$) {
|
|
my $pkg = shift;
|
|
my $name = shift;
|
|
my $deps = ($pkg->{vdepends} or $pkg->{depends});
|
|
|
|
return 0 unless defined $deps;
|
|
foreach my $dep (@{$deps}) {
|
|
return 1 if $dep eq $name;
|
|
return 1 if ($package{$dep} and (find_package_dep($package{$dep},$name) == 1));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
sub package_depends($$) {
|
|
my $a = shift;
|
|
my $b = shift;
|
|
my $ret;
|
|
|
|
return 0 if ($a->{submenu} ne $b->{submenu});
|
|
if (find_package_dep($a, $b->{name}) == 1) {
|
|
$ret = 1;
|
|
} elsif (find_package_dep($b, $a->{name}) == 1) {
|
|
$ret = -1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
sub mconf_depends($$) {
|
|
my $depends = shift;
|
|
my $only_dep = shift;
|
|
my $res;
|
|
|
|
$depends or return;
|
|
my @depends = @$depends;
|
|
foreach my $depend (@depends) {
|
|
my $m = "depends";
|
|
$depend =~ s/^([@\+]+)//;
|
|
my $flags = $1;
|
|
my $vdep;
|
|
|
|
if ($vdep = $package{$depend}->{vdepends}) {
|
|
$depend = join("||", map { "PACKAGE_".$_ } @$vdep);
|
|
} else {
|
|
$flags =~ /\+/ and do {
|
|
next if $only_dep;
|
|
$m = "select";
|
|
|
|
# Menuconfig will not treat 'select FOO' as a real dependency
|
|
# thus if FOO depends on other config options, these dependencies
|
|
# will not be checked. To fix this, we simply emit all of FOO's
|
|
# depends here as well.
|
|
$package{$depend} and $res .= mconf_depends($package{$depend}->{depends}, 1);
|
|
};
|
|
$flags =~ /@/ or $depend = "PACKAGE_$depend";
|
|
}
|
|
$res .= "\t\t$m $depend\n";
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
sub print_package_config_category($) {
|
|
my $cat = shift;
|
|
my %menus;
|
|
my %menu_dep;
|
|
|
|
return unless $category{$cat};
|
|
|
|
print "menu \"$cat\"\n\n";
|
|
my %spkg = %{$category{$cat}};
|
|
|
|
foreach my $spkg (sort {uc($a) cmp uc($b)} keys %spkg) {
|
|
foreach my $pkg (@{$spkg{$spkg}}) {
|
|
my $menu = $pkg->{submenu};
|
|
if ($menu) {
|
|
$menu_dep{$menu} or $menu_dep{$menu} = $pkg->{submenudep};
|
|
} else {
|
|
$menu = 'undef';
|
|
}
|
|
$menus{$menu} or $menus{$menu} = [];
|
|
push @{$menus{$menu}}, $pkg;
|
|
print "\tconfig DEFAULT_".$pkg->{name}."\n";
|
|
print "\t\tbool\n\n";
|
|
}
|
|
}
|
|
my @menus = sort {
|
|
($a eq 'undef' ? 1 : 0) or
|
|
($b eq 'undef' ? -1 : 0) or
|
|
($a cmp $b)
|
|
} keys %menus;
|
|
|
|
foreach my $menu (@menus) {
|
|
my @pkgs = sort {
|
|
package_depends($a, $b) or
|
|
($a->{name} cmp $b->{name})
|
|
} @{$menus{$menu}};
|
|
if ($menu ne 'undef') {
|
|
$menu_dep{$menu} and print "if $menu_dep{$menu}\n";
|
|
print "menu \"$menu\"\n";
|
|
}
|
|
foreach my $pkg (@pkgs) {
|
|
my $title = $pkg->{name};
|
|
my $c = (72 - length($pkg->{name}) - length($pkg->{title}));
|
|
if ($c > 0) {
|
|
$title .= ("." x $c). " ". $pkg->{title};
|
|
}
|
|
print "\t";
|
|
$pkg->{menu} and print "menu";
|
|
print "config PACKAGE_".$pkg->{name}."\n";
|
|
print "\t\ttristate \"$title\"\n";
|
|
print "\t\tdefault y if DEFAULT_".$pkg->{name}."\n";
|
|
foreach my $default (split /\s*,\s*/, $pkg->{default}) {
|
|
print "\t\tdefault $default\n";
|
|
}
|
|
print mconf_depends($pkg->{depends}, 0);
|
|
print "\t\thelp\n";
|
|
print $pkg->{description};
|
|
print "\n";
|
|
|
|
$pkg->{config} and print $pkg->{config}."\n";
|
|
}
|
|
if ($menu ne 'undef') {
|
|
print "endmenu\n";
|
|
$menu_dep{$menu} and print "endif\n";
|
|
}
|
|
}
|
|
print "endmenu\n\n";
|
|
|
|
undef $category{$cat};
|
|
}
|
|
|
|
sub gen_package_config() {
|
|
parse_package_metadata();
|
|
print_package_config_category 'Base system';
|
|
foreach my $cat (keys %category) {
|
|
print_package_config_category $cat;
|
|
}
|
|
}
|
|
|
|
sub parse_command() {
|
|
my $cmd = shift @ARGV;
|
|
for ($cmd) {
|
|
/^target_mk$/ and return gen_target_mk();
|
|
/^target_config$/ and return gen_target_config();
|
|
/^package_config$/ and return gen_package_config();
|
|
}
|
|
print <<EOF
|
|
Available Commands:
|
|
$0 target_mk [file] Target metadata in makefile format
|
|
$0 target_config [file] Target metadata in Kconfig format
|
|
$0 package_config [file] Package metadata in Kconfig format
|
|
EOF
|
|
}
|
|
|
|
parse_command();
|