summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen W. Taylor <otaylor@fishsoup.net>2009-08-13 23:06:51 -0400
committerColin Walters <walters@verbum.org>2009-08-17 00:22:19 -0400
commitfa71c815d441ab922b1e5501f534f2c3d1fceef8 (patch)
treea86335d50e2fe924969ca29c6ef40b6aecdb338e
parentaf6bcb48d777f683384d9b8497e1b0edba5b16e7 (diff)
downloadgobject-introspection-fa71c815d441ab922b1e5501f534f2c3d1fceef8.tar.gz
Support passing --library=lib<foo>.la
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
-rw-r--r--giscanner/dumper.py5
-rw-r--r--giscanner/shlibs.py52
-rw-r--r--giscanner/utils.py32
-rw-r--r--tests/offsets/Makefile.am9
-rw-r--r--tests/scanner/GtkFrob-1.0-expected.gir2
-rw-r--r--tests/scanner/GtkFrob-1.0-expected.tgir2
-rw-r--r--tests/scanner/Makefile.am10
-rw-r--r--tests/scanner/annotation-1.0-expected.gir2
-rw-r--r--tests/scanner/annotation-1.0-expected.tgir2
-rw-r--r--tests/scanner/drawable-1.0-expected.gir2
-rw-r--r--tests/scanner/drawable-1.0-expected.tgir2
-rw-r--r--tests/scanner/foo-1.0-expected.gir5
-rw-r--r--tests/scanner/foo-1.0-expected.tgir2
-rw-r--r--tests/scanner/utility-1.0-expected.gir2
-rw-r--r--tests/scanner/utility-1.0-expected.tgir2
15 files changed, 95 insertions, 36 deletions
diff --git a/giscanner/dumper.py b/giscanner/dumper.py
index b8f16c9d..adfe88bc 100644
--- a/giscanner/dumper.py
+++ b/giscanner/dumper.py
@@ -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:
diff --git a/giscanner/shlibs.py b/giscanner/shlibs.py
index 38a89e20..cac4fdf2 100644
--- a/giscanner/shlibs.py
+++ b/giscanner/shlibs.py
@@ -22,7 +22,17 @@
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))
diff --git a/giscanner/utils.py b/giscanner/utils.py
index 3a26a1ee..29a55609 100644
--- a/giscanner/utils.py
+++ b/giscanner/utils.py
@@ -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
diff --git a/tests/offsets/Makefile.am b/tests/offsets/Makefile.am
index b292ef6e..c725bbc0 100644
--- a/tests/offsets/Makefile.am
+++ b/tests/offsets/Makefile.am
@@ -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
diff --git a/tests/scanner/GtkFrob-1.0-expected.gir b/tests/scanner/GtkFrob-1.0-expected.gir
index 423c0539..7b8c500b 100644
--- a/tests/scanner/GtkFrob-1.0-expected.gir
+++ b/tests/scanner/GtkFrob-1.0-expected.gir
@@ -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">
diff --git a/tests/scanner/GtkFrob-1.0-expected.tgir b/tests/scanner/GtkFrob-1.0-expected.tgir
index 0d101be3..078d65f6 100644
--- a/tests/scanner/GtkFrob-1.0-expected.tgir
+++ b/tests/scanner/GtkFrob-1.0-expected.tgir
@@ -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"/>
diff --git a/tests/scanner/Makefile.am b/tests/scanner/Makefile.am
index 36aedbf7..2c6ac7ab 100644
--- a/tests/scanner/Makefile.am
+++ b/tests/scanner/Makefile.am
@@ -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 \
diff --git a/tests/scanner/annotation-1.0-expected.gir b/tests/scanner/annotation-1.0-expected.gir
index 3715edca..f01d01fa 100644
--- a/tests/scanner/annotation-1.0-expected.gir
+++ b/tests/scanner/annotation-1.0-expected.gir
@@ -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"
diff --git a/tests/scanner/annotation-1.0-expected.tgir b/tests/scanner/annotation-1.0-expected.tgir
index 76a20edb..b22080ae 100644
--- a/tests/scanner/annotation-1.0-expected.tgir
+++ b/tests/scanner/annotation-1.0-expected.tgir
@@ -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"/>
diff --git a/tests/scanner/drawable-1.0-expected.gir b/tests/scanner/drawable-1.0-expected.gir
index 6f82e3ab..da637770 100644
--- a/tests/scanner/drawable-1.0-expected.gir
+++ b/tests/scanner/drawable-1.0-expected.gir
@@ -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"
diff --git a/tests/scanner/drawable-1.0-expected.tgir b/tests/scanner/drawable-1.0-expected.tgir
index 618cf3af..705235e7 100644
--- a/tests/scanner/drawable-1.0-expected.tgir
+++ b/tests/scanner/drawable-1.0-expected.tgir
@@ -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"/>
diff --git a/tests/scanner/foo-1.0-expected.gir b/tests/scanner/foo-1.0-expected.gir
index 839a8dc1..85e2ace0 100644
--- a/tests/scanner/foo-1.0-expected.gir
+++ b/tests/scanner/foo-1.0-expected.gir
@@ -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"/>
diff --git a/tests/scanner/foo-1.0-expected.tgir b/tests/scanner/foo-1.0-expected.tgir
index 9a43eccb..fe09907c 100644
--- a/tests/scanner/foo-1.0-expected.tgir
+++ b/tests/scanner/foo-1.0-expected.tgir
@@ -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>
diff --git a/tests/scanner/utility-1.0-expected.gir b/tests/scanner/utility-1.0-expected.gir
index 8c6a602b..1b2fe84f 100644
--- a/tests/scanner/utility-1.0-expected.gir
+++ b/tests/scanner/utility-1.0-expected.gir
@@ -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">
diff --git a/tests/scanner/utility-1.0-expected.tgir b/tests/scanner/utility-1.0-expected.tgir
index d25bd59f..ec4597a7 100644
--- a/tests/scanner/utility-1.0-expected.tgir
+++ b/tests/scanner/utility-1.0-expected.tgir
@@ -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"/>