$(call v_tag,SED)sed 's/@arch@/$($*_ARCH)/g' $< >$@.new && \
mv $@.new $@
-SCRIPTS = mdw-cross crosstool
+SCRIPTS = mdw-cross crosstool cross-run
BINSCRIPTS = $(addprefix bin/,$(SCRIPTS))
TARGETS += $(BINSCRIPTS)
$(BINSCRIPTS): bin/%: src/%.in
CLEANFILES += $(TARGETS)
clean::; rm -f $(CLEANFILES)
+run-program = exec 8>&1 && rc=$$( exec 7>&1 && \
+ { exec 9>&1 && \
+ { ($1 9>&-; echo $$? >&7) | \
+ while IFS= read -r line; \
+ do printf >&9 "%-21s | %s\n" "$2" "$$line"; done; } 2>&1 | \
+ while IFS= read -r line; \
+ do printf >&9 "%-21s * %s\n" "$2" "$$line"; done; } | cat >&8 ) && \
+ exit $$rc
+
+run: $(addprefix run/,$(ARCHS))
+$(addprefix run/,$(ARCHS)): run/%:
+ @cd $(DIR) && \
+ $(call run-program,$(CROSSDIR)/bin/mdw-cross $* $(ARGS),$*)
+.PHONY: run $(addprefix run/,$(ARCHS))
+
+run-make: $(addprefix run-make/,$(ARCHS))
+$(addprefix run-make/,$(ARCHS)): run-make/%:
+ @+$(call run-program,$(CROSSDIR)/bin/mdw-cross $* $(MAKE) -C$(DIR) $(ARGS),$*)
+.PHONY: run-make $(addprefix run-make/,$(ARCHS))
+
show:; : $(VAR)
--- /dev/null
+#! /usr/bin/perl
+
+use Data::Dumper;
+
+use File::FnMatch qw(fnmatch);
+use MdwOpt;
+
+our $CROSSDIR = "@crossdir@";
+(our $ME = $0) =~ s:^.*/::;
+
+###--------------------------------------------------------------------------
+### Utilities.
+
+sub usage (*) {
+ my ($fh) = @_;
+ print $fh
+ "usage: $ME [-j N] =ARCHGLOB|:FLAVOUR ... [--] CMD [ARGS ...]\n";
+}
+sub barf ($) {
+ my ($msg) = @_;
+ print STDERR "$0: $msg\n";
+ exit 2;
+}
+
+###--------------------------------------------------------------------------
+### Read and prepare the configuration.
+
+our %C = ();
+open my $fh, "<", "$CROSSDIR/etc/config.sh" or barf "open config: $!";
+while (<$fh>) {
+ chomp;
+ if (/^\s*(#|$)/) { next; }
+ if (!/^([^=]+)='(.*)'$/) { barf "bad config line `$_'"; }
+ my ($k, $v) = ($1, $2);
+ $v =~ s/'\\''/'/g;
+ $C{$k} = $v;
+}
+
+our @ALLARCH;
+our %FLAVOUR;
+for my $f (split ' ', $C{"FLAVOURS"}) {
+ (my $v = $f) =~ tr/-/_/;
+ my @a = split ' ', $C{"${v}_ARCHS"};
+ @{$FLAVOUR{$f}} = @a;
+ push @ALLARCH, @a;
+}
+
+###--------------------------------------------------------------------------
+### Parse the command line.
+
+our @ARCH = ();
+our $JOBS = undef;
+our $DIR = ".";
+our $MARKER = "{}";
+our @CMD = ();
+
+my $mo = new MdwOpt "hC:j:m:",
+ { "help" => { 'return' => "h" },
+ "directory" => { 'return' => 'C', 'arg' => 'req' },
+ "jobs" => { 'return' => "j", 'arg' => 'req' },
+ "marker" => { 'return' => "m", 'arg' => 'req' } },
+ \@ARGV,
+ ['inorder'];
+my $bad = 0;
+OPT: for (;;) {
+ my ($opt, $arg) = $mo->read;
+ last OPT unless defined $opt;
+ if ($opt eq "h") { usage STDOUT; exit 0; }
+ elsif ($opt eq "C") { $DIR = $arg; }
+ elsif ($opt eq "j")
+ { $arg =~ /^[+]?\d+$/ or barf "bad integer `$arg'"; $JOBS = $arg; }
+ elsif ($opt eq "m") { $MARKER = $arg; }
+ elsif ($opt eq '') {
+ if ($arg =~ /^=(.*)$/) {
+ my $pat = $1;
+ my $match = 0;
+ ARCH: for my $a (@ALLARCH) {
+ next ARCH unless fnmatch $pat, $a;
+ $match = 1; push @ARCH, $a;
+ }
+ $match or barf "no architectures match `$pat'";
+ } elsif ($arg =~ /^:(.*)$/) {
+ my $f = $1;
+ exists $FLAVOUR{$f} or barf "no architeture flavour `$f'";
+ push @ARCH, @{%FLAVOUR{$f}};
+ } else {
+ push @CMD, $arg;
+ last OPT;
+ }
+ } else {
+ $bad = 1;
+ }
+}
+$bad = 1 unless @ARCH && @CMD;
+push @CMD, $mo->rest, @{$mo->{argv}};
+if ($bad) { usage STDERR; exit 2; }
+
+###--------------------------------------------------------------------------
+### Hack the arguments and run `make'.
+
+sub hack ($) {
+ my ($x) = @_;
+ $x =~ s/'/'\\''/g;
+ $x =~ s/\$/\$\$/g;
+ $x =~ s/\Q$MARKER/\$*/g;
+ return "'$x'";
+}
+
+our $TARGET = "run";
+if ($CMD[0] eq 'make') { $TARGET = "run-make"; shift @CMD; }
+our @MAKE = ("make");
+push @MAKE, "-f$CROSSDIR/Makefile";
+push @MAKE, "-j$JOBS" if defined $JOBS;
+push @MAKE, $TARGET;
+push @MAKE, "ARCHS=" . join " ", @ARCH;
+push @MAKE, "ARGS=" . join " ", map { hack $_ } @CMD;
+push @MAKE, "CROSSDIR=$CROSSDIR";
+push @MAKE, "DIR=" . hack $DIR;
+exec @MAKE;
+barf "make: $!";
+
+###----- That's all, folks --------------------------------------------------