add initial version of a package feeds management script
SVN-Revision: 8973
This commit is contained in:
parent
d7502c446b
commit
f8dfc57573
7 changed files with 484 additions and 130 deletions
2
feeds.conf
Normal file
2
feeds.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
src-svn packages https://svn.openwrt.org/openwrt/packages
|
||||
src-svn xwrt http://svn.berlios.de/svnroot/repos/xwrt/trunk/package
|
|
@ -1,15 +1,15 @@
|
|||
include $(TOPDIR)/include/verbose.mk
|
||||
TMP_DIR:=$(TOPDIR)/tmp
|
||||
|
||||
all: tmp/.$(SCAN_TARGET)
|
||||
all: $(TMP_DIR)/.$(SCAN_TARGET)
|
||||
|
||||
include $(TOPDIR)/include/host.mk
|
||||
|
||||
SCAN_TARGET ?= packageinfo
|
||||
SCAN_NAME ?= package
|
||||
SCAN_DIR ?= package
|
||||
TARGET_STAMP:=tmp/info/.files-$(SCAN_TARGET).stamp
|
||||
FILELIST:=tmp/info/.files-$(SCAN_TARGET)-$(SCAN_COOKIE)
|
||||
TARGET_STAMP:=$(TMP_DIR)/info/.files-$(SCAN_TARGET).stamp
|
||||
FILELIST:=$(TMP_DIR)/info/.files-$(SCAN_TARGET)-$(SCAN_COOKIE)
|
||||
|
||||
ifeq ($(IS_TTY),1)
|
||||
define progress
|
||||
|
@ -22,8 +22,8 @@ else
|
|||
endif
|
||||
|
||||
define PackageDir
|
||||
tmp/.$(SCAN_TARGET): tmp/info/.$(SCAN_TARGET)-$(1)
|
||||
tmp/info/.$(SCAN_TARGET)-$(1): $(SCAN_DIR)/$(2)/Makefile $(SCAN_STAMP) $(foreach DEP,$(DEPS_$(SCAN_DIR)/$(1)/Makefile) $(SCAN_DEPS),$(wildcard $(if $(filter /%,$(DEP)),$(DEP),$(SCAN_DIR)/$(1)/$(DEP))))
|
||||
$(TMP_DIR)/.$(SCAN_TARGET): $(TMP_DIR)/info/.$(SCAN_TARGET)-$(1)
|
||||
$(TMP_DIR)/info/.$(SCAN_TARGET)-$(1): $(SCAN_DIR)/$(2)/Makefile $(SCAN_STAMP) $(foreach DEP,$(DEPS_$(SCAN_DIR)/$(1)/Makefile) $(SCAN_DEPS),$(wildcard $(if $(filter /%,$(DEP)),$(DEP),$(SCAN_DIR)/$(1)/$(DEP))))
|
||||
{ \
|
||||
$$(call progress,Collecting $(SCAN_NAME) info: $(SCAN_DIR)/$(2)) \
|
||||
echo Source-Makefile: $(SCAN_DIR)/$(2)/Makefile; \
|
||||
|
@ -33,10 +33,10 @@ define PackageDir
|
|||
endef
|
||||
|
||||
$(FILELIST):
|
||||
rm -f tmp/info/.files-$(SCAN_TARGET)-*
|
||||
rm -f $(TMP_DIR)/info/.files-$(SCAN_TARGET)-*
|
||||
$(call FIND_L, $(SCAN_DIR)) $(SCAN_EXTRA) -mindepth 1 $(if $(SCAN_DEPTH),-maxdepth $(SCAN_DEPTH)) -name Makefile | xargs grep -HE 'call (Build/DefaultTargets|Build(Package|Target)|.+Package)' | sed -e 's#^$(SCAN_DIR)/##' -e 's#/Makefile:.*##' | uniq > $@
|
||||
|
||||
tmp/info/.files-$(SCAN_TARGET).mk: $(FILELIST)
|
||||
$(TMP_DIR)/info/.files-$(SCAN_TARGET).mk: $(FILELIST)
|
||||
( \
|
||||
cat $< | awk '{print "$(SCAN_DIR)/" $$0 "/Makefile" }' | xargs grep -HE '^ *SCAN_DEPS *= *' | awk -F: '{ gsub(/^.*DEPS *= */, "", $$2); print "DEPS_" $$1 "=" $$2 }'; \
|
||||
awk -v deps="$$DEPS" '{ \
|
||||
|
@ -47,7 +47,7 @@ tmp/info/.files-$(SCAN_TARGET).mk: $(FILELIST)
|
|||
true; \
|
||||
) > $@
|
||||
|
||||
-include tmp/info/.files-$(SCAN_TARGET).mk
|
||||
-include $(TMP_DIR)/info/.files-$(SCAN_TARGET).mk
|
||||
|
||||
$(TARGET_STAMP):
|
||||
( \
|
||||
|
@ -60,9 +60,9 @@ $(TARGET_STAMP):
|
|||
} \
|
||||
)
|
||||
|
||||
tmp/.$(SCAN_TARGET): $(TARGET_STAMP) $(SCAN_STAMP)
|
||||
$(TMP_DIR)/.$(SCAN_TARGET): $(TARGET_STAMP) $(SCAN_STAMP)
|
||||
$(call progress,Collecting $(SCAN_NAME) info: merging...)
|
||||
cat $(FILELIST) | awk '{gsub(/\//, "_", $$0);print "tmp/info/.$(SCAN_TARGET)-" $$0}' | xargs cat > $@
|
||||
cat $(FILELIST) | awk '{gsub(/\//, "_", $$0);print "$(TMP_DIR)/info/.$(SCAN_TARGET)-" $$0}' | xargs cat > $@
|
||||
$(call progress,Collecting $(SCAN_NAME) info: done)
|
||||
echo
|
||||
|
||||
|
|
|
@ -30,15 +30,17 @@ endif
|
|||
SCAN_COOKIE?=$(shell echo $$$$)
|
||||
export SCAN_COOKIE
|
||||
|
||||
prepare-mk: FORCE ;
|
||||
|
||||
prepare-tmpinfo: FORCE
|
||||
mkdir -p tmp/info
|
||||
+$(NO_TRACE_MAKE) -s -f include/scan.mk SCAN_TARGET="packageinfo" SCAN_DIR="package" SCAN_NAME="package" SCAN_DEPS="$(TOPDIR)/include/package*.mk" SCAN_DEPTH=4 SCAN_EXTRA=""
|
||||
+$(NO_TRACE_MAKE) -s -f include/scan.mk SCAN_TARGET="targetinfo" SCAN_DIR="target/linux" SCAN_NAME="target" SCAN_DEPS="profiles/*.mk $(TOPDIR)/include/kernel*.mk" SCAN_DEPTH=2 SCAN_EXTRA="" SCAN_MAKEOPTS="TARGET_BUILD=1"
|
||||
for type in package target; do \
|
||||
f=tmp/.$${type}info; t=tmp/.config-$${type}.in; \
|
||||
[ "$$t" -nt "$$f" ] || ./scripts/metadata.pl $${type}_config < "$$f" > "$$t" || { rm -f "$$t"; echo "Failed to build $$t"; false; break; }; \
|
||||
[ "$$t" -nt "$$f" ] || ./scripts/metadata.pl $${type}_config "$$f" > "$$t" || { rm -f "$$t"; echo "Failed to build $$t"; false; break; }; \
|
||||
done
|
||||
./scripts/metadata.pl package_mk < tmp/.packageinfo > tmp/.packagedeps || { rm -f tmp/.packagedeps; false; }
|
||||
./scripts/metadata.pl package_mk tmp/.packageinfo > tmp/.packagedeps || { rm -f tmp/.packagedeps; false; }
|
||||
touch $(TOPDIR)/tmp/.build
|
||||
|
||||
.config: ./scripts/config/conf prepare-tmpinfo
|
||||
|
@ -64,7 +66,7 @@ defconfig: scripts/config/conf prepare-tmpinfo FORCE
|
|||
$< -D .config Config.in
|
||||
|
||||
oldconfig: scripts/config/conf prepare-tmpinfo FORCE
|
||||
$< -o Config.in
|
||||
$< -$(if $(CONFDEFAULT),$(CONFDEFAULT),o) Config.in
|
||||
|
||||
menuconfig: scripts/config/mconf prepare-tmpinfo FORCE
|
||||
if [ \! -f .config -a -e $(HOME)/.openwrt/defconfig ]; then \
|
||||
|
|
|
@ -579,28 +579,11 @@ int main(int ac, char **av)
|
|||
}
|
||||
case ask_all:
|
||||
case ask_new:
|
||||
conf_read(NULL);
|
||||
break;
|
||||
case set_no:
|
||||
case set_mod:
|
||||
case set_yes:
|
||||
case set_random:
|
||||
name = getenv("KCONFIG_ALLCONFIG");
|
||||
if (name && !stat(name, &tmpstat)) {
|
||||
conf_read_simple(name);
|
||||
break;
|
||||
}
|
||||
switch (input_mode) {
|
||||
case set_no: name = "allno.config"; break;
|
||||
case set_mod: name = "allmod.config"; break;
|
||||
case set_yes: name = "allyes.config"; break;
|
||||
case set_random: name = "allrandom.config"; break;
|
||||
default: break;
|
||||
}
|
||||
if (!stat(name, &tmpstat))
|
||||
conf_read_simple(name);
|
||||
else if (!stat("all.config", &tmpstat))
|
||||
conf_read_simple("all.config");
|
||||
conf_read(NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
322
scripts/feeds
Executable file
322
scripts/feeds
Executable file
|
@ -0,0 +1,322 @@
|
|||
#!/usr/bin/perl
|
||||
use Getopt::Std;
|
||||
use FindBin;
|
||||
use Cwd;
|
||||
use lib "$FindBin::Bin";
|
||||
use metadata;
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
chdir "$FindBin::Bin/..";
|
||||
$ENV{TOPDIR}=getcwd();
|
||||
|
||||
my @feeds;
|
||||
my %build_packages;
|
||||
my %installed;
|
||||
|
||||
sub parse_config() {
|
||||
my $line = 0;
|
||||
my %name;
|
||||
|
||||
open FEEDS, "feeds.conf";
|
||||
while (<FEEDS>) {
|
||||
chomp;
|
||||
s/#.+$//;
|
||||
next unless /\S/;
|
||||
my @line = split /\s+/, $_, 3;
|
||||
$line++;
|
||||
|
||||
my $valid = 1;
|
||||
$line[0] =~ /^src-\w+$/ or $valid = 0;
|
||||
$line[1] =~ /^\w+$/ or $valid = 0;
|
||||
$line[2] =~ /\s/ and $valid = 0;
|
||||
$valid or die "Syntax error in feeds.list, line: $line\n";
|
||||
|
||||
$name{$line[1]} and die "Duplicate feed name '$line[1]', line: $line\n";
|
||||
$name{$line[1]} = 1;
|
||||
|
||||
push @feeds, [@line];
|
||||
}
|
||||
close FEEDS;
|
||||
}
|
||||
|
||||
sub update_svn($$) {
|
||||
my $name = shift;
|
||||
my $src = shift;
|
||||
|
||||
system("svn co $src ./feeds/$name") == 0 or return 1;
|
||||
-d "./feeds/$name.tmp" or mkdir "./feeds/$name.tmp" or return 1;
|
||||
-d "./feeds/$name.tmp/info" or mkdir "./feeds/$name.tmp/info" or return 1;
|
||||
|
||||
system("make -s prepare-mk TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\"");
|
||||
system("make -s -f include/scan.mk IS_TTY=1 SCAN_TARGET=\"packageinfo\" SCAN_DIR=\"feeds/$name\" SCAN_NAME=\"package\" SCAN_DEPS=\"$ENV{TOPDIR}/include/package*.mk\" SCAN_DEPTH=4 SCAN_EXTRA=\"\" TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\"");
|
||||
system("ln -sf $name.tmp/.packageinfo ./feeds/$name.index");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub get_feed($) {
|
||||
my $feed = shift;
|
||||
|
||||
clear_packages();
|
||||
parse_package_metadata("./feeds/$feed.index") or return;
|
||||
return { %package };
|
||||
}
|
||||
|
||||
sub get_installed() {
|
||||
system("make -s prepare-tmpinfo");
|
||||
clear_packages();
|
||||
parse_package_metadata("./tmp/.packageinfo");
|
||||
%installed = %package;
|
||||
}
|
||||
|
||||
sub search_feed {
|
||||
my $feed = shift;
|
||||
my @substr = @_;
|
||||
my $display;
|
||||
|
||||
return unless @substr > 0;
|
||||
get_feed($feed);
|
||||
foreach my $name (sort { lc($a) cmp lc($b) } keys %package) {
|
||||
my $pkg = $package{$name};
|
||||
my $substr;
|
||||
my $pkgmatch = 1;
|
||||
|
||||
foreach my $substr (@substr) {
|
||||
my $match;
|
||||
foreach my $key (qw(name title description)) {
|
||||
$substr and $pkg->{$key} =~ m/$substr/i and $match = 1;
|
||||
}
|
||||
$match or undef $pkgmatch;
|
||||
};
|
||||
$pkgmatch and do {
|
||||
$display or do {
|
||||
print "Search results in feed '$feed':\n";
|
||||
$display = 1;
|
||||
};
|
||||
printf "\%-25s\t\%s\n", $pkg->{name}, $pkg->{title};
|
||||
};
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
sub search {
|
||||
my %opts;
|
||||
|
||||
getopt('r:', \%opts);
|
||||
foreach my $feed (@feeds) {
|
||||
search_feed($feed->[1], @ARGV) if (!defined($opts{r}) or $opts{r} eq $feed->[1]);
|
||||
}
|
||||
}
|
||||
|
||||
sub install_svn() {
|
||||
my $feed = shift;
|
||||
my $pkg = shift;
|
||||
my $path = $pkg->{makefile};
|
||||
$path =~ s/\/Makefile$//;
|
||||
|
||||
-d "./package/feeds" or mkdir "./package/feeds";
|
||||
-d "./package/feeds/$feed->[1]" or mkdir "./package/feeds/$feed->[1]";
|
||||
system("ln -sf ../../../$path ./package/feeds/$feed->[1]/");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
my %install_method = (
|
||||
'src-svn' => \&install_svn
|
||||
);
|
||||
|
||||
my %feed;
|
||||
|
||||
sub lookup_package($$) {
|
||||
my $feed = shift;
|
||||
my $package = shift;
|
||||
|
||||
foreach my $feed ($feed, @feeds) {
|
||||
next unless $feed->[1];
|
||||
next unless $feed{$feed->[1]};
|
||||
$feed{$feed->[1]}->{$package} and return $feed;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sub install_package {
|
||||
my $feed = shift;
|
||||
my $name = shift;
|
||||
my $ret = 0;
|
||||
|
||||
$feed = lookup_package($feed, $name);
|
||||
$feed or do {
|
||||
$installed{$name} and return 0;
|
||||
warn "WARNING: Package '$name' is not available.\n";
|
||||
return 1;
|
||||
};
|
||||
|
||||
my $pkg = $feed{$feed->[1]}->{$name} or return 1;
|
||||
my $src = $pkg->{src};
|
||||
my $type = $feed->[0];
|
||||
$src or $src = $name;
|
||||
|
||||
# previously installed packages set the runtime package
|
||||
# newly installed packages set the source package
|
||||
$installed{$src} and return 0;
|
||||
|
||||
# install all dependencies
|
||||
foreach my $dep (@{$pkg->{depends}}) {
|
||||
next if $dep =~ /@/;
|
||||
$dep =~ s/^\+//;
|
||||
install_package($feed, $dep) == 0 or $ret = 1;
|
||||
}
|
||||
|
||||
# check previously installed packages
|
||||
$installed{$name} and return 0;
|
||||
$installed{$src} = 1;
|
||||
warn "Installing package '$src'\n";
|
||||
|
||||
$install_method{$type} or do {
|
||||
warn "Unknown installation method: '$type'\n";
|
||||
return 1;
|
||||
};
|
||||
|
||||
&{$install_method{$type}}($feed, $pkg) == 0 or do {
|
||||
warn "failed.\n";
|
||||
return 1;
|
||||
};
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub refresh_config {
|
||||
my $default = shift;
|
||||
$default or $default = "o";
|
||||
|
||||
# workaround for timestamp check
|
||||
system("rm -f tmp/.packageinfo");
|
||||
|
||||
# refresh the config
|
||||
system("make oldconfig CONFDEFAULT=\"$default\" Config.in >/dev/null 2>/dev/null");
|
||||
}
|
||||
|
||||
sub install {
|
||||
my $name;
|
||||
my %opts;
|
||||
my $feed;
|
||||
my $ret = 0;
|
||||
|
||||
getopt('p:d:', \%opts);
|
||||
get_installed();
|
||||
|
||||
foreach my $f (@feeds) {
|
||||
# index all feeds
|
||||
$feed{$f->[1]} = get_feed($f->[1]);
|
||||
|
||||
# look up the preferred feed
|
||||
$opts{p} and $f->[1] eq $opts{p} and $feed = $f;
|
||||
}
|
||||
|
||||
while ($name = shift @ARGV) {
|
||||
install_package($feed, $name) == 0 or $ret = 1;
|
||||
}
|
||||
|
||||
# workaround for timestamp check
|
||||
|
||||
# set the defaults
|
||||
if ($opts{d} and $opts{d} =~ /^[ymn]$/) {
|
||||
refresh_config($opts{d});
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub uninstall {
|
||||
my $name;
|
||||
my $uninstall;
|
||||
|
||||
if ($ARGV[0] eq '-a') {
|
||||
system("rm -rf ./package/feeds");
|
||||
$uninstall = 1;
|
||||
} else {
|
||||
get_installed();
|
||||
while ($name = shift @ARGV) {
|
||||
my $pkg = $installed{$name};
|
||||
$pkg or do {
|
||||
warn "WARNING: $name not installed\n";
|
||||
next;
|
||||
};
|
||||
$pkg->{src} and $name = $pkg->{src};
|
||||
warn "Uninstalling package '$name'\n";
|
||||
system("rm -f ./package/feeds/*/$name");
|
||||
$uninstall = 1;
|
||||
}
|
||||
}
|
||||
$uninstall and refresh_config();
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub usage() {
|
||||
print <<EOF;
|
||||
Usage: $0 <command> [options]
|
||||
|
||||
Commands:
|
||||
install [options] <package>: Install a package
|
||||
Options:
|
||||
-p <feedname>: Prefer this feed when installing packages
|
||||
-d <y|m|n>: Set default for newly installed packages
|
||||
|
||||
search [options] <substring>: Search for a package
|
||||
Options:
|
||||
-r <feedname>: Only search in this feed
|
||||
|
||||
uninstall -a|<package>: Uninstall a package
|
||||
-a uninstalls all packages
|
||||
|
||||
update: Update packages and lists of feeds in feeds.list
|
||||
clean: Remove downloaded/generated files
|
||||
|
||||
EOF
|
||||
exit(1);
|
||||
}
|
||||
|
||||
my %update_method = (
|
||||
'src-svn' => \&update_svn
|
||||
);
|
||||
|
||||
my %commands = (
|
||||
'update' => sub {
|
||||
-d "feeds" or do {
|
||||
mkdir "feeds" or die "Unable to create the feeds directory";
|
||||
};
|
||||
$ENV{SCAN_COOKIE} = $$;
|
||||
$ENV{KBUILD_VERBOSE} = 99;
|
||||
foreach my $feed (@feeds) {
|
||||
my ($type, $name, $src) = @$feed;
|
||||
$update_method{$type} or do {
|
||||
warn "Unknown type '$type' in feed $name\n";
|
||||
next;
|
||||
};
|
||||
warn "Updating feed '$name'...\n";
|
||||
&{$update_method{$type}}($name, $src) == 0 or do {
|
||||
warn "failed.\n";
|
||||
return 1;
|
||||
};
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
'install' => \&install,
|
||||
'search' => \&search,
|
||||
'uninstall' => \&uninstall,
|
||||
'clean' => sub {
|
||||
system("rm -rf feeds");
|
||||
}
|
||||
);
|
||||
|
||||
my $arg = shift @ARGV;
|
||||
$arg or usage();
|
||||
parse_config;
|
||||
foreach my $cmd (keys %commands) {
|
||||
$arg eq $cmd and do {
|
||||
exit(&{$commands{$cmd}}());
|
||||
};
|
||||
}
|
||||
usage();
|
|
@ -1,24 +1,11 @@
|
|||
#!/usr/bin/perl
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin";
|
||||
use strict;
|
||||
my %preconfig;
|
||||
my %package;
|
||||
my %srcpackage;
|
||||
my %category;
|
||||
my %subdir;
|
||||
use metadata;
|
||||
|
||||
my %board;
|
||||
|
||||
sub get_multiline {
|
||||
my $prefix = shift;
|
||||
my $str;
|
||||
while (<>) {
|
||||
last if /^@@/;
|
||||
s/^\s*//g;
|
||||
$str .= (($_ and $prefix) ? $prefix . $_ : $_);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
sub confstr($) {
|
||||
my $conf = shift;
|
||||
$conf =~ tr#/\.\-/#___#;
|
||||
|
@ -26,8 +13,13 @@ sub confstr($) {
|
|||
}
|
||||
|
||||
sub parse_target_metadata() {
|
||||
my ($target, @target, $profile);
|
||||
while (<>) {
|
||||
my $file = shift @ARGV;
|
||||
my ($target, @target, $profile);
|
||||
open FILE, "<$file" or do {
|
||||
warn "Can't open file '$file': $!\n";
|
||||
return;
|
||||
};
|
||||
while (<FILE>) {
|
||||
chomp;
|
||||
/^Target:\s*(.+)\s*$/ and do {
|
||||
$target = {
|
||||
|
@ -46,7 +38,7 @@ sub parse_target_metadata() {
|
|||
/^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 $target->{desc} = get_multiline();
|
||||
/^Target-Description:/ and $target->{desc} = get_multiline(*FILE);
|
||||
/^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;
|
||||
|
@ -61,10 +53,11 @@ sub parse_target_metadata() {
|
|||
};
|
||||
/^Target-Profile-Name:\s*(.+)\s*$/ and $profile->{name} = $1;
|
||||
/^Target-Profile-Packages:\s*(.*)\s*$/ and $profile->{packages} = [ split(/\s+/, $1) ];
|
||||
/^Target-Profile-Description:\s*(.*)\s*/ and $profile->{desc} = get_multiline();
|
||||
/^Target-Profile-Config:/ and $profile->{config} = get_multiline("\t");
|
||||
/^Target-Profile-Description:\s*(.*)\s*/ and $profile->{desc} = get_multiline(*FILE);
|
||||
/^Target-Profile-Config:/ and $profile->{config} = get_multiline(*FILE, "\t");
|
||||
/^Target-Profile-Kconfig:/ and $profile->{kconfig} = 1;
|
||||
}
|
||||
close FILE;
|
||||
foreach my $target (@target) {
|
||||
@{$target->{profiles}} > 0 or $target->{profiles} = [
|
||||
{
|
||||
|
@ -77,78 +70,6 @@ sub parse_target_metadata() {
|
|||
return @target;
|
||||
}
|
||||
|
||||
sub parse_package_metadata() {
|
||||
my $pkg;
|
||||
my $makefile;
|
||||
my $preconfig;
|
||||
my $subdir;
|
||||
my $src;
|
||||
while (<>) {
|
||||
chomp;
|
||||
/^Source-Makefile: \s*((.+\/)([^\/]+)\/Makefile)\s*$/ and do {
|
||||
$makefile = $1;
|
||||
$subdir = $2;
|
||||
$src = $3;
|
||||
$subdir =~ s/^package\///;
|
||||
$subdir{$src} = $subdir;
|
||||
$srcpackage{$src} = [];
|
||||
undef $pkg;
|
||||
};
|
||||
/^Package:\s*(.+?)\s*$/ and do {
|
||||
$pkg = {};
|
||||
$pkg->{src} = $src;
|
||||
$pkg->{makefile} = $makefile;
|
||||
$pkg->{name} = $1;
|
||||
$pkg->{default} = "m if ALL";
|
||||
$pkg->{depends} = [];
|
||||
$pkg->{builddepends} = [];
|
||||
$pkg->{subdir} = $subdir;
|
||||
$package{$1} = $pkg;
|
||||
push @{$srcpackage{$src}}, $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 $pkg->{depends} = [ split /\s+/, $1 ];
|
||||
/^Build-Depends: \s*(.+)\s*$/ and $pkg->{builddepends} = [ split /\s+/, $1 ];
|
||||
/^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 $pkg->{description} = "\t\t $1\n". get_multiline("\t\t ");
|
||||
/^Config: \s*(.*)\s*$/ and $pkg->{config} = "$1\n".get_multiline();
|
||||
/^Prereq-Check:/ and $pkg->{prereq} = 1;
|
||||
/^Preconfig:\s*(.+)\s*$/ and do {
|
||||
my $pkgname = $pkg->{name};
|
||||
$preconfig{$pkgname} or $preconfig{$pkgname} = {};
|
||||
if (exists $preconfig{$pkgname}->{$1}) {
|
||||
$preconfig = $preconfig{$pkgname}->{$1};
|
||||
} else {
|
||||
$preconfig = {
|
||||
id => $1
|
||||
};
|
||||
$preconfig{$pkgname}->{$1} = $preconfig;
|
||||
}
|
||||
};
|
||||
/^Preconfig-Type:\s*(.*?)\s*$/ and $preconfig->{type} = $1;
|
||||
/^Preconfig-Label:\s*(.*?)\s*$/ and $preconfig->{label} = $1;
|
||||
/^Preconfig-Default:\s*(.*?)\s*$/ and $preconfig->{default} = $1;
|
||||
}
|
||||
return %category;
|
||||
}
|
||||
|
||||
sub gen_kconfig_overrides() {
|
||||
my %config;
|
||||
my %kconfig;
|
||||
|
@ -318,20 +239,31 @@ EOF
|
|||
print "endchoice\n";
|
||||
}
|
||||
|
||||
|
||||
sub find_package_dep($$) {
|
||||
my %dep_check;
|
||||
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}) {
|
||||
next if $dep_check{$dep};
|
||||
$dep_check{$dep} = 1;
|
||||
return 1 if $dep eq $name;
|
||||
return 1 if ($package{$dep} and (find_package_dep($package{$dep},$name) == 1));
|
||||
return 1 if ($package{$dep} and (__find_package_dep($package{$dep},$name) == 1));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# wrapper to avoid infinite recursion
|
||||
sub find_package_dep($$) {
|
||||
my $pkg = shift;
|
||||
my $name = shift;
|
||||
|
||||
%dep_check = ();
|
||||
return __find_package_dep($pkg, $name);
|
||||
}
|
||||
|
||||
sub package_depends($$) {
|
||||
my $a = shift;
|
||||
my $b = shift;
|
||||
|
@ -452,7 +384,7 @@ sub print_package_config_category($) {
|
|||
}
|
||||
|
||||
sub gen_package_config() {
|
||||
parse_package_metadata();
|
||||
parse_package_metadata($ARGV[0]) or exit 1;
|
||||
print "menuconfig UCI_PRECONFIG\n\tbool \"Image configuration\"\n";
|
||||
foreach my $preconfig (keys %preconfig) {
|
||||
foreach my $cfg (keys %{$preconfig{$preconfig}}) {
|
||||
|
@ -478,7 +410,7 @@ sub gen_package_mk() {
|
|||
my %dep;
|
||||
my $line;
|
||||
|
||||
parse_package_metadata();
|
||||
parse_package_metadata($ARGV[0]) or exit 1;
|
||||
foreach my $name (sort {uc($a) cmp uc($b)} keys %package) {
|
||||
my $config;
|
||||
my $pkg = $package{$name};
|
||||
|
|
113
scripts/metadata.pm
Normal file
113
scripts/metadata.pm
Normal file
|
@ -0,0 +1,113 @@
|
|||
package metadata;
|
||||
use base 'Exporter';
|
||||
use strict;
|
||||
use warnings;
|
||||
our @EXPORT = qw(%package %srcpackage %category %subdir %preconfig clear_packages parse_package_metadata get_multiline);
|
||||
|
||||
our %package;
|
||||
our %preconfig;
|
||||
our %srcpackage;
|
||||
our %category;
|
||||
our %subdir;
|
||||
|
||||
sub get_multiline {
|
||||
my $fh = shift;
|
||||
my $prefix = shift;
|
||||
my $str;
|
||||
while (<$fh>) {
|
||||
last if /^@@/;
|
||||
s/^\s*//g;
|
||||
$str .= (($_ and $prefix) ? $prefix . $_ : $_);
|
||||
}
|
||||
|
||||
return $str ? $str : "";
|
||||
}
|
||||
|
||||
sub clear_packages() {
|
||||
%subdir = ();
|
||||
%preconfig = ();
|
||||
%package = ();
|
||||
%srcpackage = ();
|
||||
%category = ();
|
||||
}
|
||||
|
||||
sub parse_package_metadata($) {
|
||||
my $file = shift;
|
||||
my $pkg;
|
||||
my $makefile;
|
||||
my $preconfig;
|
||||
my $subdir;
|
||||
my $src;
|
||||
|
||||
open FILE, "<$file" or do {
|
||||
warn "Cannot open '$file': $!\n";
|
||||
return undef;
|
||||
};
|
||||
while (<FILE>) {
|
||||
chomp;
|
||||
/^Source-Makefile: \s*((.+\/)([^\/]+)\/Makefile)\s*$/ and do {
|
||||
$makefile = $1;
|
||||
$subdir = $2;
|
||||
$src = $3;
|
||||
$subdir =~ s/^package\///;
|
||||
$subdir{$src} = $subdir;
|
||||
$srcpackage{$src} = [];
|
||||
undef $pkg;
|
||||
};
|
||||
/^Package:\s*(.+?)\s*$/ and do {
|
||||
$pkg = {};
|
||||
$pkg->{src} = $src;
|
||||
$pkg->{makefile} = $makefile;
|
||||
$pkg->{name} = $1;
|
||||
$pkg->{default} = "m if ALL";
|
||||
$pkg->{depends} = [];
|
||||
$pkg->{builddepends} = [];
|
||||
$pkg->{subdir} = $subdir;
|
||||
$package{$1} = $pkg;
|
||||
push @{$srcpackage{$src}}, $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 $pkg->{depends} = [ split /\s+/, $1 ];
|
||||
/^Build-Depends: \s*(.+)\s*$/ and $pkg->{builddepends} = [ split /\s+/, $1 ];
|
||||
/^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 $pkg->{description} = "\t\t $1\n". get_multiline(*FILE, "\t\t ");
|
||||
/^Config: \s*(.*)\s*$/ and $pkg->{config} = "$1\n".get_multiline(*FILE);
|
||||
/^Prereq-Check:/ and $pkg->{prereq} = 1;
|
||||
/^Preconfig:\s*(.+)\s*$/ and do {
|
||||
my $pkgname = $pkg->{name};
|
||||
$preconfig{$pkgname} or $preconfig{$pkgname} = {};
|
||||
if (exists $preconfig{$pkgname}->{$1}) {
|
||||
$preconfig = $preconfig{$pkgname}->{$1};
|
||||
} else {
|
||||
$preconfig = {
|
||||
id => $1
|
||||
};
|
||||
$preconfig{$pkgname}->{$1} = $preconfig;
|
||||
}
|
||||
};
|
||||
/^Preconfig-Type:\s*(.*?)\s*$/ and $preconfig->{type} = $1;
|
||||
/^Preconfig-Label:\s*(.*?)\s*$/ and $preconfig->{label} = $1;
|
||||
/^Preconfig-Default:\s*(.*?)\s*$/ and $preconfig->{default} = $1;
|
||||
}
|
||||
close FILE;
|
||||
return %category;
|
||||
}
|
||||
|
||||
1;
|
Loading…
Reference in a new issue