1#!/usr/bin/env python3 2 3# Usage: 4# taucc -cc=g++ -pdt_parse=/../cxxparse -tau_lib_dir=/.../lib COMPILE_OPTIONS 5# 6# Options: 7# -cc : C/C++ compiler 8# -pdt_parse : pdtoolkit parser for C++ 9# -tau_lib_dir : TAU library dir 10# -v,-verbose : verbose mode - shows the exact commands invoked 11# -leave_tmp : do not delete temporary files 12# -E : run preprocessor only 13# 14import commands 15import sys 16import os 17import tempfile 18def runcmd(cmd,verbose): 19 if verbose: 20 print(cmd) 21 (status, output) = commands.getstatusoutput(cmd) 22 if status: 23 raise RuntimeError('Unable to run '+cmd+':\n'+output) 24 elif output: 25 print(output) 26 27def getTauFlags(tau_lib_dir): 28 fd,name=tempfile.mkstemp(prefix='taucc-') 29 try: 30 tau_makefile = str(os.path.join(tau_lib_dir, os.path.basename(os.environ['TAU_MAKEFILE']))) 31 except: 32 tau_makefile = str(os.path.join(tau_lib_dir, 'Makefile.tau-mpi-pdt')) 33 buf = 'include ' + tau_makefile 34 buf += ''' 35tauflags: 36 -@echo TAU_INSTRUMENT0R:${TAU_PREFIX_INSTALL_DIR}/${CONFIG_ARCH}/bin/tau_instrumentor 37 -@echo TAU_DEFS:${TAU_DEFS} 38 -@echo TAU_INCLUDE:${TAU_INCLUDE} 39 -@echo TAU_LIBS:${TAU_LIBS} 40 -@echo TAU_MPI_INC:${TAU_MPI_INC} 41 -@echo TAU_MPI_LIBS:${TAU_MPI_LIBS} 42 -@echo TAU_CXXLIBS:${TAU_CXXLIBS} 43''' 44 os.write(fd,buf) 45 os.close(fd) 46 cmd = 'make -f '+ name + ' tauflags' 47 (status, output) = commands.getstatusoutput(cmd) 48 if status: 49 os.remove(name) 50 raise RuntimeError('Unable to run '+cmd+':\n'+output) 51 os.remove(name) 52 # remove unnecessary stuff from output 53 tau_defs ='' 54 tau_include='' 55 tau_libs='' 56 tau_mpi_libs='' 57 for line in output.splitlines(): 58 if line.find('TAU_INSTRUMENT0R:') >= 0: tau_instr = line.replace('TAU_INSTRUMENT0R:','') 59 elif line.find('TAU_DEFS:') >= 0: tau_defs = line.replace('TAU_DEFS:',' ') 60 elif line.find('TAU_INCLUDE:') >= 0: tau_include = line.replace('TAU_INCLUDE:',' ') 61 elif line.find('TAU_LIBS:') >= 0: tau_libs = line.replace('TAU_LIBS:',' ') 62 elif line.find('TAU_MPI_INC:') >= 0: tau_mpi_inc = line.replace('TAU_MPI_INC:',' ') 63 elif line.find('TAU_MPI_LIBS:') >= 0: tau_mpi_libs = line.replace('TAU_MPI_LIBS:',' ') 64 elif line.find('TAU_CXXLIBS:') >= 0: tau_cxxlibs = line.replace('TAU_CXXLIBS:',' ') 65 return tau_instr,tau_defs,tau_include,tau_libs,tau_mpi_inc,tau_mpi_libs,tau_cxxlibs 66 67def main(): 68 69 sourcefiles=[] 70 objfiles=[] 71 libfiles=[] 72 arglist='' 73 pdt_parse='cxxparse' 74 iscparse=0 75 tau_instr='tau_instrumentor' 76 cc='gcc' 77 verbose=0 78 compileonly=0 79 leave_tmp = 0 80 81 for arg in sys.argv[1:]: 82 filename,ext = os.path.splitext(arg) 83 argsplit = arg.split('=') 84 #look for sourcefiles, validate & add to a list 85 if ext == '.c' or ext == '.cc' or ext == '.cpp' or ext == '.cxx' or ext == '.C': 86 if os.path.isfile(arg): 87 sourcefiles.append(arg) 88 elif argsplit[0] == '-cc': 89 cc = argsplit[1] 90 elif argsplit[0] == '-pdt_parse': 91 pdt_parse = argsplit[1] 92 if pdt_parse.find('cparse') >=0: iscparse = 1 93 elif pdt_parse.find('cxxparse') >=0: iscparse = 0 94 else: sys.exit('Error: Unknown parser - use either cparse or cxxparse: '+pdt_parse) 95 elif arg == '-c': 96 compileonly = 1 97 elif arg == '-E': 98 compileonly = 1 99 arglist += ' '+arg 100 elif arg == '-leave_tmp': 101 leave_tmp = 1 102 elif argsplit[0] == '-tau_lib_dir': 103 tau_lib_dir = argsplit[1] 104 elif arg.startswith('-L') or arg.startswith('-l'): 105 libfiles.append(arg) 106 elif arg == '-v' or arg == '-verbose': 107 verbose = 1 108 arglist += ' '+arg 109 else: 110 # Now make sure quotes are escaped properly 111 # Group the rest of the arguments into a different list 112 arg=arg.replace('"','\\"') 113 arglist += ' '+arg 114 115 # error if sourcefiles not specified with -c 116 if sourcefiles == [] and compileonly: 117 sys.exit('Error: no sourcefiles specified with -c') 118 # obtain TAU info from TAU makefile 119 tau_instr,tau_defs,tau_include,tau_libs,tau_mpi_inc,tau_mpi_libs,tau_cxxlibs = getTauFlags(tau_lib_dir) 120 if sourcefiles != []: 121 # Now Compile the sourcefiles 122 for sourcefile in sourcefiles: 123 root,ext = os.path.splitext(sourcefile) 124 obj_file = root + '.o' 125 objfiles.append(obj_file) # for use later at linktime 126 if iscparse: 127 if ext == '.c': pdt_file = root+ '.pdb' 128 else: pdt_file = sourcefile+ '.pdb' 129 else: 130 if ext == '.cc' or ext == '.cpp' or ext == '.cxx' or ext == '.C' : pdt_file = root+ '.pdb' 131 else: pdt_file = sourcefile+ '.pdb' 132 tau_file = root +'.inst' + ext 133 cmd1 = pdt_parse + ' ' + sourcefile + arglist + tau_defs + tau_include + tau_mpi_inc 134 135 cmd2 = tau_instr + ' ' + pdt_file + ' ' + sourcefile +' -o '+ tau_file 136 cmd2 += ' -c -rn PetscFunctionReturn -rv PetscFunctionReturnVoid\\(\\)' 137 cmd3 = cc + ' -c ' + tau_file + ' -o ' + obj_file + arglist + tau_defs + tau_include +tau_mpi_inc 138 139 140 runcmd(cmd1,verbose) 141 runcmd(cmd2,verbose) 142 if not leave_tmp: os.remove(pdt_file) 143 runcmd(cmd3,verbose) 144 if not leave_tmp: os.remove(tau_file) 145 146 if not compileonly: 147 objarg='' 148 for objfile in objfiles: 149 objarg += ' ' + objfile 150 libarg='' 151 for libfile in libfiles: 152 libarg += ' '+libfile 153 cmd1 = cc + ' ' + objarg +' ' + arglist + libarg + tau_mpi_libs + tau_libs + tau_cxxlibs 154 runcmd(cmd1,verbose) 155 if not leave_tmp: # delete the objfiles created 156 for objfile in objfiles: 157 os.remove(objfile) 158 159if __name__ == '__main__': 160 try: 161 main() 162 except Exception as e: 163 sys.exit('ERROR: '+str(e)) 164