Commit | Line | Data |
---|---|---|
6cb0a33a MW |
1 | #! /usr/bin/perl |
2 | ||
3 | use Data::Dumper; | |
4 | ||
5 | use File::FnMatch qw(fnmatch); | |
6 | use MdwOpt; | |
7 | ||
8 | our $CROSSDIR = "@crossdir@"; | |
9 | (our $ME = $0) =~ s:^.*/::; | |
10 | ||
11 | ###-------------------------------------------------------------------------- | |
12 | ### Utilities. | |
13 | ||
14 | sub usage (*) { | |
15 | my ($fh) = @_; | |
16 | print $fh | |
17 | "usage: $ME [-j N] =ARCHGLOB|:FLAVOUR ... [--] CMD [ARGS ...]\n"; | |
18 | } | |
19 | sub barf ($) { | |
20 | my ($msg) = @_; | |
21 | print STDERR "$0: $msg\n"; | |
22 | exit 2; | |
23 | } | |
24 | ||
25 | ###-------------------------------------------------------------------------- | |
26 | ### Read and prepare the configuration. | |
27 | ||
28 | our %C = (); | |
29 | open my $fh, "<", "$CROSSDIR/etc/config.sh" or barf "open config: $!"; | |
30 | while (<$fh>) { | |
31 | chomp; | |
32 | if (/^\s*(#|$)/) { next; } | |
33 | if (!/^([^=]+)='(.*)'$/) { barf "bad config line `$_'"; } | |
34 | my ($k, $v) = ($1, $2); | |
35 | $v =~ s/'\\''/'/g; | |
36 | $C{$k} = $v; | |
37 | } | |
38 | ||
39 | our @ALLARCH; | |
40 | our %FLAVOUR; | |
41 | for my $f (split ' ', $C{"FLAVOURS"}) { | |
42 | (my $v = $f) =~ tr/-/_/; | |
43 | my @a = split ' ', $C{"${v}_ARCHS"}; | |
44 | @{$FLAVOUR{$f}} = @a; | |
45 | push @ALLARCH, @a; | |
46 | } | |
47 | ||
48 | ###-------------------------------------------------------------------------- | |
49 | ### Parse the command line. | |
50 | ||
51 | our @ARCH = (); | |
52 | our $JOBS = undef; | |
c65bb1c1 MW |
53 | our $KEEPGOING = 0; |
54 | our $SILENT = 0; | |
55 | our $DRYRUN = 0; | |
6cb0a33a MW |
56 | our $DIR = "."; |
57 | our $MARKER = "{}"; | |
58 | our @CMD = (); | |
59 | ||
c65bb1c1 | 60 | my $mo = new MdwOpt "hC:j:km:ns", |
6cb0a33a MW |
61 | { "help" => { 'return' => "h" }, |
62 | "directory" => { 'return' => 'C', 'arg' => 'req' }, | |
63 | "jobs" => { 'return' => "j", 'arg' => 'req' }, | |
c65bb1c1 MW |
64 | "keep-going" => { 'return' => "k" }, |
65 | "marker" => { 'return' => "m", 'arg' => 'req' }, | |
66 | "dry-run" => { 'return' => "n" }, | |
67 | "silent" => { 'return' => "s" } }, | |
6cb0a33a MW |
68 | \@ARGV, |
69 | ['inorder']; | |
70 | my $bad = 0; | |
71 | OPT: for (;;) { | |
72 | my ($opt, $arg) = $mo->read; | |
73 | last OPT unless defined $opt; | |
74 | if ($opt eq "h") { usage STDOUT; exit 0; } | |
75 | elsif ($opt eq "C") { $DIR = $arg; } | |
76 | elsif ($opt eq "j") | |
77 | { $arg =~ /^[+]?\d+$/ or barf "bad integer `$arg'"; $JOBS = $arg; } | |
c65bb1c1 | 78 | elsif ($opt eq "k") { $KEEPGOING = 1; } |
6cb0a33a | 79 | elsif ($opt eq "m") { $MARKER = $arg; } |
c65bb1c1 MW |
80 | elsif ($opt eq "n") { $DRYRUN = $arg; } |
81 | elsif ($opt eq "s") { $SILENT = $arg; } | |
6cb0a33a MW |
82 | elsif ($opt eq '') { |
83 | if ($arg =~ /^=(.*)$/) { | |
84 | my $pat = $1; | |
85 | my $match = 0; | |
86 | ARCH: for my $a (@ALLARCH) { | |
87 | next ARCH unless fnmatch $pat, $a; | |
88 | $match = 1; push @ARCH, $a; | |
89 | } | |
90 | $match or barf "no architectures match `$pat'"; | |
91 | } elsif ($arg =~ /^:(.*)$/) { | |
92 | my $f = $1; | |
93 | exists $FLAVOUR{$f} or barf "no architeture flavour `$f'"; | |
94 | push @ARCH, @{%FLAVOUR{$f}}; | |
95 | } else { | |
96 | push @CMD, $arg; | |
97 | last OPT; | |
98 | } | |
99 | } else { | |
100 | $bad = 1; | |
101 | } | |
102 | } | |
103 | $bad = 1 unless @ARCH && @CMD; | |
104 | push @CMD, $mo->rest, @{$mo->{argv}}; | |
105 | if ($bad) { usage STDERR; exit 2; } | |
106 | ||
107 | ###-------------------------------------------------------------------------- | |
108 | ### Hack the arguments and run `make'. | |
109 | ||
110 | sub hack ($) { | |
111 | my ($x) = @_; | |
112 | $x =~ s/'/'\\''/g; | |
113 | $x =~ s/\$/\$\$/g; | |
114 | $x =~ s/\Q$MARKER/\$*/g; | |
115 | return "'$x'"; | |
116 | } | |
117 | ||
118 | our $TARGET = "run"; | |
119 | if ($CMD[0] eq 'make') { $TARGET = "run-make"; shift @CMD; } | |
120 | our @MAKE = ("make"); | |
121 | push @MAKE, "-f$CROSSDIR/Makefile"; | |
122 | push @MAKE, "-j$JOBS" if defined $JOBS; | |
c65bb1c1 MW |
123 | push @MAKE, "-k" if $KEEPGOING; |
124 | push @MAKE, "-n" if $DRYRUN; | |
125 | push @MAKE, "-s" if $SILENT; | |
6cb0a33a MW |
126 | push @MAKE, $TARGET; |
127 | push @MAKE, "ARCHS=" . join " ", @ARCH; | |
128 | push @MAKE, "ARGS=" . join " ", map { hack $_ } @CMD; | |
129 | push @MAKE, "CROSSDIR=$CROSSDIR"; | |
130 | push @MAKE, "DIR=" . hack $DIR; | |
131 | exec @MAKE; | |
132 | barf "make: $!"; | |
133 | ||
134 | ###----- That's all, folks -------------------------------------------------- |