Added support for @rpath

This commit is contained in:
Marius Kintel 2015-11-15 02:40:40 -05:00
parent 9a9c7ec31d
commit 7060b25827

View file

@ -31,21 +31,26 @@ def usage():
def lookup_library(file):
found = None
if not re.match("/", file):
if re.search("@executable_path", file):
abs = re.sub("^@executable_path", executable_path, file)
if os.path.exists(abs): found = abs
if DEBUG: print "Lib in @executable_path found: " + str(found)
elif re.search("\.app/", file):
found = file
if DEBUG: print "App found: " + str(found)
elif re.search("\.framework/", file):
found = os.path.join("/Library/Frameworks", file)
if DEBUG: print "Framework found: " + str(found)
else:
for path in os.getenv("DYLD_LIBRARY_PATH").split(':'):
abs = os.path.join(path, file)
if re.search("@rpath", file):
file = re.sub("^@rpath", lc_rpath, file)
if os.path.exists(file): found = file
if DEBUG: print "Lib in @rpath found: " + str(file)
if (not found):
if re.search("@executable_path", file):
abs = re.sub("^@executable_path", executable_path, file)
if os.path.exists(abs): found = abs
if DEBUG: print "Library found: " + str(found)
if DEBUG: print "Lib in @executable_path found: " + str(found)
elif re.search("\.app/", file):
found = file
if DEBUG: print "App found: " + str(found)
elif re.search("\.framework/", file):
found = os.path.join("/Library/Frameworks", file)
if DEBUG: print "Framework found: " + str(found)
else:
for path in os.getenv("DYLD_LIBRARY_PATH").split(':'):
abs = os.path.join(path, file)
if os.path.exists(abs): found = abs
if DEBUG: print "Library found: " + str(found)
else:
found = file
return found
@ -117,6 +122,18 @@ if __name__ == '__main__':
executable = sys.argv[1]
if DEBUG: print "Processing " + executable
executable_path = os.path.dirname(executable)
# Find the Runpath search path (LC_RPATH)
p = subprocess.Popen(["otool", "-l", executable], stdout=subprocess.PIPE)
output = p.communicate()[0]
if p.returncode != 0:
print 'Error otool -l failed on main executable'
sys.exit(1)
# Check deployment target
m = re.search("LC_RPATH\n(.*)\n\s+path ([^ ]+)", output, re.MULTILINE)
lc_rpath = m.group(2)
if DEBUG: print 'Runpath search path: ' + lc_rpath
# processed is a dict {libname : [parents]} - each parent is dependant on libname
processed = {}
pending = [executable]
@ -125,17 +142,18 @@ if __name__ == '__main__':
dep = pending.pop()
if DEBUG: print "Evaluating " + dep
deps = find_dependencies(dep)
# if DEBUG: print "Deps: " + ' '.join(deps)
assert(deps)
for d in deps:
absfile = lookup_library(d)
if not re.match(executable_path, absfile):
print "Error: External dependency " + d
sys.exit(1)
if absfile == None:
print "Not found: " + d
print " ..required by " + str(processed[dep])
error = True
continue
if not re.match(executable_path, absfile):
print "Error: External dependency " + d
sys.exit(1)
if absfile in processed:
processed[absfile].append(dep)
else: