#!/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 # export DISTCC_TRANS=true # # 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 = '/sw/bin/distcc'; my $DATADIR = '/sw/var/lib/distcc'; if ($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 . ':' . $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]; }