diff options
author | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-11-10 16:21:32 +0000 |
---|---|---|
committer | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-11-10 16:21:32 +0000 |
commit | 5033f39a3b2031ebadaa285d5671c9df33fb1465 (patch) | |
tree | 7d31850559b233dedd1d6d1b56232644c407d269 /etc | |
parent | efde15c57cd9279362d6c5878a70f971a1ba1869 (diff) | |
download | ATCD-5033f39a3b2031ebadaa285d5671c9df33fb1465.tar.gz |
added ace_ld, drop-in replacement for ld that supports munching
Diffstat (limited to 'etc')
-rwxr-xr-x | etc/ace_ld | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/etc/ace_ld b/etc/ace_ld new file mode 100755 index 00000000000..00787b85fe0 --- /dev/null +++ b/etc/ace_ld @@ -0,0 +1,172 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# +# Drop-in replacement for "ld" that supports munching. +# +# The first three lines above let this script run without specifying the +# full path to perl, as long as it is in the user's PATH. +# Taken from perlrun man page. + +$usage = "usage: $0 [-? | [[-c <compile>] [-m <munch>] [-n <nm>]] [-f]]]"; + +#### +#### process command line args +#### +while ( $#ARGV >= 0 && $ARGV[0] =~ /^-/ ) { + if ( $ARGV[0] eq '-c' ) { + if ( $ARGV[1] !~ /^[-].+$/ ) { + $compile = $ARGV[1]; shift; + } else { + print STDERR "$0: must provide argument for -c option\n"; + die $usage; + } + } elsif ( $ARGV[0] eq '-m' ) { + if ( $ARGV[1] !~ /^[-].+$/ ) { + $munch = $ARGV[1]; shift; + } else { + print STDERR "$0: must provide argument for -m option\n"; + die $usage; + } + } elsif ( $ARGV[0] eq '-n' ) { + if ( $ARGV[1] !~ /^[-].+$/ ) { + $nm = $ARGV[1]; shift; + } else { + print STDERR "$0: must provide argument for -n option\n"; + die $usage; + } + } elsif ( $ARGV[0] eq '-?' ) { + print "$usage"; + exit; + } else { + warn "$0: unknown option $ARGV[0]\n"; + die $usage; + } + shift; +} + + +#### +#### Save link command, i.e., current @ARGV, for use below. +#### +@args = @ARGV; + + +#### +#### Find full path to each library. +#### +@libDirs = (); +$current_dir_in_libDirs = 0; +@libs = (); +@objs = ''; + +foreach $arg (@ARGV) { + if ($arg =~ /-L([\S]+)/) { + ($dir = $1) =~ s%/+$%%; #### trim any trailing slashes + push @libDirs, $dir; + $current_dir_in_libDirs = 1 if $dir eq '.'; + } elsif ($arg =~ /-l([\S]+)/) { + push @libs, $1; + } elsif ($arg =~ /\.o$/) { + push @objs, $arg; + } +} + +#### Add . to libDirs if it doesn't already have it. +push @libDirs, "." unless $current_dir_in_libDirs; + +foreach $lib (@libs) { + foreach $libDir (@libDirs) { + if (-e "$libDir/lib$lib.a") { + $full_path{$lib} = "$libDir/lib$lib.a"; + last; + } + } +} + + +#### +#### Set up signal handler. +#### +$done = 0; +$SIG{'HUP'} = $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'TERM'} = 'cleanup'; + + +#### +#### Munch, if $munch is non-null. +#### +if ($munch) { + $munch_objs = join (' ', @objs); + $munch_libs = join (' ', values %full_path); + + open (MUNCH, "$nm $munch_objs $munch_libs | $munch |") || + fail ("$0: unable to run \"$nm\" or \"$munch\"\n"); + + open (CTORDTOR, "> __ctordtor.c") || + fail ("$0: unable to open \"__ctordtor.c\"\n"); + + while (<MUNCH>) { + #### Filter out munch output that contains '.cpp'. It results from + #### .cpp files that have no text or data, e.g., .cpp files that + #### only contain template instantiations. These lines confuse g++. + print CTORDTOR unless /\.cpp/; + } + + close CTORDTOR || fail ("$0: unable to write \"__ctordtor.c\"\n"); + close MUNCH; + + system ("$compile -o .obj/__ctordtor.o __ctordtor.c") && + fail ("$0: \"$compile\" failed\n"); +} + + +#### +#### Construct the link command from @args and perform the link. +#### +if ($munch) { + #### Insert ctordtor object file before first library in link command. + $arg_lib = 0; + foreach $arg (@ARGV) { + if ($arg =~ /-l/) { + last; + } + ++$arg_lib; + } + splice (@args, $arg_lib, 0, ".obj/__ctordtor.o"); +} + +$link_command = join (' ', @args); + +system ("$link_command") && fail ("$0: $link_command failed\n"); + + +$done = 1; +&cleanup; + + +#### +#### +#### +sub fail { + local ($message) = @_; + + warn $message; + &cleanup; +} + + +#### +#### clean up when done or on signal +#### +sub cleanup { + unlink "__ctordtor.c", ".obj/__ctordtor.o"; + if ($done) { + exit 0; + } else { + exit 1; + } +} + +#### EOF |