Support passing --library=lib<foo>.la
authorOwen W. Taylor <otaylor@fishsoup.net>
Fri, 14 Aug 2009 03:06:51 +0000 (23:06 -0400)
committerColin Walters <walters@verbum.org>
Mon, 17 Aug 2009 04:22:19 +0000 (00:22 -0400)
In addition to the current --library=<foo>, support --library=lib<foo>.la.
This makes it unambiguous that we are referencing an uninstalled
library and allows accurate extraction of the shared library name
for the uninstalled library.

* tests/scanner/Makefile.am tests/offsets/Makefile.am: Use the
  new form of --library=. Also some LD_LIBRARY_PATH frobbing as needed.

*-expected.gir *-expected.tgir: We now pick out the shared library
  accurately, so fix shared-library="" in our reference girs. (The
  comparison may need some pre-sanitization now to work on non-ELF)

http://bugzilla.gnome.org/show_bug.cgi?id=591669

15 files changed:
giscanner/dumper.py
giscanner/shlibs.py
giscanner/utils.py
tests/offsets/Makefile.am
tests/scanner/GtkFrob-1.0-expected.gir
tests/scanner/GtkFrob-1.0-expected.tgir
tests/scanner/Makefile.am
tests/scanner/annotation-1.0-expected.gir
tests/scanner/annotation-1.0-expected.tgir
tests/scanner/drawable-1.0-expected.gir
tests/scanner/drawable-1.0-expected.tgir
tests/scanner/foo-1.0-expected.gir
tests/scanner/foo-1.0-expected.tgir
tests/scanner/utility-1.0-expected.gir
tests/scanner/utility-1.0-expected.tgir

index b8f16c9..adfe88b 100644 (file)
@@ -193,7 +193,10 @@ class DumpCompiler(object):
             if (uninst_builddir and
                 self._options.libraries[0] == 'girepository-1.0'):
                 continue
-            args.append('-l' + library)
+            if library.endswith(".la"): # explicitly specified libtool library
+                args.append(library)
+            else:
+                args.append('-l' + library)
 
         # hack for building gobject-introspection itself
         if uninst_builddir:
index 38a89e2..cac4fdf 100644 (file)
 import re
 import subprocess
 
-from .utils import get_libtool_command
+from .utils import get_libtool_command, extract_libtool_shlib
+
+# For .la files, the situation is easy.
+def _resolve_libtool(options, binary, libraries):
+    shlibs = []
+    for library in libraries:
+        shlib = extract_libtool_shlib(library)
+        if shlib:
+            shlibs.append(shlib)
+
+    return shlibs
 
 # Assume ldd output is something vaguely like
 #
@@ -35,20 +45,27 @@ from .utils import get_libtool_command
 # 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.
 #
-def _library_pattern(library_name):
+def _ldd_library_pattern(library_name):
     return re.compile("(?<![A-Za-z0-9_-])(lib*%s[^A-Za-z0-9_-][^\s\(\)]*)"
                       % re.escape(library_name))
 
-# We want to resolve a set of library names (the <foo> of -l<foo>)
-# against a library to find the shared library name. The shared
-# library name is suppose to be what you pass to dlopen() (or
-# equivalent). And we want to do this using the libraries that 'binary'
-# is linking against. The implementation below assumes that we are on an
+# This is a what we do for non-la files. We assume that we are on an
 # ELF-like system where ldd exists and the soname extracted with ldd is
-# a filename that can be opened with dlopen(). Alternate implementations
-# could be added here.
+# a filename that can be opened with dlopen().
 #
-def resolve_shlibs(options, binary, libraries):
+# On OS X this will need a straightforward alternate implementation
+# in terms of otool.
+#
+# Windows is more difficult, since there isn't always a straightforward
+# translation between library name (.lib) and the name of the .dll, so
+# extracting the dll names from the compiled app may not be sufficient.
+# We might need to hunt down the .lib in the compile-time path and
+# use that to figure out the name of the DLL.
+#
+def _resolve_non_libtool(options, binary, libraries):
+    if not libraries:
+        return []
+
     args = []
     libtool = get_libtool_command(options)
     if libtool:
