]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Added new relocate target and script.
authorLuca Heltai <luca.heltai@sissa.it>
Fri, 11 Mar 2016 16:22:58 +0000 (17:22 +0100)
committerLuca Heltai <luca.heltai@sissa.it>
Mon, 14 Mar 2016 08:55:05 +0000 (09:55 +0100)
cmake/setup_custom_targets.cmake
contrib/utilities/relocate_libraries.py [new file with mode: 0755]

index 41f8ed38e129b597f41922b0719f02546b5056bd..e3782000caf933425abd5985358435b7e8870b0d 100644 (file)
@@ -99,6 +99,19 @@ ADD_CUSTOM_TARGET(indent
   COMMENT "Indenting all files in the deal.II directories"
   )
 
+#
+# Provide "relocate" target to run install_name_tool on all external libraries
+# under ${DEAL_II_CPACK_EXTERNAL_LIBS_TREE}
+#
+IF(CMAKE_SYSTEM_NAME MATCHES "Darwin" AND 
+  NOT "${DEAL_II_CPACK_EXTERNAL_LIBS_TREE}" STREQUAL "")
+  ADD_CUSTOM_TARGET(relocate
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+    COMMAND ./contrib/utilities/relocate_libraries.py
+    COMMENT "Running install_name_tool under ${DEAL_II_CPACK_EXTERNAL_LIBS_TREE}"
+    )
+ENDIF()
+
 
 #
 # Provide an "info" target to print a help message:
@@ -140,6 +153,9 @@ FILE(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/print_info.cmake
 #
 #    indent         - indent all headers and source file
 #
+#    relocate       - (only available on Darwin machines) fix RPATH for external 
+#                     libraries, if packaging was requested
+#
 ###\")"
   )
 
diff --git a/contrib/utilities/relocate_libraries.py b/contrib/utilities/relocate_libraries.py
new file mode 100755 (executable)
index 0000000..4f1bab6
--- /dev/null
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+
+# This script runs install_name_tool on each library under basedir (first argument
+# on command line) and makes sure that all libraries are installed with absolute
+# id name. This makes Mac OS X happy about not using DYLD_LIBRARY_PATH, which is generally
+# a bad thing. 
+
+import os
+import sys
+from subprocess import check_output as run
+
+basedir = '/Applications/deal.II.app/Contents/Resources/opt/'
+if len(sys.argv) > 1:
+    basedir = sys.argv[1]
+
+## Lib object
+# 
+# Stores the name of a library, its install name, its location and all its dependencies, as given by `otool -L`
+
+class Lib(object):
+    location = None
+    install_name = None
+    name = None
+    deps = None
+    def __str__(self):
+        mystr = ""
+        mystr +=  "Name        :"+str(self.name)
+        mystr +="\nInstall name:"+str(self.install_name)
+        mystr +="\nLocation    :"+str(self.location)
+        mystr +="\nDeps        : ... "
+        return mystr
+
+# Walk the current tree, and extract all libraries
+def get_libs():
+    libraries = []
+
+    for root, dirs, files in os.walk(basedir):
+        for f in files:
+            filename = os.path.join(root, f)
+            if os.path.isfile(filename) and f.endswith("dylib"):
+                a = Lib()
+                a.name = f
+                a.install_name = run(["otool", "-D", filename]).split('\n')[1]
+                a.location= os.path.join(root, f)
+                long_deps = run(["otool", "-L", a.location]).split('\n')
+                a.deps = [dep.partition(' ')[0][1::] for dep in long_deps[2:-1]]
+                libraries += [a]
+    return libraries
+
+
+# # Fix all install names first
+# 
+# Some will fail, because they are either stub files, or system files...
+
+# In[ ]:
+
+libraries = get_libs()
+c = 0
+failed = []
+for c in range(len(libraries)):
+    i = libraries[c]
+    if os.path.islink(i.location):
+        continue
+    if i.install_name != i.location:
+        try:
+            run(["install_name_tool",'-id',i.location, i.location])
+        except:
+            print("Failed: ",i.name)
+            print( "(",libraries[c].name,")")
+            failed += [c]
+print (failed)
+print ('Removing failed libs...')
+for fail in reversed(failed):
+    print ("Removing from list",libraries[fail].name)
+    del libraries[fail]
+
+
+# # Fix all dependencies with absolute paths
+
+for c  in xrange(len(libraries)):
+    this_lib = libraries[c]
+    if this_lib.install_name != this_lib.location:
+        print('Not valid:', i.name)
+    else:
+        lib = this_lib.name
+        command = ['install_name_tool']
+        for dep in this_lib.deps:
+            for loc in libraries:
+                if dep.find(loc.name) != -1 and dep != loc.install_name:
+                    command += ['-change', dep, loc.install_name]
+                    break
+        try:
+            if len(command) != 1:
+                command += [this_lib.location]
+                print('Processing', lib)
+                print('======================\n\n')
+                print(" ".join(command))
+                print('======================\n\n')
+                run(command)
+        except:
+            print('\n\n*********************************************')
+            print('Last command failed!')
+            print(" ".join(command))
+            print('*********************************************\n\n')
+
+
+
+

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.