summaryrefslogtreecommitdiff
path: root/giscanner/shlibs.py
diff options
context:
space:
mode:
authorOwen W. Taylor <otaylor@fishsoup.net>2009-08-13 16:09:27 -0400
committerColin Walters <walters@verbum.org>2009-08-17 00:11:44 -0400
commitaf6bcb48d777f683384d9b8497e1b0edba5b16e7 (patch)
treec80ce74f9f0611dedb9d21e9d15176a269ceb69b /giscanner/shlibs.py
parent19db6454c48b6d8e4a0f033cf6c1d2b4be66f6c7 (diff)
downloadgobject-introspection-af6bcb48d777f683384d9b8497e1b0edba5b16e7.tar.gz
Resolve library names to shared libraries ourselves
Using ctypes.util.find_library() to resolve library names to sonames causes problems with dealing with uninstalled libtool operation properly. We're unlikely to find any way of combining the two that will be robust against future changes in both facilities. Switch to a different approach - run 'ldd' on the compiled introspection binary and extract sonames from there This is less portable but should be quite robust where it works. utils.py dumper.py: Move libtool-command-line finding into utils.py girwriter.py: Remove library name resolution from here, expect libraries to be passed in preresolved. shlibs.py scannermain.py: New file including resolve_shlibs() to resolve library names using the introspection binary. tests/scanner/Makefile.am: Add .libs to LD_LIBRARY_PATH http://bugzilla.gnome.org/show_bug.cgi?id=591669
Diffstat (limited to 'giscanner/shlibs.py')
-rw-r--r--giscanner/shlibs.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/giscanner/shlibs.py b/giscanner/shlibs.py
new file mode 100644
index 00000000..38a89e20
--- /dev/null
+++ b/giscanner/shlibs.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+# -*- Mode: Python -*-
+# GObject-Introspection - a framework for introspecting GObject libraries
+# Copyright (C) 2009 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+import re
+import subprocess
+
+from .utils import get_libtool_command
+
+# Assume ldd output is something vaguely like
+#
+# libpangoft2-1.0.so.0 => /usr/lib/libpangoft2-1.0.so.0 (0x006c1000)
+#
+# We say that if something in the output looks like libpangoft2<blah>
+# then the *first* such in the output is the soname. We require <blah>
+# to start with [^A-Za-z0-9_-] to avoid problems with libpango vs libpangoft2
+#
+# 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):
+ 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
+# 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.
+#
+def resolve_shlibs(options, binary, libraries):
+ args = []
+ libtool = get_libtool_command(options)
+ if libtool:
+ args.extend(libtool)
+ args.append('--mode=execute')
+ args.extend(['ldd', binary.args[0]])
+ proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+ patterns = {}
+ for library in libraries:
+ patterns[library] = _library_pattern(library)
+
+ shlibs = []
+ for line in proc.stdout:
+ for library, pattern in patterns.iteritems():
+ m = pattern.search(line)
+ if m:
+ del patterns[library]
+ shlibs.append(m.group(1))
+ break
+
+ if len(patterns) > 0:
+ raise SystemExit(
+ "ERROR: can't resolve libraries to shared libraries: " +
+ ", ".join(patterns.keys()))
+
+ return shlibs