@@ -58,7 +75,7 @@ def resolve_shlibs(options, binary, libraries):
     proc = subprocess.Popen(args, stdout=subprocess.PIPE)
     patterns = {}
     for library in libraries:
-        patterns[library] = _library_pattern(library)
+        patterns[library] = _ldd_library_pattern(library)
 
     shlibs = []
     for line in proc.stdout:
@@ -75,3 +92,16 @@ def resolve_shlibs(options, binary, libraries):
             ", ".join(patterns.keys()))
 
     return shlibs
+
+# We want to resolve a set of library names (the <foo> of -l<foo>)
+# against a library to find the shared library name. The shared
+# library name is suppose to be what you pass to dlopen() (or
+# equivalent). And we want to do this using the libraries that 'binary'
+# is linking against.
+#
+def resolve_shlibs(options, binary, libraries):
+    libtool = filter(lambda x: x.endswith(".la"), libraries)
+    non_libtool = filter(lambda x: not x.endswith(".la"), libraries)
+
+    return (_resolve_libtool(options, binary, libtool) +
+            _resolve_non_libtool(options, binary, non_libtool))
index 3a26a1e..29a5560 100644 (file)
@@ -20,6 +20,7 @@
 
 import re
 import os
+import subprocess
 
 # Copied from h2defs.py
 _upperstr_pat1 = re.compile(r'([^A-Z])([A-Z])')
@@ -46,12 +47,33 @@ def to_underscores_noprefix(name):
 
 _libtool_pat = re.compile("dlname='([A-z0-9\.\-\+]+)'\n")
 
+def _extract_dlname_field(la_file):
+    f = open(la_file)
+    data = f.read()
+    f.close()
+    m = _libtool_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):
+    dlname = _extract_dlname_field(la_file)
+    if dlname is None:
+        return None
+
+    # From the comments in extract_libtool(), older libtools had
+    # a path rather than the raw dlname
+    return os.path.basename(dlname)
 
-def extract_libtool(libname):
-    data = open(libname).read()
-    filename = _libtool_pat.search(data).groups()[0]
-    libname = os.path.join(os.path.dirname(libname),
-                           '.libs', filename)
+def extract_libtool(la_file):
+    dlname = _extract_dlname_field(la_file)
+    if dlname is None:
+        raise ValueError("%s has no dlname. Not a shared library?" % la_file)
+    libname = os.path.join(os.path.dirname(la_file),
+                           '.libs', dlname)
     # FIXME: This hackish, but I'm not sure how to do this
     #        in a way which is compatible with both libtool 2.2
     #        and pre-2.2. Johan 2008-10-21
index b292ef6..c725bbc 100644 (file)
@@ -22,7 +22,7 @@ offsets-1.0.gir: liboffsets.la offsets.h $(SCANNER_BIN) $(SCANNER_LIBS) Makefile
        $(CHECK_DEBUG) $(SCANNER) \
        --include=GObject-2.0 \
         --libtool="$(SHAVE_SAVED_LIBTOOL)" \
-       --library=offsets \
+       --library=liboffsets.la \
        --namespace=offsets \
        --nsversion=1.0 \
        --pkg gobject-2.0 \
@@ -30,7 +30,8 @@ offsets-1.0.gir: liboffsets.la offsets.h $(SCANNER_BIN) $(SCANNER_LIBS) Makefile
         --output $@
 
 %.typelib: %.gir $(top_builddir)/tools/g-ir-compiler$(EXEEXT) Makefile
-       $(top_builddir)/tools/g-ir-compiler --includedir=. --includedir=$(top_builddir)/gir $< -o $@
+       LD_LIBRARY_PATH=$(top_builddir)/girepository/.libs:$(builddir)/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH} \
+        $(top_builddir)/tools/g-ir-compiler --includedir=. --includedir=$(top_builddir)/gir $< -o $@
 
 CLEANFILES += offsets-1.0.gir offsets-1.0.typelib
 
@@ -52,8 +53,8 @@ CLEANFILES += gitestoffsets.c
 ############################################################
 
 check-local: offsets-1.0.typelib
