seafile-client/scripts/build_helper.py

108 lines
3.7 KiB
Python
Executable file

#!/usr/bin/env python
import subprocess, sys, os
import re
from multiprocessing import cpu_count
num_cpus=cpu_count()
def get_dependencies_by_otool(path):
if path.endswith('.app') and os.path.isdir(path):
path = os.path.join(path, 'Contents', 'MacOS', os.path.basename(path))
lines = check_string_output(['otool', '-L', path]).split('\n')[1:]
outputs = [path]
for line in lines:
name = line.split('(')[0].strip()
if name.startswith('@executable_path/'):
name = os.path.join(path, name[len('@executable_path/'):])
if name.startswith('@loader_path/'):
name = os.path.join(path, name[len('@loader_path/'):])
# todo: search rpath
if not name.startswith('/'):
continue
# skip system libraries
if name.startswith('/usr/lib') or name.startswith('/System'):
continue
# skip Frameworks (TODO: support frameworks)
if re.search(r'(\w+)\.framework/Versions/[A-Z]/(\1)$', name):
continue
# if file not found
if not os.path.exists(name):
raise IOError('broken dependency: file %s not found' % name)
outputs.append(os.path.normpath(name))
return outputs
def get_dependencies_by_ldd(path):
lines = check_string_output(['ldd', '-v', path]).split('Version information:')[1].split('\n\t')
outputs = []
for line in lines:
if not line.startswith('\t'):
continue
name = line.strip().split('=>')[1].strip()
# todo: search rpath
if name.startswith('$ORIGIN/'):
name = os.path.join(path, name[len('$ORIGIN/'):])
# skip system libraries, such as linux-vdso.so
if not name.startswith('/'):
continue
# skip system libraries, part2
if name.startswith('/usr/lib') or name.startswith('/usr/lib64'):
continue
# skip system libraries, part3
if name.startswith('/lib') or name.startswith('/lib64'):
continue
# if file not found
if not os.path.exists(name):
raise IOError('broken dependency: file %s not found' % name)
outputs.append(os.path.normpath(name))
# remove duplicate items
return list(set(outputs))
def get_dependencies_by_objdump(path):
print 'todo'
return []
def get_dependencies_by_dependency_walker(path):
print 'todo'
return []
def get_dependencies(path):
if os.name == 'winnt':
return get_dependencies_by_objdump(path)
elif sys.platform == 'darwin':
return get_dependencies_by_otool(path)
elif sys.platform == 'linux':
return get_dependencies_by_ldd(path)
else:
raise IOError('not supported in platform %s' % sys.platform)
def get_dependencies_recursively(path):
if os.name == 'winnt':
return get_dependencies_by_objdump(path)
elif sys.platform == 'darwin':
deps = get_dependencies_by_otool(path)
while(True):
deps_extened = list(deps)
for dep in deps:
deps_extened.extend(get_dependencies_by_otool(dep))
deps_extened = set(deps_extened)
if deps_extened != deps:
deps = deps_extened;
else:
return list(deps_extened)
elif sys.platform == 'linux':
return get_dependencies_by_ldd(path)
else:
raise IOError('not supported in platform %s' % sys.platform)
def check_string_output(command):
return subprocess.check_output(command).decode().strip()
if __name__ == '__main__':
if (len(sys.argv) < 2):
print 'Usage: %s <input-file>' % sys.argv[0]
sys.exit(-1)
print get_dependencies_recursively(sys.argv[1])