Merge pull request #12558 (GI-shlibpaths)

So far only .la files get correctly converted to absolute paths in the
GIR file. However if there are .so files which depend on a particular
library using GI, they still get only the basename of the .so file.

This improves on the existing absolute_shlib_path.patch not only
figuring out the absolute path of .so files but also falling back on the
absolute path of $out/lib (or $lib/lib with multiple outputs) of the
current build.

With this, we should no longer need to resort to setting LD_LIBRARY_PATH
for all programs that use GI libraries.

I'm merging this because after more than a month no issues came up so
far.

aszlig 183ac3f2 f70ec0de

+115 -6
+105 -3
pkgs/development/libraries/gobject-introspection/absolute_shlib_path.patch
··· 1 - --- ./giscanner/utils.py.orig 2014-08-14 22:05:05.055334080 +0200 2 - +++ ./giscanner/utils.py 2014-08-14 22:05:24.687497334 +0200 3 - @@ -110,17 +110,11 @@ 1 + diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py 2 + index 89ec193..54f1d2e 100755 3 + --- a/giscanner/scannermain.py 4 + +++ b/giscanner/scannermain.py 5 + @@ -94,6 +94,39 @@ def get_windows_option_group(parser): 6 + return group 7 + 8 + 9 + +def _get_default_fallback_libpath(): 10 + + # Newer multiple-output-optimized stdenv has an environment variable 11 + + # $outputLib which in turn specifies another variable which then is used as 12 + + # the destination for the library contents (${!outputLib}/lib). 13 + + store_path = os.environ.get(os.environ.get("outputLib")) 14 + + if store_path is None: 15 + + outputs = os.environ.get("outputs", "out").split() 16 + + if "lib" in outputs: 17 + + # For multiple output derivations let's try whether there is a $lib 18 + + # environment variable and use that as the base store path. 19 + + store_path = os.environ.get("lib") 20 + + elif "out" in outputs: 21 + + # Otherwise we have a single output derivation, so the libraries 22 + + # most certainly will end up in "$out/lib". 23 + + store_path = os.environ.get("out") 24 + + 25 + + if store_path is not None: 26 + + # Even if we have a $lib as output, there still should be a $lib/lib 27 + + # directory. 28 + + return os.path.join(store_path, 'lib') 29 + + else: 30 + + # If we haven't found a possible scenario, let's return an empty string 31 + + # so that the shared library won't be prepended with a path. 32 + + # 33 + + # Note that this doesn't mean that all hope is lost, because after all 34 + + # we can still use --fallback-library-path to set one. 35 + + # 36 + + # Also, we're not returning None, because that would make it very 37 + + # difficult to disable adding fallback paths altogether using something 38 + + # like: --fallback-library-path="" 39 + + return "" 40 + + 41 + + 42 + def _get_option_parser(): 43 + parser = optparse.OptionParser('%prog [options] sources') 44 + parser.add_option('', "--quiet", 45 + @@ -200,6 +233,10 @@ match the namespace prefix.""") 46 + parser.add_option("", "--filelist", 47 + action="store", dest="filelist", default=[], 48 + help="file containing headers and sources to be scanned") 49 + + parser.add_option("", "--fallback-library-path", 50 + + action="store", dest="fallback_libpath", 51 + + default=_get_default_fallback_libpath(), 52 + + help="Path to prepend to unknown shared libraries") 53 + 54 + group = get_preprocessor_option_group(parser) 55 + parser.add_option_group(group) 56 + diff --git a/giscanner/shlibs.py b/giscanner/shlibs.py 57 + index 838d343..ca7fc0d 100644 58 + --- a/giscanner/shlibs.py 59 + +++ b/giscanner/shlibs.py 60 + @@ -53,10 +53,24 @@ def _resolve_libtool(options, binary, libraries): 61 + # Match absolute paths on OS X to conform to how libraries are usually 62 + # referenced on OS X systems. 63 + def _ldd_library_pattern(library_name): 64 + + nix_store_dir = re.escape('@nixStoreDir@'.rstrip('/')) 65 + pattern = "(?<![A-Za-z0-9_-])(lib*%s[^A-Za-z0-9_-][^\s\(\)]*)" 66 + - if platform.system() == 'Darwin': 67 + - pattern = "([^\s]*lib*%s[^A-Za-z0-9_-][^\s\(\)]*)" 68 + - return re.compile(pattern % re.escape(library_name)) 69 + + pattern = r''' 70 + + ( 71 + + (?: 72 + + # First match Nix store paths because they need to be absolute. 73 + + (?:%s(?:/[^/]*)+) 74 + + # Everything else not a store path remains relative, because we 75 + + # would end up with temporary paths that are only valid during 76 + + # build time in the resulting GIR file. 77 + + | (?<=/) 78 + + ) 79 + + # And finally the library itself: 80 + + (?:lib%s[^A-Za-z0-9_-][^\s\(\)]*) 81 + + ) 82 + + ''' 83 + + return re.compile(pattern % (nix_store_dir, re.escape(library_name)), 84 + + re.VERBOSE) 85 + 86 + 87 + # This is a what we do for non-la files. We assume that we are on an 88 + @@ -115,7 +129,11 @@ def _resolve_non_libtool(options, binary, libraries): 89 + m = pattern.search(line) 90 + if m: 91 + del patterns[library] 92 + - shlibs.append(m.group(1)) 93 + + match = m.group(1) 94 + + if not match.startswith('/') \ 95 + + and len(options.fallback_libpath) > 0: 96 + + match = os.path.join(options.fallback_libpath, match) 97 + + shlibs.append(match) 98 + break 99 + 100 + if len(patterns) > 0: 101 + diff --git a/giscanner/utils.py b/giscanner/utils.py 102 + index 660081e..c9c767a 100644 103 + --- a/giscanner/utils.py 104 + +++ b/giscanner/utils.py 105 + @@ -109,17 +109,11 @@ def extract_libtool_shlib(la_file): 4 106 if dlname is None: 5 107 return None 6 108
+7 -2
pkgs/development/libraries/gobject-introspection/default.nix
··· 1 1 { stdenv, fetchurl, glib, flex, bison, pkgconfig, libffi, python 2 - , libintlOrEmpty, autoconf, automake, otool }: 2 + , libintlOrEmpty, autoconf, automake, otool 3 + , substituteAll, nixStoreDir ? builtins.storeDir 4 + }: 3 5 # now that gobjectIntrospection creates large .gir files (eg gtk3 case) 4 6 # it may be worth thinking about using multiple derivation outputs 5 7 # In that case its about 6MB which could be separated ··· 33 35 34 36 setupHook = ./setup-hook.sh; 35 37 36 - patches = [ ./absolute_shlib_path.patch ]; 38 + patches = stdenv.lib.singleton (substituteAll { 39 + src = ./absolute_shlib_path.patch; 40 + inherit nixStoreDir; 41 + }); 37 42 38 43 meta = with stdenv.lib; { 39 44 description = "A middleware layer between C libraries and language bindings";
+3 -1
pkgs/top-level/all-packages.nix
··· 6871 6871 #GMP ex-satellite, so better keep it near gmp 6872 6872 mpfr = callPackage ../development/libraries/mpfr/default.nix { }; 6873 6873 6874 - gobjectIntrospection = callPackage ../development/libraries/gobject-introspection { }; 6874 + gobjectIntrospection = callPackage ../development/libraries/gobject-introspection { 6875 + nixStoreDir = config.nix.storeDir or builtins.storeDir; 6876 + }; 6875 6877 6876 6878 goocanvas = callPackage ../development/libraries/goocanvas { }; 6877 6879