-       LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:} GI_TYPELIB_PATH=:$(top_builddir)/gir \
-         gitestoffsets$(EXEEXT) offsets.compiled offsets.introspected
+       LD_LIBRARY_PATH=$(top_builddir)/girepository/.libs:$(builddir)/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH} \
+        GI_TYPELIB_PATH=:$(top_builddir)/gir gitestoffsets$(EXEEXT) offsets.compiled offsets.introspected
        diff -u offsets.compiled offsets.introspected
 
 CLEANFILES += offsets.compiled offsets.introspected
index 423c053..7b8c500 100644 (file)
@@ -11,7 +11,7 @@ and/or use gtk-doc annotations.  -->
   <package name="gobject-2.0"/>
   <namespace name="GtkFrob"
              version="1.0"
-             shared-library="gtkfrob"
+             shared-library="libgtkfrob.so"
              c:prefix="Gtk">
     <function name="language_manager_get_default"
               c:identifier="gtk_frob_language_manager_get_default">
index 0d101be..078d65f 100644 (file)
@@ -5,7 +5,7 @@
             xmlns:glib="http://www.gtk.org/introspection/glib/1.0">
   <include name="GObject" version="2.0"/>
   <include name="GLib" version="2.0"/>
-  <namespace name="GtkFrob" version="1.0" shared-library="gtkfrob" c:prefix="Gtk">
+  <namespace name="GtkFrob" version="1.0" shared-library="libgtkfrob.so" c:prefix="Gtk">
     <function name="language_manager_get_default" c:identifier="gtk_frob_language_manager_get_default">
       <return-value transfer-ownership="none">
         <type name="none"/>
index 36aedbf..2c6ac7a 100644 (file)
@@ -43,7 +43,7 @@ annotation-1.0.gir: libannotation.la annotation.c annotation.h utility-1.0.gir $
        --include=GObject-2.0 \
        --include=utility-1.0 \
         --libtool="$(LIBTOOL)" \
-       --library=annotation \
+       --library=libannotation.la \
        --namespace=annotation \
        --nsversion=1.0 \
        --pkg gobject-2.0 \
