Mercurial > hg > mxe-octave-anirudha
changeset 3214:0e32c67b78ca
[Darwin] Python script for fixing "dyld: Library not loaded" errors
author | Anirudha Bose <ani07nov@gmail.com> |
---|---|
date | Sat, 21 Sep 2013 16:28:11 +0530 |
parents | a4692f0e6932 |
children | d1fb703f2cd0 |
files | darwin_files/standalone.py |
diffstat | 1 files changed, 62 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/darwin_files/standalone.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +## +## This Python script can be used to rewrite dylib references in Mach-O headers +## and resolve the dynamic shared library install names which originally point +## to the libraries in MXE $(HOST_LIBDIR). +## +## Requirements: +## * Python 2.7 +## * Macholib (pip install http://pypi.python.org/pypi/macholib) +## +## Usage: +## * python -mmacholib find [path to Resources directory of .app] | python standalone.py +## +## Example: +## * python -mmacholib find ./Octave-3.7.5.app/Contents/Resources/ | python standalone.py +## +## Important Notes: +## * Octave should be compiled with the option -headerpad_max_install_names in the LDFLAGS. +## * The script must be executed as root, if Octave was compiled with root permissions. +## * Before applying this script, make sure the bin and lib directory is present inside the +## Resources folder. +## * Shared libraries like libcholmod.so, libumfpack.so, and others which end with .so +## extension are not assigned any path in the Mach-O headers during compilation. This is +## likely to happen while using MXE. This script can fix such errors too, but make sure +## you do not use this script on the same App Bundle more than once. + +__author__ = "Anirudha Bose" +__email__ = "ani07nov@gmail.com" + +from __future__ import print_function + +import os +import sys + +from macholib.MachO import MachO + +def dylibs_fix(path): + print(path) + m = MachO(path) + for header in m.headers: + seen = set() + for idx, name, other in header.walkRelocatables(): + if other not in seen: + seen.add(other) + relative_name = other[other.find("lib"):] + if other.startswith("/Users"): + command = 'install_name_tool -change "%s" "@executable_path/../%s" ./%s\n'%(other,relative_name,path) + print(command) + os.system(command) + elif other.endswith(".so"): + command = 'install_name_tool -change "%s" "@executable_path/../lib/%s" ./%s\n'%(other,other,path) + print(command) + os.system(command) +def main(): + for path in sys.stdin: + dylibs_fix(path) + +if __name__ == '__main__': + try: + sys.exit(main()) + except KeyboardInterrupt: + pass