mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-21 22:47:56 +00:00
436 lines
9.7 KiB
Perl
436 lines
9.7 KiB
Perl
|
#!/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) ];
|
||
|
}
|
||
|
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";
|
||
|
/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};
|
||
|
|
||
|
@$profiles > 0 or $profiles = [
|
||
|
{
|
||
|
id => 'Default',
|
||
|
name => 'Default',
|
||
|
packages => []
|
||
|
}
|
||
|
];
|
||
|
foreach my $profile (@$profiles) {
|
||
|
print <<EOF;
|
||
|
config LINUX_$target->{conf}_$profile->{id}
|
||
|
bool "$profile->{name}"
|
||
|
depends LINUX_$target->{conf}
|
||
|
EOF
|
||
|
foreach my $pkg (@{$target->{packages}}, @{$profile->{packages}}) {
|
||
|
print "\tselect DEFAULT_$pkg\n";
|
||
|
}
|
||
|
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 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";
|
||
|
}
|
||
|
foreach my $depend (@{$pkg->{depends}}) {
|
||
|
my $m = "depends";
|
||
|
$depend =~ s/^([@\+]+)//;
|
||
|
my $flags = $1;
|
||
|
my $vdep;
|
||
|
|
||
|
if ($vdep = $package{$depend}->{vdepends}) {
|
||
|
$depend = join("||", map { "PACKAGE_".$_ } @$vdep);
|
||
|
} else {
|
||
|
$flags =~ /@/ or $depend = "PACKAGE_$depend";
|
||
|
$flags =~ /\+/ and $m = "select";
|
||
|
}
|
||
|
print "\t\t$m $depend\n";
|
||
|
}
|
||
|
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();
|