Last active
August 29, 2015 14:02
-
-
Save vitawasalreadytaken/486b0c03dc38f327bef0 to your computer and use it in GitHub Desktop.
Check that the Quickfix Python module is able to find the dynamically linked libraries it requires, and suggest how to fix incorrect paths.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import logging, os, subprocess | |
def checkQuickfixDylibs(soPath): | |
''' | |
Verify that _quickfix.so's required dylibs exist, and suggest how to fix incorrect paths. | |
It is assumed that missing libs (most likely just libquickfix.14.dylib) should be present | |
in the same directory as _quickfix.so. | |
:param soPath: path/to/_quickfix.so (or path/to/libquickfix_python.10.dylib). | |
''' | |
system = subprocess.check_output(('uname', '-s')).strip() | |
if system == 'Darwin': | |
# Mac OS X. Use otool. | |
otool = subprocess.check_output(('otool', '-L', soPath)).strip() | |
# Possible output: | |
# path/to/_quickfix.so: | |
# /tmp/quickfix/prefix/lib/libquickfix_python.10.dylib (compatibility version 11.0.0, current version 11.0.0) | |
# /tmp/quickfix/src/C++/.libs/libquickfix.14.dylib (compatibility version 15.0.0, current version 15.0.0) | |
# /usr/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.9.0) | |
# /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0) | |
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1) | |
libs = [ L.strip().split(' ', 1)[0] for L in otool.split('\n')[1:] ] | |
logging.debug('Quickfix at path = %s requires shared libs = %r.', soPath, libs) | |
for path in libs: | |
if os.path.basename(path) != 'libquickfix_python.10.dylib': | |
# libquickfix_python.10.dylib refers to the Python module itself and can be safely ignored. | |
if not os.path.exists(path): | |
possiblePath = os.path.abspath(os.path.join(os.path.dirname(soPath), os.path.basename(path))) | |
fix = 'install_name_tool -change {missing} {correct} {so}'.format(missing = path, correct = possiblePath, so = soPath) | |
raise RuntimeError('Shared library = {0} does not exist. Run `{1}` to fix the path.'.format(path, fix)) | |
elif system == 'Linux': | |
# Linux. Use ldd. | |
ldd = subprocess.check_output(('ldd', soPath)).strip() | |
# Possible output: | |
# linux-vdso.so.1 => (0x00007fffa8dfe000) | |
# libquickfix.so.14 => not found | |
# libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f74a1bbb000) | |
# libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f74a18b7000) | |
# libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f74a14f1000) | |
# libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f74a12da000) | |
# /lib64/ld-linux-x86-64.so.2 (0x00007f74a296e000) | |
# libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f74a0fd4000) | |
lines = [ L.strip() for L in ldd.split('\n') ] | |
logging.debug('Quickfix at path = %s requires shared libs = %r.', soPath, lines) | |
for line in lines: | |
if '=>' in line: | |
name, details = line.split(' => ') | |
if details == 'not found': | |
possibleRpath = os.path.abspath(os.path.join(os.path.dirname(soPath))) | |
fix = 'patchelf --set-rpath {rpath} {so}'.format(rpath = possibleRpath, so = soPath) | |
raise RuntimeError('Shared library = {0} does not exist. Run `{1}` to fix the rpath (http://nixos.org/patchelf.html).'.format(name, fix)) | |
else: | |
raise RuntimeError('Unknown operating system: {}'.format(system)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment