summaryrefslogtreecommitdiff
path: root/scripts/macosx-sanity-check.py
diff options
context:
space:
mode:
authorkintel <kintel@b57f626f-c46c-0410-a088-ec61d464b74c>2010-05-07 16:24:22 (GMT)
committerkintel <kintel@b57f626f-c46c-0410-a088-ec61d464b74c>2010-05-07 16:24:22 (GMT)
commit838bb59ead12c77b0e64f4843c9d3be0abbf78b0 (patch)
tree4d7a00b771b340eda2a7ab2610675c56ba8536e8 /scripts/macosx-sanity-check.py
parent2bc4e8b860d5626f66f61cbad4e62d519e0e7a48 (diff)
Added sanity check script
git-svn-id: http://svn.clifford.at/openscad/trunk@528 b57f626f-c46c-0410-a088-ec61d464b74c
Diffstat (limited to 'scripts/macosx-sanity-check.py')
-rwxr-xr-xscripts/macosx-sanity-check.py100
1 files changed, 100 insertions, 0 deletions
diff --git a/scripts/macosx-sanity-check.py b/scripts/macosx-sanity-check.py
new file mode 100755
index 0000000..2438906
--- /dev/null
+++ b/scripts/macosx-sanity-check.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+
+#
+# This is be used to verify that all the dependant libraries of a Mac OS X executable
+# are present and that they are backwards compatible with at least 10.5.
+# Run with an executable as parameter
+#
+
+import sys
+import os
+import subprocess
+import re
+
+DEBUG = False
+
+def usage():
+ print >> sys.stderr, "Usage: " + sys.argv[0] + " <executable>"
+ sys.exit(1)
+
+# Try to find the given library by searching in the typical locations
+# Returns the full path to the library or None if the library is not found.
+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: " + found
+ elif re.search("\.app/", file):
+ found = file
+ if DEBUG: print "App found: " + found
+ elif re.search("\.framework/", file):
+ found = os.path.join("/Library/Frameworks", file)
+ if DEBUG: print "Framework found: " + 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: " + found
+ else:
+ found = file
+ return found
+
+# Returns a list of dependent libraries, excluding system libs
+def find_dependencies(file):
+ libs = []
+
+ p = subprocess.Popen(["otool", "-L", file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ output = p.communicate()[0]
+ if p.returncode != 0: return None
+ deps = output.split('\n')
+ for dep in deps:
+# print dep
+ dep = re.sub(".*:$", "", dep) # Take away header line
+ dep = re.sub("^\t", "", dep) # Remove initial tabs
+ dep = re.sub(" \(.*\)$", "", dep) # Remove trailing parentheses
+ if len(dep) > 0 and not re.search("/System/Library", dep) and not re.search("/usr/lib", dep):
+ libs.append(dep)
+ return libs
+
+def validate_lib(lib):
+ p = subprocess.Popen(["otool", "-l", lib], stdout=subprocess.PIPE)
+ output = p.communicate()[0]
+ if p.returncode != 0: return False
+ if re.search("LC_DYLD_INFO_ONLY", output):
+ print "Error: Requires Snow Leopard: " + lib
+ return False
+ return True
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2: usage()
+ executable = sys.argv[1]
+ if DEBUG: print "Processing " + executable
+ executable_path = os.path.dirname(executable)
+ # processed is a dict {libname : [parents]} - each parent is dependant on libname
+ processed = {}
+ pending = [executable]
+ while len(pending) > 0:
+ dep = pending.pop()
+ if DEBUG: print "Evaluating " + dep
+ deps = find_dependencies(dep)
+ assert(deps)
+ for d in deps:
+ absfile = lookup_library(d)
+ if absfile == None:
+ print "Not found: " + d
+ print " ..required by " + str(processed[dep])
+ continue
+ if absfile in processed:
+ processed[absfile].append(dep)
+ else:
+ processed[absfile] = [dep]
+ if DEBUG: print "Pending: " + absfile
+ pending.append(absfile)
+
+ for dep in processed:
+ if DEBUG: print "Validating: " + dep
+# print " " + str(processed[dep])
+ if not validate_lib(dep):
+ print "..required by " + str(processed[dep])
contact: Jan Huwald // Impressum