From 06e88a80c7e0bc8c5e5fe35f40cf8c6ca24447ea Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 13 Jan 2007 14:05:14 +0000
Subject: [PATCH] merge the scripts dealing with package/target metadata to
 remove some redundant code

SVN-Revision: 6088
---
 Makefile                      |   4 +-
 include/target.mk             |   2 +-
 scripts/gen_package_config.pl | 194 ---------------
 scripts/gen_target_config.pl  | 200 ----------------
 scripts/gen_target_mk.pl      |  88 -------
 scripts/metadata.pl           | 435 ++++++++++++++++++++++++++++++++++
 6 files changed, 438 insertions(+), 485 deletions(-)
 delete mode 100755 scripts/gen_package_config.pl
 delete mode 100755 scripts/gen_target_config.pl
 delete mode 100755 scripts/gen_target_mk.pl
 create mode 100755 scripts/metadata.pl

diff --git a/Makefile b/Makefile
index a3d5720db3..84c8c51156 100644
--- a/Makefile
+++ b/Makefile
@@ -82,10 +82,10 @@ tmpinfo-clean: FORCE
 	@-rm -rf tmp/.pkginfo tmp/.targetinfo
 
 tmp/.config.in: tmp/.pkginfo
-	@./scripts/gen_package_config.pl < $< > $@ || rm -f $@
+	@./scripts/metadata.pl package_config < $< > $@ || rm -f $@
 
 tmp/.config-target.in: tmp/.targetinfo
-	@./scripts/gen_target_config.pl < $< > $@ || rm -f $@
+	@./scripts/metadata.pl target_config < $< > $@ || rm -f $@
 
 .config: ./scripts/config/conf tmp/.config.in tmp/.config-target.in
 	@[ -f .config ] || $(NO_TRACE_MAKE) menuconfig
diff --git a/include/target.mk b/include/target.mk
index 17a41f7c49..bd3ceb955b 100644
--- a/include/target.mk
+++ b/include/target.mk
@@ -12,6 +12,6 @@ $(TMP_DIR)/.target.mk: $(TOPDIR)/.target.mk
 	$(CP) $< $@
 else
 $(TMP_DIR)/.target.mk: $(TMP_DIR)/.targetinfo
-	$(SCRIPT_DIR)/gen_target_mk.pl < $(TMP_DIR)/.targetinfo > $@
+	$(SCRIPT_DIR)/metadata.pl target_mk < $(TMP_DIR)/.targetinfo > $@
 endif
 
