darshan-gen-cc.pl.in 5.79 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
#!/usr/bin/perl -w
#
#  (C) 2009 by Argonne National Laboratory.
#      See COPYRIGHT in top-level directory.
#

# takes a standard mpicc script as an argument and tried to generate a
# darshan-enabled mpicc script to mimic it's behavior

use Getopt::Long;
use English;

13 14 15 16
$CP_WRAPPERS="@CP_WRAPPERS@";
$DARSHAN_LIB_PATH="@darshan_lib_path@";
$CP_ZLIB_LINK_FLAGS="@__CP_ZLIB_LINK_FLAGS@";

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
my $input_file = "";
my $output_file = "";

process_args();

# run original mpicc with -show argument to capture command line for
# compilation and linking
my $compile_cmd = `$input_file -show -c foo.c`;
if (!($compile_cmd))
{
    printf STDERR "Error: failed to invoke $input_file with -show\n";
    exit(1);
}

my $link_cmd = `$input_file -show foo.o -o foo`;
if (!($link_cmd))
{
    printf STDERR "Error: failed to invoke $input_file with -show\n";
    exit(1);
}

# check command lines for accuracy
if(!($compile_cmd =~ /-c foo.c/) || !($link_cmd =~ /foo.o -o foo/))
{
    printf STDERR "Error: faulty output from $input_file with -show.\n";
    exit(1);
}
44 45
chomp($compile_cmd);
chomp($link_cmd);
46 47 48

open (OUTPUT, ">$output_file") || die("Error opening output file: $!");

49
# substitute arguments and darshan options into commands
50 51
$base_link_cmd = $link_cmd;
$base_link_cmd =~ s/foo.o -o foo/"\$\{allargs\[\@\]\}"/g;
52
$link_cmd =~ s/foo.o -o foo/"\$\{newallargs\[\@\]\}" -L$DARSHAN_LIB_PATH $CP_ZLIB_LINK_FLAGS -ldarshan-mpi-io -lz $CP_WRAPPERS/g;
53
$link_cmd =~ s/$/ -L$DARSHAN_LIB_PATH -ldarshan-posix/g;
54
$compile_cmd =~ s/-c foo.c/"\$\{allargs\[\@\]\}"/g;
55

56 57 58 59
# create link cmd with noshrargs variable
$link_cmd_no_shared = $base_link_cmd;
$link_cmd_no_shared =~ s/allargs/noshrargs/;

Philip Carns's avatar
Philip Carns committed
60
print OUTPUT<<'EOF';
Philip Carns's avatar
Philip Carns committed
61
#!/bin/bash
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
#
# Auto-generated mpicc script from darshan-gen-cc.pl
#
#
# Internal variables
# Show is set to echo to cause the compilation command to be echoed instead 
# of executed.
Show=

linking=yes
allargs=("$@")
argno=0
for arg in "$@" ; do
    # Set addarg to no if this arg should be ignored by the C compiler
    addarg=yes
    case "$arg" in 
 	# ----------------------------------------------------------------
	# Compiler options that affect whether we are linking or no
    -c|-S|-E|-M|-MM)
    # The compiler links by default
    linking=no
    ;;
    -show)
    addarg=no
    Show=echo
    ;;
    esac
    if [ $addarg = no ] ; then
	unset allargs[$argno]
    fi
    # Some versions of bash do not accept ((argno++))
    argno=`expr $argno + 1`
done
if [ "$linking" = yes ] ; then
    if [ -n "$C_LINKPATH_SHL" ] ; then
	# prepend the path for the shared libraries to the library list
	mpilibs="$C_LINKPATH_SHL$libdir $mpilibs"
    fi
100
EOF
Philip Carns's avatar
Philip Carns committed
101
print OUTPUT<<"EOF";
102 103 104 105 106 107 108 109
    # Trial run to generate a symbol listing.  We only enable Darshan if:
    # a) MPI is used
    # b) PMPI is _not_ used
    #
    # We want Darshan to get out of the way if the user is doing a runtime
    # test in configure (in which case MPI objects break the executable) or
    # if the user is using another PMPI based tool

