--- /dev/null 2006-03-02 00:07:15.000000000 -0500 +++ distcc/gcc-translator.pl 2006-03-02 00:07:58.000000000 -0500 @@ -0,0 +1,145 @@ +#!/usr/bin/perl -w + +# usage: put this file in $DATADIR, then make symlinks for each +# of the compilers: +# +# cd $DATADIR +# for arch in powerpc i386; do +# for version in "" "-3.3" "-4.0"; do +# for gcc in cc c++ gcc g++; do +# if [ -f "/usr/bin/${gcc}${version}" ]; then +# ln -s "/usr/bin/${gcc}${version}" "${arch}-apple-darwin${DARWINVER}-${gcc}${version}" +# fi +# done +# done +# done +# +# install distcc and ccache, then set: +# +# export CCACHE_PREFIX=$DATADIR/gcc-translator.pl +# +# assuming you've got ccache set up to do symlinks to take over gcc, the gcc-translator script +# will automatically translate gcc calls into target-style gcc names (powerpc-apple-darwin8-gcc) + +use strict; + +my $DISTCCBIN = '@FINKPREFIX@/bin/distcc'; +my $DATADIR = '@FINKPREFIX@/var/lib/distcc'; + +if (not exists $ENV{'DISTCC_TRANS'} or $ENV{'DISTCC_TRANS'} !~ /^(true|1|yes|y)$/i) { + exit run_command($DISTCCBIN, @ARGV); +} + +my $DEBUG = 0; + +my $arch_lookup = { + ppc => 'powerpc', + ppc64 => 'powerpc', + i386 => 'i386', +}; + +my $reverse_arch_lookup = { + 'powerpc' => 'ppc', + 'i386' => 'i386', +}; + +$ENV{'PATH'} = $DATADIR . '/translated:' . $ENV{'PATH'}; + +if ($0 =~ /(powerpc|i386)-apple-([^\d]+)(\d+)-(.*)$/) { + my ($archname, $os, $version, $compiler) = ($1, $2, $3, $4); + + my @command = ('/usr/bin/' . $compiler); + if (exists $reverse_arch_lookup->{$archname}) { + push(@command, '-arch', $reverse_arch_lookup->{$archname}); + } + push(@command, @ARGV); + exit run_command(@command); +} + +my $compiler = shift(@ARGV) || 'gcc'; +if ($compiler !~ m#/#) { + $compiler = which($compiler); +} + +my $arch; +my @args; + +$compiler = render_symlinks($compiler); + +my $lastarg; +for my $arg (@ARGV) { + if ($arg eq "-arch") { + $lastarg = "arch"; + } elsif (defined $lastarg and $lastarg eq "arch") { + $arch = $arch_lookup->{$arg} if (exists $arch_lookup->{$arg}); + $lastarg = undef; + } else { + push(@args, $arg); + } +} + +chomp(my $uname = lc(`uname -s -r -p`)); +my ($osname, $version, $archname) = split(/\s+/, $uname); +$version =~ s/^(\d+).*$/$1/; + +if (not defined $arch) { + $arch = $archname; +} + +$compiler = "${arch}-apple-${osname}${version}-" . basename($compiler); + +my @command = ($DISTCCBIN, $compiler, @args); +exit run_command(@command); + +sub run_command { + print STDERR "@command\n" if ($DEBUG); + + my $exit = system(@_); + + if ($exit == -1) { + die "failed to execute $DISTCCBIN $compiler @args\n"; + } elsif ($exit & 127) { + printf STDERR "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; + } else { + return int($exit >> 8); + } +} + +sub render_symlinks { + my $filename = shift; + + if (defined $filename and -l $filename) { + my $linkname = readlink($filename); + if ($linkname !~ m#/#) { + $linkname = dirname($filename) . $linkname; + } + return render_symlinks($linkname); + } + + return $filename; +} + +sub which { + my $filename = shift; + + for my $dir (split(/:/, $ENV{'PATH'})) { + my $fullname = $dir . '/' . $filename; + next if (-l $fullname and (readlink($fullname) =~ /distcc/ or readlink($fullname) =~ /ccache/)); + + if (-f $dir . '/' . $filename) { + return $dir . '/' . $filename; + } + } +} + +sub basename { + my $filename = shift; + + return @{[ $filename =~ m#^.*/([^/]+)$#]}[0]; +} + +sub dirname { + my $filename = shift; + + return @{[ $filename =~ m#^(.*/)[^/]*$# ]}[0]; +}