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