diff --git a/scripts/gen_package_config.pl b/scripts/gen_package_config.pl
deleted file mode 100755
index 51031a898a..0000000000
--- a/scripts/gen_package_config.pl
+++ /dev/null
@@ -1,194 +0,0 @@
-#!/usr/bin/perl
-# 
-# Copyright (C) 2006 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-use strict;
-
-my $src;
-my $makefile;
-my $pkg;
-my %package;
-my %category;
-
-
-sub find_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_dep($package{$dep},$name) == 1));
-	}
-	return 0;
-}
-
-sub depends($$) {
-	my $a = shift;
-	my $b = shift;
-	my $ret;
-
-	return 0 if ($a->{submenu} ne $b->{submenu});
-	if (find_dep($a, $b->{name}) == 1) {
-		$ret = 1;
-	} elsif (find_dep($b, $a->{name}) == 1) {
-		$ret = -1;
-	} else {
-		return 0;
-	}
-#	print STDERR "depends($a->{name}, $b->{name}) == $ret\n";
-	return $ret;
-}
-
-
-sub print_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 {
-			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};
-}
-
-my $line;
-while ($line = <>) {
-	chomp $line;
-	$line =~ /^Source-Makefile: \s*(.+\/([^\/]+)\/Makefile)\s*$/ and do {
-		$makefile = $1;
-		$src = $2;
-		undef $pkg;
-	};
-	$line =~ /^Package: \s*(.+)\s*$/ and do {
-		$pkg = {};
-		$pkg->{src} = $src;
-		$pkg->{makefile} = $makefile;
-		$pkg->{name} = $1;
-		$pkg->{default} = "m if ALL";
-		$package{$1} = $pkg;
-	};
-	$line =~ /^Version: \s*(.+)\s*$/ and $pkg->{version} = $1;
-	$line =~ /^Title: \s*(.+)\s*$/ and $pkg->{title} = $1;
-	$line =~ /^Menu: \s*(.+)\s*$/ and $pkg->{menu} = $1;
-	$line =~ /^Submenu: \s*(.+)\s*$/ and $pkg->{submenu} = $1;
-	$line =~ /^Submenu-Depends: \s*(.+)\s*$/ and $pkg->{submenudep} = $1;
-	$line =~ /^Default: \s*(.+)\s*$/ and $pkg->{default} = $1;
-	$line =~ /^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};
-		}
-	};
-	$line =~ /^Depends: \s*(.+)\s*$/ and do {
-		my @dep = split /\s+/, $1;
-		$pkg->{depends} = \@dep;
-	};
-	$line =~ /^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;
-	};
-	$line =~ /^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;
-	};
-	$line =~ /^Config: \s*(.*)\s*$/ and do {
-		my $conf = "$1\n";
-		my $line;
-		while ($line = <>) {
-			last if $line =~ /^@@/;
-			$conf .= "$line";
-		}
-		$pkg->{config} = $conf;
-	}
-}
-
-print_category 'Base system';
-foreach my $cat (keys %category) {
-	print_category $cat;
-}
diff --git a/scripts/gen_target_config.pl b/scripts/gen_target_config.pl
deleted file mode 100755
index 10c6c2c0b2..0000000000
--- a/scripts/gen_target_config.pl
+++ /dev/null
@@ -1,200 +0,0 @@
-#!/usr/bin/perl
-# 
-# Copyright (C) 2006 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-use strict;
-
-my @target;
-my $target;
-my $profiles;
-my $profile;
-
-sub 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;
-}
-
-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
-		};
-		$target->{kernel} =~ tr/\./_/;
-		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 do {
-		my $f = [];
-		$target->{features} = $f;
-		@$f = 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 do {
-		my @pkgs = split /\s+/, $1;
-		$target->{defaultpkgs} = \@pkgs;
-	};
-	/^Target-Profile:\s*(.+)\s*$/ and do {
-		$profiles = $target->{profiles} or $target->{profiles} = $profiles = [];
-		$profile = {
-			id => $1
-		};
-		push @$profiles, $profile;
-	};
-	/^Target-Profile-Name:\s*(.+)\s*$/ and $profile->{name} = $1;
-	/^Target-Profile-Packages:\s*(.+)\s*$/ and do {
-		my @pkgs = split /\s+/, $1;
-		$profile->{pkgs} = \@pkgs;
-	};
-}
-
-@target = sort {
-	$a->{name} cmp $b->{name}
-} @target;
-
-
-print <<EOF;
-choice
-	prompt "Target System"
-	default LINUX_2_4_BRCM
-	
-EOF
-
-foreach $target (@target) {
-	my $features = features(@{$target->{features}});
-	my $help = $target->{desc};
-	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_$target->{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 $target (@target) {
-	my $profiles;
-	
-	$profiles = $target->{profiles} or $profiles = [
-		{
-			id => 'Default',
-			name => 'Default',
-			pkgs => []
-		}
-	];
-	foreach my $profile (@$profiles) {
-		print <<EOF;
-config LINUX_$target->{conf}_$profile->{id}
-	bool "$profile->{name}"
-	depends LINUX_$target->{conf}
-EOF
-		foreach my $pkg (@{$target->{defaultpkgs}}, @{$profile->{pkgs}}) {
-			print "\tselect DEFAULT_$pkg\n";
-		}
-		print "\n";
-	}
-}
-
-print "endchoice\n";
diff --git a/scripts/gen_target_mk.pl b/scripts/gen_target_mk.pl
deleted file mode 100755
index 613c35bf2e..0000000000
--- a/scripts/gen_target_mk.pl
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/perl
-# 
-# Copyright (C) 2006 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-use strict;
-
-my @target;
-my $target;
-my $profile;
-
-while (<>) {
-	chomp;
-	/^Target:\s*((.+)-(\d+\.\d+))\s*$/ and do {
-		$target = {
-			id => $1,
-			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 = sort {
-	$a->{id} cmp $b->{id}
-} @target;
-
-foreach $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";
diff --git a/scripts/metadata.pl b/scripts/metadata.pl
new file mode 100755
index 0000000000..5da5ac48a0
--- /dev/null
+++ b/scripts/metadata.pl
@@ -0,0 +1,435 @@
+#!/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();
-- 
2.30.2