thinkpad-ec/scripts/generate_deps

155 lines
4.1 KiB
Perl
Executable File

#!/usr/bin/env perl
use warnings;
use strict;
#
# Copyright (C) 2017-2019 Hamish Coleman
#
# Read through a descriptions file on input and auto generate a list of rules
# for building the various files on output
#
# Each rule input line generates two dependancies:
# $filename.orig from $depname.orig using macro rule_$rule_extract
# $depname from $filename using macro rule_$rule_insert
#
# TODO:
# - this currently hardcods a dependancy on .config for every generated rule
# - which could be relaxed with some work
# - also, hardcoding it might not be the nicest method
my @entries;
while(<>) {
s/^#.*//; # remove comment lines
next if (m/^$/);
if (!m/^(\S+)\s+(\S+)\s+(.*)/) {
# if we dont have three space-separated fields, skip the line
next;
}
my $entry = {};
$entry->{generator_file} = $ARGV;
$entry->{generator_line} = $.;
$entry->{filename} = $1;
$entry->{tags_raw} = $2;
$entry->{description} = $3;
for my $tv (split(/,/,$entry->{tags_raw})) {
my ($tag,$val_raw) = split(/:/,$tv);
if (!defined($val_raw)) {
warn("Missing tag value");
next;
}
my @values = split(/;/,$val_raw);
push @{$entry->{tags}{$tag}}, @values;
}
# default tags - if there is a value loaded from the tags_raw, it will
# take precedence, but otherwise this ensures we create the array and
# have the default value at [0]
push @{$entry->{tags}{extract}},1;
push @{$entry->{tags}{insert}},1;
push @{$entry->{tags}{suffix}},1;
push @entries,$entry;
}
my $rules_found = 0;
my @extracts;
my @inserts;
for my $entry (@entries) {
# only generate rules for lines that ask for them
next if (!defined($entry->{tags}{rule}));
# FIXME - if there is more than one rule, error?
# currently need at least one dep defined
next if (!defined($entry->{tags}{dep}));
$rules_found++;
my @deps = @{$entry->{tags}{dep}};
my $dep0 = shift @deps;
my @deps_extract;
if (defined($entry->{tags}{depe})) {
@deps_extract = @{$entry->{tags}{depe}};
}
my @deps_insert;
if (defined($entry->{tags}{depi})) {
@deps_insert = @{$entry->{tags}{depi}};
}
my @params;
if (defined($entry->{tags}{param})) {
@params = @{$entry->{tags}{param}};
}
if ($entry->{tags}{extract}[0]) {
# generate the forward rule
my $suffix = "";
if ($entry->{tags}{suffix}[0]) {
$suffix = ".orig";
}
my $rule = "rule_".$entry->{tags}{rule}[0]."_extract";
push @extracts,
sprintf("# %s:%i\n",
$entry->{generator_file},
$entry->{generator_line},
),
sprintf("%s: %s %s %s\n\t\$(call %s)\n\n",
$entry->{filename}.$suffix,
$dep0.$suffix,
join(' ',
@deps,
@deps_extract,
$entry->{generator_file},
'.config',
),
'$('.$rule.'_DEPS)',
join(',',$rule,@params),
);
}
if ($entry->{tags}{insert}[0]) {
# generate the inverse rule
my $rule = "rule_".$entry->{tags}{rule}[0]."_insert";
push @inserts,
sprintf("# %s:%i\n",
$entry->{generator_file},
$entry->{generator_line},
),
sprintf("%s: %s %s %s\n\t\$(call %s)\n\n",
$dep0,
$entry->{filename},
join(' ',
@deps,
@deps_insert,
$entry->{generator_file},
'.config',
),
'$('.$rule.'_DEPS)',
join(',',$rule,@params),
);
}
}
if (!$rules_found) {
# only generate output if we have at least one matching line - so an empty input
# will just result in an empty output
exit(0);
}
print("# autogenerated rules file - do not edit\n\n");
print(join('',@extracts));
print("\n\n");
print(join('',@inserts));
print STDERR "Generated dependancies from descriptions\n";