110 111
    # if allargs includes any libraries, then we need to get 
    # -ldarshan-mpi-io in there first
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
    argno=0;
    once=0;
    newallargs=\("\$\{allargs\[\@\]\}"\);
    for arg in "\$\{newallargs\[\@\]\}"; do
        res=`expr match "\$arg" "^-l"`;
        if [ \$res -gt 0 -a \$once -lt 1 ]; then
            newallargs[\$argno]=-ldarshan-mpi-io
            argno=`expr \$argno + 1`
            newallargs[\$argno]=\$arg;
            once=1;
        else
            newallargs[\$argno]=\$arg;
        fi
        argno=`expr \$argno + 1`
    done
127

128 129 130 131 132 133
    used_darshan=0

    # create a temporary file
    tmpfile=`mktemp`
    # generate a map of the symbol names
    # don't use -shared for this step
134 135 136 137 138 139 140 141 142 143
    argno=0
    noshrargs=\("\$\{allargs\[\@\]\}");
    for arg in "\$\{noshrargs\[\@\]\}"; do
        if [ "\$arg" = "-shared" ]; then
            unset noshrarg[\$argno];
        fi
        argno=`expr \$argno + 1`
    done
    $link_cmd_no_shared -Wl,-Map,\$tmpfile \$LDFLAGS -o /dev/null >& /dev/null

144 145 146
    # is MPI in there?
    grep MPI \$tmpfile >& /dev/null
    rc_mpi=\$?
147 148
    # is PMPI being used for any init, finalize, or mpi-io calls?
    grep -E \\(PMPI_File_\\)\\|\\(PMPI_Init\\)\\|\\(PMPI_Finalize\\) \$tmpfile | grep -v -E \\(mpich.cnk.a\\|mpich.a\\) |grep \\(PMPI >& /dev/null
149 150 151 152 153 154 155 156 157
    rc_pmpi=\$?
    rm \$tmpfile >& /dev/null

    # disable darshan if the executable is not an MPI program (this feature
    # mainly allows runtime configure tests to work
    if [ \$rc_mpi -eq 0 ] ; then
        # disable darshan if something else is already using PMPI; we don't
        # want to cause any symbol conflicts
        if [ \$rc_pmpi -ne 0 ] ; then
Philip Carns's avatar
Philip Carns committed
158
            \$Show $link_cmd
159 160 161 162 163 164
            used_darshan=1
        fi
    fi

    # otherwise use the normal command line
    if [ "\$used_darshan" = "0" ] ; then
Philip Carns's avatar
Philip Carns committed
165
        \$Show $base_link_cmd
166 167
    fi
    rc=\$?
168
else
169 170
    \$Show $compile_cmd
    rc=\$?
171 172
fi

173
exit \$rc
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
EOF

close(OUTPUT);

chmod(0755, $output_file); 

exit(0);

sub process_args
{
    use vars qw( $opt_help $opt_output );

    Getopt::Long::Configure("no_ignore_case", "bundling");
    GetOptions( "help",
        "output=s");

    if($opt_help)
    {
        print_help();
        exit(0);
    }

    if($opt_output)
    {
        $output_file = $opt_output;
    }
    else
    {
        print_help();
        exit(1);
    }

    # there should only be one remaining argument: the input file 
    if($#ARGV != 0)
    {
        print "Error: invalid arguments.\n";
        print_help();
        exit(1);
    }
    $input_file = $ARGV[0];

    return;
}

sub print_help
{
Philip Carns's avatar
Philip Carns committed
220
    print<<"EOF";
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235

Usage: $PROGRAM_NAME <stock mpicc> --output <modified mpicc>

    --help          Prints this help message
    --output        Specifies name of output script

Purpose:

    This script takes an existing mpicc script as input and generates a
    modified version that includes Darshan support.

EOF
    return;
}