@@ -56,7 +56,7 @@ drawable-1.0.gir: libdrawable.la drawable.c drawable.h utility-1.0.gir $(SCANNER
        --include=GObject-2.0 \
        --include=utility-1.0 \
         --libtool="$(LIBTOOL)" \
-       --library=drawable \
+       --library=libdrawable.la \
        --namespace=drawable \
        --nsversion=1.0 \
        --pkg gobject-2.0 \
@@ -70,7 +70,7 @@ foo-1.0.gir: libfoo.la foo.c foo.h utility-1.0.gir $(SCANNER_BIN) $(SCANNER_LIBS
        --include=utility-1.0 \
        --c-include="foo.h" \
         --libtool="$(LIBTOOL)" \
-       --library=foo \
+       --library=libfoo.la \
        --namespace=foo \
        --nsversion=1.0 \
        --pkg gobject-2.0 \
@@ -82,7 +82,7 @@ utility-1.0.gir: libutility.la utility.h $(SCANNER_BIN) $(SCANNER_LIBS) Makefile
        $(CHECK_DEBUG) $(SCANNER) \
        --include=GObject-2.0 \
         --libtool="$(LIBTOOL)" \
-       --library=utility \
+       --library=libutility.la \
        --namespace=utility \
        --nsversion=1.0 \
        --pkg gobject-2.0 \
@@ -95,7 +95,7 @@ GtkFrob-1.0.gir: libgtkfrob.la gtkfrob.h $(SCANNER_BIN) $(SCANNER_LIBS) Makefile
        $(CHECK_DEBUG) $(SCANNER) \
        --include=GObject-2.0 \
         --libtool="$(LIBTOOL)" \
-       --library=gtkfrob \
+       --library=libgtkfrob.la \
        --namespace=GtkFrob \
        --strip-prefix=Gtk \
        --nsversion=1.0 \
index 3715edc..f01d01f 100644 (file)
@@ -12,7 +12,7 @@ and/or use gtk-doc annotations.  -->
   <package name="gobject-2.0"/>
   <namespace name="annotation"
              version="1.0"
-             shared-library="annotation"
+             shared-library="libannotation.so"
              c:prefix="annotation">
     <callback name="Callback"
               c:type="AnnotationCallback"
index 76a20ed..b22080a 100644 (file)
@@ -6,7 +6,7 @@
   <include name="utility" version="1.0"/>
   <include name="GObject" version="2.0"/>
   <include name="GLib" version="2.0"/>
-  <namespace name="annotation" version="1.0" shared-library="annotation" c:prefix="annotation">
+  <namespace name="annotation" version="1.0" shared-library="libannotation.so" c:prefix="annotation">
     <callback name="Callback">
       <return-value transfer-ownership="none">
         <type name="int"/>
index 6f82e3a..da63777 100644 (file)
@@ -12,7 +12,7 @@ and/or use gtk-doc annotations.  -->
   <package name="gobject-2.0"/>
   <namespace name="drawable"
              version="1.0"
-             shared-library="drawable"
+             shared-library="libdrawable.so"
              c:prefix="drawable">
     <class name="TestDrawable"
            c:type="TestDrawable"
index 618cf3a..705235e 100644 (file)
@@ -6,7 +6,7 @@
   <include name="utility" version="1.0"/>
   <include name="GObject" version="2.0"/>
   <include name="GLib" version="2.0"/>
-  <namespace name="drawable" version="1.0" shared-library="drawable" c:prefix="drawable">
+  <namespace name="drawable" version="1.0" shared-library="libdrawable.so" c:prefix="drawable">
     <class name="TestDrawable" parent="GObject.Object" glib:type-struct="TestDrawableClass" abstract="1" glib:type-name="TestDrawable" glib:get-type="test_drawable_get_type">
       <field name="parent_instance">
         <type name="GObject.Object"/>
index 839a8dc..85e2ace 100644 (file)
@@ -11,7 +11,10 @@ and/or use gtk-doc annotations.  -->
   <include name="utility" version="1.0"/>
   <package name="gobject-2.0"/>
   <c:include name="foo.h"/>
-  <namespace name="foo" version="1.0" shared-library="foo" c:prefix="foo">
+  <namespace name="foo"
+             version="1.0"
+             shared-library="libfoo.so"
+             c:prefix="foo">
     <alias name="List" target="GLib.SList" c:type="FooList"/>
     <alias name="ObjectCookie" target="any" c:type="FooObjectCookie"/>
     <alias name="XEvent" target="none" c:type="FooXEvent"/>
index 9a43ecc..fe09907 100644 (file)
@@ -6,7 +6,7 @@
   <include name="utility" version="1.0"/>
   <include name="GObject" version="2.0"/>
   <include name="GLib" version="2.0"/>
-  <namespace name="foo" version="1.0" shared-library="foo" c:prefix="foo">
+  <namespace name="foo" version="1.0" shared-library="libfoo.so" c:prefix="foo">
     <enumeration name="ASingle">
       <member name="some_single_enum" value="0"/>
     </enumeration>
index 8c6a602..1b2fe84 100644 (file)
@@ -11,7 +11,7 @@ and/or use gtk-doc annotations.  -->
   <package name="gobject-2.0"/>
   <namespace name="utility"
              version="1.0"
-             shared-library="utility"
+             shared-library="libutility.so"
              c:prefix="utility">
     <alias name="Glyph" target="uint32" c:type="UtilityGlyph"/>
     <record name="Buffer" c:type="UtilityBuffer">
index d25bd59..ec4597a 100644 (file)
@@ -5,7 +5,7 @@
             xmlns:glib="http://www.gtk.org/introspection/glib/1.0">
   <include name="GObject" version="2.0"/>
   <include name="GLib" version="2.0"/>
-  <namespace name="utility" version="1.0" shared-library="utility" c:prefix="utility">
+  <namespace name="utility" version="1.0" shared-library="libutility.so" c:prefix="utility">
     <record name="Buffer">
       <field name="data" writable="1">
         <type name="any"/>