Thread

  1. BUG #1412: binaries are linked to numerous extraneous shared

    Todd R. Eigenschink <todd@tekinteractive.com> — 2005-01-19T13:49:32Z

    The following bug has been logged online:
    
    Bug reference:      1412
    Logged by:          Todd Eigenschink
    Email address:      todd@tekinteractive.com
    PostgreSQL version: 8 (any recent)
    Operating system:   Linux
    Description:        binaries are linked to numerous extraneous shared
    Details: 
    
    For a long time, Postgres binaries have been linked to numerous extraneous
    shared libraries.  Since the same command line is used for all tools, it's
    no surprise.
    
    I asked for that to be cleaned up a long time ago and offered a tool to do
    it, but nobody ever took me up on the suggestion.
    
    I wrote a tool that works like this:
    
    ./configure --prefix=$PREFIX
    make
    make install
    relink-postgres $PREFIX
    make install
    
    The relink rebuilds the binaries in the source tree based on what it finds
    in $PREFIX/bin.  It just tries to remove shared libraries and relink until
    it gets down to the minimal set of libs that will permit the link to
    succeed.
    
    This will probably be mangled.  I'll be glad to mail it on request.  Sample
    output:
    
    Relinking src/bin/psql/psql
    Successfully removed: -lz -lcrypt -lresolv -lnsl -ldl -lm
    
    Relinking src/bin/scripts/vacuumdb
    Successfully removed: -lz -lreadline -lncurses -lcrypt -lresolv -lnsl -ldl
    -lm
    
    
    
    #!/bin/sh
    
    minlibs_script=/tmp/minlibs.pl.$$
    dir=$1
    
    ######################################################################
    
    cat <<'EOF' > $minlibs_script
    $| = 1;
    
    my @cmd = @ARGV;
    
    print "Successfully removed:";
    
    while (1)
    {
        my @before_cmd = @cmd;
    
        for (my $i = 1; $i < @cmd; $i++)
        {
            next unless $cmd[$i] =~ /^-l/;
    
            my @tmp = @cmd;
            splice @tmp, $i, 1;
    
            system(join(' ', @tmp, '>/dev/null', '2>&1'));
    
            if ($? == 0)
            {
                # Success.
                print " $cmd[$i]";
                @cmd = @tmp;
                last;
            }
        }
    
        # Bail if no changes were made in this pass.
        last if @cmd == @before_cmd;
    }
    
    if (@cmd == @ARGV)
    {
        print "nothing.\n";
    }
    else
    {
        print "\n";
    }
    
    # Execute it one last time to recreate whatever binary we might have
    killed.
    system(@cmd);
    EOF
    
    ######################################################################
    
    for binary in $dir/bin/*; do
    
        ldd $binary 2>&1 | grep -q 'not a dynamic executable' && continue
    
        file=`basename $binary`
        [ "$file" = "postmaster" ] && continue
    
        path=`find src -type f -name $file`
        bindir=`dirname $path`
    
        echo "Relinking $bindir/$file"
        if [ "$bindir" = "" ]; then
            echo "No directory!"
            exit 1
        fi
    
        rm $path
        gcccmd=`make 2>&1 | grep -- "-o $file"`
        #echo "gcc cmd = " $gcccmd
    
        (cd $bindir && perl $minlibs_script $gcccmd)
    
        echo
    
    done
    
    rm $minlibs_script