src/cross-run.in: Delete pointless `Data::Dumper' import.
[mdw-cross] / src / cross-run.in
CommitLineData
6cb0a33a
MW
1#! /usr/bin/perl
2
6cb0a33a
MW
3use File::FnMatch qw(fnmatch);
4use MdwOpt;
5
6our $CROSSDIR = "@crossdir@";
7(our $ME = $0) =~ s:^.*/::;
8
9###--------------------------------------------------------------------------
10### Utilities.
11
12sub usage (*) {
13 my ($fh) = @_;
14 print $fh
ce7bce96 15 "usage: $ME [-kns] [-j N] =ARCHGLOB|:FLAVOUR ... [--] CMD [ARGS ...]\n";
6cb0a33a
MW
16}
17sub barf ($) {
18 my ($msg) = @_;
19 print STDERR "$0: $msg\n";
20 exit 2;
21}
22
23###--------------------------------------------------------------------------
24### Read and prepare the configuration.
25
26our %C = ();
27open my $fh, "<", "$CROSSDIR/etc/config.sh" or barf "open config: $!";
28while (<$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
37our @ALLARCH;
38our %FLAVOUR;
39for 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
49our @ARCH = ();
50our $JOBS = undef;
c65bb1c1
MW
51our $KEEPGOING = 0;
52our $SILENT = 0;
53our $DRYRUN = 0;
6cb0a33a
MW
54our $DIR = ".";
55our $MARKER = "{}";
56our @CMD = ();
57
c65bb1c1 58my $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'];
68my $bad = 0;
69OPT: 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;
102push @CMD, $mo->rest, @{$mo->{argv}};
103if ($bad) { usage STDERR; exit 2; }
104
105###--------------------------------------------------------------------------
106### Hack the arguments and run `make'.
107
108sub hack ($) {
109 my ($x) = @_;
110 $x =~ s/'/'\\''/g;
111 $x =~ s/\$/\$\$/g;
112 $x =~ s/\Q$MARKER/\$*/g;
113 return "'$x'";
114}
115
116our $TARGET = "run";
117if ($CMD[0] eq 'make') { $TARGET = "run-make"; shift @CMD; }
118our @MAKE = ("make");
119push @MAKE, "-f$CROSSDIR/Makefile";
120push @MAKE, "-j$JOBS" if defined $JOBS;
c65bb1c1
MW
121push @MAKE, "-k" if $KEEPGOING;
122push @MAKE, "-n" if $DRYRUN;
123push @MAKE, "-s" if $SILENT;
6cb0a33a
MW
124push @MAKE, $TARGET;
125push @MAKE, "ARCHS=" . join " ", @ARCH;
126push @MAKE, "ARGS=" . join " ", map { hack $_ } @CMD;
127push @MAKE, "CROSSDIR=$CROSSDIR";
128push @MAKE, "DIR=" . hack $DIR;
129exec @MAKE;
130barf "make: $!";
131
132###----- That's all, folks --------------------------------------------------