forked from NCAR/ccpp-physics
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pgifix.py
executable file
·93 lines (83 loc) · 3.1 KB
/
pgifix.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
#!/usr/bin/env python
import argparse
import os
import subprocess
import sys
parser = argparse.ArgumentParser(description='Fix cap objects produced by PGI compiler')
parser.add_argument("--cmake", default=False, action='store_true')
parser.add_argument("caps", nargs='+')
FIXCMD_TEMPLATE = 'objcopy '
def parse_args():
args = parser.parse_args()
cmake = args.cmake
caps = args.caps
return (cmake, caps)
def execute(cmd, debug = True, abort = True):
"""Runs a local command in a shell. Waits for completion and
returns status, stdout and stderr. If abort = True, abort in
case an error occurs during the execution of the command."""
if debug:
print 'Executing "{0}"'.format(cmd)
p = subprocess.Popen(cmd, stdout = subprocess.PIPE,
stderr = subprocess.PIPE, shell = True)
(stdout, stderr) = p.communicate()
status = p.returncode
if debug:
message = 'Execution of "{0}" returned with exit code {1}\n'.format(cmd, status)
message += ' stdout: "{0}"\n'.format(stdout.rstrip('\n'))
message += ' stderr: "{0}"'.format(stderr.rstrip('\n'))
print message
if not status == 0:
message = 'Execution of command {0} failed, exit code {1}\n'.format(cmd, status)
message += ' stdout: "{0}"\n'.format(stdout.rstrip('\n'))
message += ' stderr: "{0}"'.format(stderr.rstrip('\n'))
if abort:
raise Exception(message)
else:
print message
return (status, stdout.rstrip('\n'), stderr.rstrip('\n'))
def correct_cap_object_names(fixcmd, cmake, cap):
(cappath, capname) = os.path.split(cap)
# Determine pgi-prepended prefix to remove, different
# for cmake builds and make builds (object filename)
if cmake:
pgiprefix = capname.rstrip('.F90.o').lower() + '_'
else:
pgiprefix = capname.rstrip('.o').lower() + '_'
# Get list of all symbols in cap object
nmcmd = 'nm {0}'.format(cap)
(status, stdout, stderr) = execute(nmcmd)
del nmcmd
# Parse all symbols and generate objcopy command
found = False
for line in stdout.split('\n'):
try:
(address, symboltype, objectname) = line.split()
except ValueError:
continue
if not symboltype == 'T':
continue
if objectname.startswith(pgiprefix):
newname = objectname[len(pgiprefix):]
else:
continue
if newname.endswith('_cap'):
fixcmd += '--redefine-sym {0}={1} '.format(objectname, newname)
found = True
if not found:
raise Exception('Unable to rename CCPP scheme caps in cap "{0}"'.format(cap))
return fixcmd
def correct_object_names(fixcmd, cap):
tmp = cap + '.tmp'
fixcmd += '{0} {1}'.format(cap, tmp)
execute(fixcmd)
mvcmd = 'mv -v {0} {1}'.format(tmp, cap)
execute(mvcmd)
def main():
(cmake, caps) = parse_args()
for cap in caps:
fixcmd = FIXCMD_TEMPLATE
fixcmd = correct_cap_object_names(fixcmd, cmake, cap)
correct_object_names(fixcmd, cap)
if __name__ == '__main__':
main()