85 lines
2.4 KiB
Python
85 lines
2.4 KiB
Python
|
#!/usr/bin/env python
|
||
|
import sysconfig
|
||
|
import subprocess
|
||
|
import json
|
||
|
import os
|
||
|
import sys
|
||
|
|
||
|
os.chdir(os.path.dirname(__file__))
|
||
|
|
||
|
so_files = [
|
||
|
sysconfig.get_config_var("LIBDIR")+"/"+sysconfig.get_config_var("LDLIBRARY"),
|
||
|
sysconfig.get_config_var("LIBPL")+"/"+sysconfig.get_config_var("LDLIBRARY")
|
||
|
]
|
||
|
so_file = None
|
||
|
for name in so_files:
|
||
|
if os.path.isfile(name):
|
||
|
so_file = name
|
||
|
if not so_file:
|
||
|
print('Could not find %r' % so_files)
|
||
|
sys.exit(1)
|
||
|
|
||
|
so_symbols = set()
|
||
|
for line in subprocess.check_output(['readelf', '-Ws', so_file]).splitlines():
|
||
|
if line:
|
||
|
so_symbols.add(line.decode('utf-8').split()[-1])
|
||
|
|
||
|
assert 'PyList_Type' in so_symbols
|
||
|
assert 'PyList_New' in so_symbols
|
||
|
|
||
|
cfgs = []
|
||
|
if sys.version_info.major == 3:
|
||
|
sys_lib = 'python3-sys'
|
||
|
for i in range(4, sys.version_info.minor+1):
|
||
|
cfgs += ['--cfg', 'Py_3_{}'.format(i)]
|
||
|
else:
|
||
|
sys_lib = 'python27-sys'
|
||
|
|
||
|
interesting_config_flags = [
|
||
|
"Py_USING_UNICODE",
|
||
|
"Py_UNICODE_WIDE",
|
||
|
"WITH_THREAD",
|
||
|
"Py_DEBUG",
|
||
|
"Py_REF_DEBUG",
|
||
|
"Py_TRACE_REFS",
|
||
|
"COUNT_ALLOCS"
|
||
|
]
|
||
|
for name in interesting_config_flags:
|
||
|
if sysconfig.get_config_var(name):
|
||
|
cfgs += ['--cfg', 'py_sys_config="{}"'.format(name)]
|
||
|
interesting_config_values = ['Py_UNICODE_SIZE']
|
||
|
for name in interesting_config_values:
|
||
|
cfgs += ['--cfg', 'py_sys_config="{}_{}"'.format(name, sysconfig.get_config_var(name))]
|
||
|
|
||
|
|
||
|
json_output = subprocess.check_output(['rustc', '-Z', 'ast-json', '../{}/src/lib.rs'.format(sys_lib)] + cfgs)
|
||
|
doc = json.loads(json_output.decode('utf-8'))
|
||
|
foreign_symbols = set()
|
||
|
def visit(node):
|
||
|
if isinstance(node, dict):
|
||
|
node_node = node.get('node', None)
|
||
|
if isinstance(node_node, dict) and node_node.get('variant') in ('ForeignItemStatic', 'ForeignItemFn'):
|
||
|
foreign_symbols.add(node['ident'])
|
||
|
for v in node.values():
|
||
|
visit(v)
|
||
|
elif isinstance(node, list):
|
||
|
for v in node:
|
||
|
visit(v)
|
||
|
elif isinstance(node, (int, type(u''), bool, type(None))):
|
||
|
pass
|
||
|
else:
|
||
|
raise Exception('Unsupported node type {}'.format(type(node)))
|
||
|
visit(doc)
|
||
|
|
||
|
assert 'PyList_Type' in foreign_symbols
|
||
|
assert 'PyList_New' in foreign_symbols
|
||
|
|
||
|
names = sorted(foreign_symbols - so_symbols)
|
||
|
if names:
|
||
|
print('Symbols missing in {}:'.format(so_file))
|
||
|
print('\n'.join(names))
|
||
|
sys.exit(1)
|
||
|
else:
|
||
|
print('Symbols in {} OK.'.format(so_file))
|
||
|
|