#! /usr/bin/env perl # # (C) 2014 by Argonne National Laboratory. # See COPYRIGHT in top-level directory. # use warnings; use strict; # Check to make sure the file was passed in as a parameter if ($#ARGV != 0) { print "Usage: buildiface <filename>\n"; exit 1; } open(FD, $ARGV[0]) || die "Could not open file " . $ARGV[0]; while (<FD>) { if (/\/\*\s*Begin Prototypes/) { last; } } my $eol = 1; my $fullline = ""; my $tab = " "; my $retarg; my $routine; my $args; my @arglist; my $fname; my $cdesc_routine; my $x; my $y; my @argbits; my $num_dtypes; my @dtype_bind; my $io_header; my $make_exists = 0; open(OUTFD, ">all_romio_symbols.c") || die "Could not open file all_romio_symbols.c"; print OUTFD <<EOT; /* -*- Mode: C; c-basic-offset:4 ; -*- */ /* * (C) 2014 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. * * This file is automatically generated by buildiface * DO NOT EDIT */ /* * This file is created for the sole purpose of referencing all the symbols * in ROMIO. * * All ROMIO public symbols are being added into the libromio convenience * library, which is LIBADD'ed into libmpi. The correct behavior would * be for libtool to add -Wl,--whole-archive to the link line, thus * forcing all symbols in libromio to end up in libmpi. However, in some * cases, this is not working out correctly. For example, with the * Absoft compiler, the linker flags were being reordered thus causing * the -Wl,--whole-archive flag to not correspond to libromio. * Consequently, only symbols that were used from within the other * functions of libmpi were being included. * * In the past, we got lucky in two ways: * * 1. We were including all the Fortran 77 symbols into libmpi. Since * the Fortran symbols were calling the C ROMIO symbols, those ROMIO * symbols were pulled in even without -Wl,--whole-archive. * * 2. The problem only showed up with absoft and nag, both of which are * Fortran-only compilers. If a C compiler has this issue, it should * have shown up when Fortran support is disabled. */ #include <stdio.h> #include "mpi.h" void MPIR_All_romio_symbols(void); void MPIR_All_romio_symbols(void) { #ifdef MPI_MODE_RDONLY EOT while (<FD>) { if (/\/\*\s*End Prototypes/) { last; } if (/\/\*\s*Begin Skip Prototypes/) { while (<FD>) { if (/\/\*\s*End Skip Prototypes/) { last; } } } # If we found a semi-colon at the end, that's the end of the line. # This is not perfect (e.g., does not work when a single line has # multiple semi-colon separated statements), but should be good # enough for the MPICH mpi.h file if (/.*;/) { $eol = 1; } else { $eol = 0; } chomp($_); $fullline .= "$_"; if ($eol == 0) { next; } # We got the entire prototype in a single line # parse out comments $fullline =~ s+/\*.*\*/++g; # parse out attributes $fullline =~ s/MPICH_ATTR_POINTER_WITH_TYPE_TAG\(.*\)//g; # cleanup pointer format $fullline =~ s/\s*\*/* /g; # parse out unnecessary spaces $fullline =~ s/^\s*//g; $fullline =~ s/\s*$//g; $fullline =~ s/\s*;/;/g; $fullline =~ s/\s\s*/ /g; # split the line into the return type, routine name, and arguments $fullline =~ m/([^ ]*) ([^(]*)\((.*)\)/; $retarg = $1; $routine = $2; $args = $3; # cleanup args $args =~ s/^\s*//g; $args =~ s/\s*$//g; @arglist = split(/,/, $args); for ($x = 0; $x <= $#arglist; $x++) { $arglist[$x] =~ s/^\s*//g; $arglist[$x] =~ s/\s*$//g; } print OUTFD "${tab}{\n"; for ($x = 0; $x <= $#arglist; $x++) { print OUTFD "${tab}${tab}$arglist[$x]"; if ($arglist[$x] =~ /\*/) { print OUTFD " = NULL;\n"; } elsif ($arglist[$x] =~ /MPI_Comm/) { print OUTFD " = MPI_COMM_NULL;\n"; } elsif ($arglist[$x] =~ /MPI_Info/) { print OUTFD " = MPI_INFO_NULL;\n"; } elsif ($arglist[$x] =~ /MPI_File/) { print OUTFD " = MPI_FILE_NULL;\n"; } elsif ($arglist[$x] =~ /MPI_Datatype/) { print OUTFD " = MPI_DATATYPE_NULL;\n"; } elsif ($arglist[$x] =~ /MPI_Errhandler/) { print OUTFD " = MPI_ERRHANDLER_NULL;\n"; } elsif ($arglist[$x] =~ /MPI_Offset/) { print OUTFD " = 0;\n"; } elsif ($arglist[$x] =~ /int/) { print OUTFD " = 0;\n"; } else { print "$arglist[$x]\n"; print OUTFD ";\n"; } } print OUTFD "\n${tab}${tab}$routine("; for ($x = 0; $x <= $#arglist; $x++) { @argbits = split(/ /, $arglist[$x]); if ($x < $#arglist) { print OUTFD "$argbits[$#argbits], "; } else { print OUTFD "$argbits[$#argbits]);\n"; } } print OUTFD "${tab}}\n\n"; $fullline = ""; } # A few symbols are not in mpio.h print OUTFD <<EOT; { MPI_Fint fh = 0; MPI_File_f2c(fh); } { MPI_File fh = MPI_FILE_NULL; MPI_File_c2f(fh); } #endif /* MPI_MODE_RDONLY */ } EOT close FD; close OUTFD;