c83e697aa0
After patching up the shared libraries in c420de6
to use absolute paths,
there are still some libraries left which do not get an absolute paths
assigned.
Those libraries are the ones which have an absolute path outside of the
Nix store, so we assume that they're build products of the current build
and make them absolute by prepending "$out/lib" or "$lib/lib" (depending
on whether it's a multiple output derivation or not) to its basename.
So for my test case, the resulting library paths now look like this:
/nix/store/...-libblockdev-1.3/lib/libblockdev.so.0
/nix/store/...-glibc-2.21/lib/libm.so.6
/nix/store/...-dmraid-1.0.0.rc16/lib/libdmraid.so.1.0.0.rc16
/nix/store/...-libblockdev-1.3/lib/libbd_utils.so.0
Which is perfectly fine and everything gets resolved correctly after
importing the library using GI.
However, I didn't test it against other libraries and programs, so this
still needs testing, especially for Darwin.
Signed-off-by: aszlig <aszlig@redmoonstudios.org>
122 lines
4.9 KiB
Diff
122 lines
4.9 KiB
Diff
diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py
|
|
index 89ec193..8ee92c3 100755
|
|
--- a/giscanner/scannermain.py
|
|
+++ b/giscanner/scannermain.py
|
|
@@ -94,6 +94,34 @@ def get_windows_option_group(parser):
|
|
return group
|
|
|
|
|
|
+def _get_default_fallback_libpath():
|
|
+ outputs = os.environ.get("outputs", "out").split()
|
|
+ if "lib" in outputs:
|
|
+ # For multiple output derivations let's try whether there is a $lib
|
|
+ # environment variable and use that as the base store path.
|
|
+ store_path = os.environ.get("lib")
|
|
+ elif "out" in outputs:
|
|
+ # Otherwise we have a single output derivation, so the libraries most
|
|
+ # certainly will end up in "$out/lib".
|
|
+ store_path = os.environ.get("out")
|
|
+
|
|
+ if store_path is not None:
|
|
+ # Even if we have a $lib as output, there still should be a $lib/lib
|
|
+ # directory.
|
|
+ return os.path.join(store_path, 'lib')
|
|
+ else:
|
|
+ # If we haven't found a possible scenario, let's return an empty string
|
|
+ # so that the shared library won't be prepended with a path.
|
|
+ #
|
|
+ # Note that this doesn't mean that all hope is lost, because after all
|
|
+ # we can still use --fallback-library-path to set one.
|
|
+ #
|
|
+ # Also, we're not returning None, because that would make it very
|
|
+ # difficult to disable adding fallback paths altogether using something
|
|
+ # like: --fallback-library-path=""
|
|
+ return ""
|
|
+
|
|
+
|
|
def _get_option_parser():
|
|
parser = optparse.OptionParser('%prog [options] sources')
|
|
parser.add_option('', "--quiet",
|
|
@@ -200,6 +228,10 @@ match the namespace prefix.""")
|
|
parser.add_option("", "--filelist",
|
|
action="store", dest="filelist", default=[],
|
|
help="file containing headers and sources to be scanned")
|
|
+ parser.add_option("", "--fallback-library-path",
|
|
+ action="store", dest="fallback_libpath",
|
|
+ default=_get_default_fallback_libpath(),
|
|
+ help="Path to prepend to unknown shared libraries")
|
|
|
|
group = get_preprocessor_option_group(parser)
|
|
parser.add_option_group(group)
|
|
diff --git a/giscanner/shlibs.py b/giscanner/shlibs.py
|
|
index 838d343..35b6dab 100644
|
|
--- a/giscanner/shlibs.py
|
|
+++ b/giscanner/shlibs.py
|
|
@@ -53,10 +53,24 @@ def _resolve_libtool(options, binary, libraries):
|
|
# Match absolute paths on OS X to conform to how libraries are usually
|
|
# referenced on OS X systems.
|
|
def _ldd_library_pattern(library_name):
|
|
+ nix_store_dir = re.escape('@nixStoreDir@'.rstrip('/'))
|
|
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))
|
|
+ pattern = r'''
|
|
+ (
|
|
+ (?:
|
|
+ # First match Nix store paths because they need to be absolute.
|
|
+ (?:%s(?:/[^/]*)+)
|
|
+ # Everything else not a store path remains relative, because we
|
|
+ # would end up having absolute build paths in the resulting GIR
|
|
+ # file.
|
|
+ | (?<=/)
|
|
+ )
|
|
+ # And finally the library itself:
|
|
+ (?:lib%s[^A-Za-z0-9_-][^\s\(\)]*)
|
|
+ )
|
|
+ '''
|
|
+ return re.compile(pattern % (nix_store_dir, re.escape(library_name)),
|
|
+ re.VERBOSE)
|
|
|
|
|
|
# This is a what we do for non-la files. We assume that we are on an
|
|
@@ -115,7 +129,11 @@ def _resolve_non_libtool(options, binary, libraries):
|
|
m = pattern.search(line)
|
|
if m:
|
|
del patterns[library]
|
|
- shlibs.append(m.group(1))
|
|
+ match = m.group(1)
|
|
+ if not match.startswith('/') \
|
|
+ and len(options.fallback_libpath) > 0:
|
|
+ match = os.path.join(options.fallback_libpath, match)
|
|
+ shlibs.append(match)
|
|
break
|
|
|
|
if len(patterns) > 0:
|
|
diff --git a/giscanner/utils.py b/giscanner/utils.py
|
|
index 660081e..c9c767a 100644
|
|
--- a/giscanner/utils.py
|
|
+++ b/giscanner/utils.py
|
|
@@ -109,17 +109,11 @@ 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)
|
|
+ dlbasename = os.path.basename(dlname)
|
|
+ libdir = _extract_libdir_field(la_file)
|
|
+ if libdir is None:
|
|
+ return dlbasename
|
|
+ return libdir + '/' + dlbasename
|
|
|
|
|
|
def extract_libtool(la_file):
|