[gobject-introspection] scanner: Improve compatibility with OS X



commit 513dfb969c2317377eb0f0ec150767a8d95c6d2e
Author: Clemens Lang <cal macports org>
Date:   Mon Feb 10 18:44:06 2014 -0500

    scanner: Improve compatibility with OS X
    
    While gobject-introspection works on OS X, a few circumstances are
    handled a little different there. For one, libraries are linked using
    absolute paths. The current gobject-introspection code however strips
    any path components and just uses the filename in the .gir file –
    while this doesn't cause failure, the generated typlibs will only work
    in presence of a correctly set DYLD_LIBRARY_PATH or
    DYLD_FALLBACK_LIBRARY_PATH environment variable.
    
    Setting DYLD_LIBRARY_PATH on OS X often is a bad idea due to the
    side-effects: Doing so causes the directory parts of libraries
    referenced using an absolute path to be ignored if there is a equally
    named file in the directory listed in $DYLD_LIBRARY_PATH, possibly
    overriding referenced system libraries with incompatible versions.
    
    Setting DYLD_FALLBACK_LIBRARY_PATH is the better solution for this
    problem; however because this variable has an implicit default value
    it's not simple to do so correctly.
    
    The best solution to the problem is referencing libraries from .girs
    using absolute paths, just as all other binaries on OS X. The attached
    patches against 2.38.0 implement that.
    
    Another quirk one needs to be aware of on OS X is that Apple ships a
    program called libtool, which is not GNU libtool and incompatible with
    it. GNU libtool, if present, is usually called glibtool on OS X. The
    patches also fix this.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=709583

 giscanner/shlibs.py |    8 ++++++--
 giscanner/utils.py  |   31 +++++++++++++++++++++++++++++--
 2 files changed, 35 insertions(+), 4 deletions(-)
---
diff --git a/giscanner/shlibs.py b/giscanner/shlibs.py
index 1241827..21fcafd 100644
--- a/giscanner/shlibs.py
+++ b/giscanner/shlibs.py
@@ -49,9 +49,13 @@ def _resolve_libtool(options, binary, libraries):
 # The negative lookbehind at the start is to avoid problems if someone
 # is crazy enough to name a library liblib<foo> when lib<foo> exists.
 #
+# Match absolute paths on OS X to conform to how libraries are usually
+# referenced on OS X systems.
 def _ldd_library_pattern(library_name):
-    return re.compile("(?<![A-Za-z0-9_-])(lib*%s[^A-Za-z0-9_-][^\s\(\)]*)"
-                      % re.escape(library_name))
+    pattern = "(?<![A-Za-z0-9_-])(lib*%s[^A-Za-z0-9_-][^\s\(\)]*)"
+    if platform.system() == 'Darwin':
+        pattern = "([^\s]*lib*%s[^A-Za-z0-9_-][^\s\(\)]*)"
+    return re.compile(pattern % re.escape(library_name))
 
 
 # This is a what we do for non-la files. We assume that we are on an
diff --git a/giscanner/utils.py b/giscanner/utils.py
index def53fe..abd1a26 100644
--- a/giscanner/utils.py
+++ b/giscanner/utils.py
@@ -21,6 +21,7 @@
 import re
 import os
 import subprocess
+import platform
 
 
 _debugflags = None
@@ -88,6 +89,20 @@ def _extract_dlname_field(la_file):
         return None
 
 
+_libtool_libdir_pat = re.compile("libdir='([^']+)'")
+
+
+def _extract_libdir_field(la_file):
+    f = open(la_file)
+    data = f.read()
+    f.close()
+    m = _libtool_libdir_pat.search(data)
+    if m:
+        return m.groups()[0]
+    else:
+        return None
+
+
 # Returns the name that we would pass to dlopen() the library
 # corresponding to this .la file
 def extract_libtool_shlib(la_file):
@@ -95,6 +110,14 @@ def extract_libtool_shlib(la_file):
     if dlname is None:
         return None
 
+    # Darwin uses absolute paths where possible; since the libtool files never
+    # contain absolute paths, use the libdir field
+    if platform.system() == 'Darwin':
+        dlbasename = os.path.basename(dlname)
+        libdir = _extract_libdir_field(la_file)
+        if libdir is None:
+            return dlbasename
+        return libdir + '/' + dlbasename
     # From the comments in extract_libtool(), older libtools had
     # a path rather than the raw dlname
     return os.path.basename(dlname)
@@ -127,14 +150,18 @@ def get_libtool_command(options):
         # we simply split().
         return libtool_path.split(' ')
 
+    libtool_cmd = 'libtool'
+    if platform.system() == 'Darwin':
+        # libtool on OS X is a completely different program written by Apple
+        libtool_cmd = 'glibtool'
     try:
-        subprocess.check_call(['libtool', '--version'],
+        subprocess.check_call([libtool_cmd, '--version'],
                               stdout=open(os.devnull))
     except (subprocess.CalledProcessError, OSError):
         # If libtool's not installed, assume we don't need it
         return None
 
-    return ['libtool']
+    return [libtool_cmd]
 
 
 def files_are_identical(path1, path2):


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]