nixpkgs/pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch

129 lines
5.3 KiB
Diff
Raw Normal View History

diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py
index 89ec193..54f1d2e 100755
--- a/giscanner/scannermain.py
+++ b/giscanner/scannermain.py
@@ -94,6 +94,39 @@ def get_windows_option_group(parser):
return group
+def _get_default_fallback_libpath():
+ # Newer multiple-output-optimized stdenv has an environment variable
+ # $outputLib which in turn specifies another variable which then is used as
+ # the destination for the library contents (${!outputLib}/lib).
+ store_path = os.environ.get(os.environ.get("outputLib"))
+ if store_path is None:
+ 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 +233,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)
gobject-introspection: Fix patching shared objects The gi-r-scanner is generating a list of shared libraries that are referenced in the shared-library attribute of the <namespace/> element of the GIR file. However, this attribute only contains the names of the libraries and not the full store paths, like for example while preparing to package libblockdev, the following items were included in the shared-library attribute: /nix/store/...-libblockdev-1.3/lib/libblockdev.so.0 libm.so.6 libdmraid.so.1.0.0.rc16 libbd_utils.so.0 Unfortunately, loading such a library without setting LD_LIBRARY_PATH is going to fail finding libm.so.6 and libdmraid.so.1.0.0.rc16. Now the first attempt at solving this was to put absolute paths of all the libraries referenced in the shared-library attribute, but this also led up to including paths of build-time shared objects into that attribute: /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 /tmp/nix-build-libblockdev-1.3.drv-0/.../utils/.libs/libbd_utils.so.0 This of course is not what we want, so the final solution is to only use the absolute path whenever it is a Nix path and leave the library name as-is if the path doesn't reside within the store, 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 libbd_utils.so.0 The downside of this approach is that if not even the output path of the library is in LD_LIBRARY_PATH, even loading of libbd_utils.so.0 could fail, so we need to patch the loader as well. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2016-01-22 20:49:33 +03:00
diff --git a/giscanner/shlibs.py b/giscanner/shlibs.py
index 838d343..ca7fc0d 100644
gobject-introspection: Fix patching shared objects The gi-r-scanner is generating a list of shared libraries that are referenced in the shared-library attribute of the <namespace/> element of the GIR file. However, this attribute only contains the names of the libraries and not the full store paths, like for example while preparing to package libblockdev, the following items were included in the shared-library attribute: /nix/store/...-libblockdev-1.3/lib/libblockdev.so.0 libm.so.6 libdmraid.so.1.0.0.rc16 libbd_utils.so.0 Unfortunately, loading such a library without setting LD_LIBRARY_PATH is going to fail finding libm.so.6 and libdmraid.so.1.0.0.rc16. Now the first attempt at solving this was to put absolute paths of all the libraries referenced in the shared-library attribute, but this also led up to including paths of build-time shared objects into that attribute: /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 /tmp/nix-build-libblockdev-1.3.drv-0/.../utils/.libs/libbd_utils.so.0 This of course is not what we want, so the final solution is to only use the absolute path whenever it is a Nix path and leave the library name as-is if the path doesn't reside within the store, 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 libbd_utils.so.0 The downside of this approach is that if not even the output path of the library is in LD_LIBRARY_PATH, even loading of libbd_utils.so.0 could fail, so we need to patch the loader as well. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2016-01-22 20:49:33 +03:00
--- a/giscanner/shlibs.py
+++ b/giscanner/shlibs.py
@@ -53,10 +53,27 @@ def _resolve_libtool(options, binary, libraries):
gobject-introspection: Fix patching shared objects The gi-r-scanner is generating a list of shared libraries that are referenced in the shared-library attribute of the <namespace/> element of the GIR file. However, this attribute only contains the names of the libraries and not the full store paths, like for example while preparing to package libblockdev, the following items were included in the shared-library attribute: /nix/store/...-libblockdev-1.3/lib/libblockdev.so.0 libm.so.6 libdmraid.so.1.0.0.rc16 libbd_utils.so.0 Unfortunately, loading such a library without setting LD_LIBRARY_PATH is going to fail finding libm.so.6 and libdmraid.so.1.0.0.rc16. Now the first attempt at solving this was to put absolute paths of all the libraries referenced in the shared-library attribute, but this also led up to including paths of build-time shared objects into that attribute: /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 /tmp/nix-build-libblockdev-1.3.drv-0/.../utils/.libs/libbd_utils.so.0 This of course is not what we want, so the final solution is to only use the absolute path whenever it is a Nix path and leave the library name as-is if the path doesn't reside within the store, 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 libbd_utils.so.0 The downside of this approach is that if not even the output path of the library is in LD_LIBRARY_PATH, even loading of libbd_utils.so.0 could fail, so we need to patch the loader as well. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2016-01-22 20:49:33 +03:00
# 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\(\)]*)"
gobject-introspection: Fix patching shared objects The gi-r-scanner is generating a list of shared libraries that are referenced in the shared-library attribute of the <namespace/> element of the GIR file. However, this attribute only contains the names of the libraries and not the full store paths, like for example while preparing to package libblockdev, the following items were included in the shared-library attribute: /nix/store/...-libblockdev-1.3/lib/libblockdev.so.0 libm.so.6 libdmraid.so.1.0.0.rc16 libbd_utils.so.0 Unfortunately, loading such a library without setting LD_LIBRARY_PATH is going to fail finding libm.so.6 and libdmraid.so.1.0.0.rc16. Now the first attempt at solving this was to put absolute paths of all the libraries referenced in the shared-library attribute, but this also led up to including paths of build-time shared objects into that attribute: /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 /tmp/nix-build-libblockdev-1.3.drv-0/.../utils/.libs/libbd_utils.so.0 This of course is not what we want, so the final solution is to only use the absolute path whenever it is a Nix path and leave the library name as-is if the path doesn't reside within the store, 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 libbd_utils.so.0 The downside of this approach is that if not even the output path of the library is in LD_LIBRARY_PATH, even loading of libbd_utils.so.0 could fail, so we need to patch the loader as well. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2016-01-22 20:49:33 +03:00
- return re.compile(pattern % re.escape(library_name))
+ return re.compile(pattern % re.escape(library_name))
gobject-introspection: Fix patching shared objects The gi-r-scanner is generating a list of shared libraries that are referenced in the shared-library attribute of the <namespace/> element of the GIR file. However, this attribute only contains the names of the libraries and not the full store paths, like for example while preparing to package libblockdev, the following items were included in the shared-library attribute: /nix/store/...-libblockdev-1.3/lib/libblockdev.so.0 libm.so.6 libdmraid.so.1.0.0.rc16 libbd_utils.so.0 Unfortunately, loading such a library without setting LD_LIBRARY_PATH is going to fail finding libm.so.6 and libdmraid.so.1.0.0.rc16. Now the first attempt at solving this was to put absolute paths of all the libraries referenced in the shared-library attribute, but this also led up to including paths of build-time shared objects into that attribute: /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 /tmp/nix-build-libblockdev-1.3.drv-0/.../utils/.libs/libbd_utils.so.0 This of course is not what we want, so the final solution is to only use the absolute path whenever it is a Nix path and leave the library name as-is if the path doesn't reside within the store, 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 libbd_utils.so.0 The downside of this approach is that if not even the output path of the library is in LD_LIBRARY_PATH, even loading of libbd_utils.so.0 could fail, so we need to patch the loader as well. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2016-01-22 20:49:33 +03:00
+ 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 with temporary paths that are only valid during
+ # build time in the resulting GIR file.
gobject-introspection: Fix patching shared objects The gi-r-scanner is generating a list of shared libraries that are referenced in the shared-library attribute of the <namespace/> element of the GIR file. However, this attribute only contains the names of the libraries and not the full store paths, like for example while preparing to package libblockdev, the following items were included in the shared-library attribute: /nix/store/...-libblockdev-1.3/lib/libblockdev.so.0 libm.so.6 libdmraid.so.1.0.0.rc16 libbd_utils.so.0 Unfortunately, loading such a library without setting LD_LIBRARY_PATH is going to fail finding libm.so.6 and libdmraid.so.1.0.0.rc16. Now the first attempt at solving this was to put absolute paths of all the libraries referenced in the shared-library attribute, but this also led up to including paths of build-time shared objects into that attribute: /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 /tmp/nix-build-libblockdev-1.3.drv-0/.../utils/.libs/libbd_utils.so.0 This of course is not what we want, so the final solution is to only use the absolute path whenever it is a Nix path and leave the library name as-is if the path doesn't reside within the store, 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 libbd_utils.so.0 The downside of this approach is that if not even the output path of the library is in LD_LIBRARY_PATH, even loading of libbd_utils.so.0 could fail, so we need to patch the loader as well. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2016-01-22 20:49:33 +03:00
+ | (?<=/)
+ )
+ # 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 +132,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:
gobject-introspection: Fix patching shared objects The gi-r-scanner is generating a list of shared libraries that are referenced in the shared-library attribute of the <namespace/> element of the GIR file. However, this attribute only contains the names of the libraries and not the full store paths, like for example while preparing to package libblockdev, the following items were included in the shared-library attribute: /nix/store/...-libblockdev-1.3/lib/libblockdev.so.0 libm.so.6 libdmraid.so.1.0.0.rc16 libbd_utils.so.0 Unfortunately, loading such a library without setting LD_LIBRARY_PATH is going to fail finding libm.so.6 and libdmraid.so.1.0.0.rc16. Now the first attempt at solving this was to put absolute paths of all the libraries referenced in the shared-library attribute, but this also led up to including paths of build-time shared objects into that attribute: /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 /tmp/nix-build-libblockdev-1.3.drv-0/.../utils/.libs/libbd_utils.so.0 This of course is not what we want, so the final solution is to only use the absolute path whenever it is a Nix path and leave the library name as-is if the path doesn't reside within the store, 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 libbd_utils.so.0 The downside of this approach is that if not even the output path of the library is in LD_LIBRARY_PATH, even loading of libbd_utils.so.0 could fail, so we need to patch the loader as well. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
2016-01-22 20:49:33 +03:00
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):